An Osciloscope, Frequencymeter and Spectrum Analyzer Based on a Low End PC (AMD K5, 100MHz, 16Mb, 200HD)
Advanced
instrumentation is for most of us researchers, unaffordable. The key for a third world-reseacher is to find
means to obtain, with a low budget, a desired instrument. I have long time delighted with National
Instruments’ LabView, but it is just out my hands ($$$$$). However, for low frequency measurements
(some hundreds of Hz), my solution might find its niche.
Built
around the old trusty ISA bus, a ADC0804 is addressed to read analog values.
The software was made on the forgotten QBASIC (Thanks God for BASIC!) It is
ideal for us experimenters and researchers for its quick debuging. The program performs the following
operations:
-Obtains
the mean value, and plots a dashed line of it.
-Measures
the frequency of the signal.
-Derivates
the signal (it may or may not be ploted, just remove the REM from the line)
-Obtains
the Spectrum using the FFT (Fast Fourier Transform)
It could
also integrate the signal, but it will be used later. In my design, I also included a DAC (digital to Analog Converter)
so the computer can store a wave, derivate it, integrate it, or generate a
whole new one and sintetize one. So,
depending on software alone, the system can be used just like LabView, simply
by creating the appropiate algorythm.
This is the
schematics (rather simple) of the ADC:
The
schematics shows only two ICS: the 74138 address decoder and the ADC0804 8 bit A/D
converter.
The BASIC
source code is as follows:
5 TOL = 3
10 DIM
V(640), W(640), DV(640), DW(640), REV(512), IMV(512), TTFV(512)
15 R1 =
TIMER
18 FOR I =
1 TO 636
20 V(I) =
INP(&H200): W(I) = INP(&H220)
30 GOSUB
100
40 NEXT I
43 R2 = TIMER:
R = (R2 - R1) * 1000: SR = 636 / R
45 SCREEN
11: VIEW (1, 1)-(638, 440), , 1: WINDOW (1, 255)-(636, -255)
50 LINE (1,
255)-(636, -255), 0, BF: LINE (1, 0)-(636, 0), , , &HFF00
55 GOSUB
200
60 GOSUB
300: GOSUB 400
65 FOR I =
1 TO 635
70 LINE (I,
V(I))-(I + 1, V(I + 1)): LINE (I, W(I))-(I + 1, W(I + 1))
75 REM LINE
(I, 10 * DV(I) + DCOFFSETV)-(I + 1, 10 * DV(I + 1) + DCOFFSETV): LINE (I, 2 *
DW(I) + DCOFFSETW)-(I + 1, 2 * DW(I + 1) + DCOFFSETW)
80 GOSUB
100
85 NEXT I
90 GOSUB
500: GOSUB 1800
95 END
100 FOR D =
1 TO 40
110 IF
INKEY$ <> "" THEN GOTO 95
120 NEXT D
130 RETURN
200 VMAX =
V(1): VMIN = V(1): WMAX = W(1): WMIN = W(1)
210 FOR J =
2 TO 636
220 IF V(J)
> VMAX THEN VMAX = V(J)
230 IF VMIN
> V(J) THEN VMIN = V(J)
240 IF W(J)
> WMAX THEN WMAX = W(J)
250 IF WMIN
> W(J) THEN WMIN = W(J)
260 NEXT J
270 RETURN
300
DCOFFSETV = (VMAX - VMIN) / 2 + VMIN: VPP = VMAX - VMIN
310
DCOFFSETW = (WMAX - WMIN) / 2 + WMIN: WPP = WMAX - WMIN
320 LINE
(1, DCOFFSETV)-(636, DCOFFSETV), , , &HF0
330 LINE (1,
DCOFFSETW)-(636, DCOFFSETW), , , &HF0
340 RETURN
400 FOR T =
1 TO 635
410 DV(T) =
V(T + 1) - V(T)
420 DW(T) =
W(T + 1) - W(T)
430 NEXT T
440 RETURN
500 GOSUB
1000
510 I = 80
520 IF V(I)
>= VPP / 2 - TOL THEN GOTO 540
530 I = I +
1: GOTO 520
540 VSTART
= I
550 I =
VSTART + 1
560 IF V(I)
<= TOL - VPP / 2 THEN GOTO 580
570 I = I +
1: GOTO 560
580 VMID =
I
590 I =
VMID + 1
600 IF V(I)
>= VPP / 2 - TOL THEN GOTO 620
610 I = I +
1: GOTO 600
620 VFIN =
I
630 REM
*********************************
640 I = 80
650 IF W(I)
>= WPP / 2 - TOL THEN GOTO 670
660 I = I +
1: GOTO 650
670 WSTART
= I
680 I =
WSTART + 1
690 IF W(I)
<= TOL - WPP / 2 THEN GOTO 710
700 I = I +
1: GOTO 690
710 WMID =
I
720 I =
WMID + 1
730 IF W(I)
>= WPP / 2 - TOL THEN GOTO 750
740 I = I +
1: GOTO 730
750 WFIN =
I
760 LOCATE
3, 2: PRINT USING "##.# Hz"; SR * 1000 / (VFIN - VSTART);
765 PRINT
" ";
770 PRINT
USING "##.# Hz"; SR * 1000 / (WFIN - WSTART)
780 RETURN
1000 FOR I
= 1 TO 636
1010 V(I) =
V(I) - DCOFFSETV
1020 W(I) =
W(I) - DCOFFSETW
1030 NEXT I
1040 RETURN
1050 PI =
3.14159265#: N = 512
1060 NM1 =
N - 1
1070 ND2 =
N / 2
1080 M =
CINT(LOG(N) / LOG(2))
1090 J =
ND2
1100 '
1110 FOR I
= 1 TO N - 2
1120 IF I >= J THEN GOTO 1190
1130 TR = REV(J)
1140 TI = IMV(J)
1150 REV(J) = REV(I)
1160 IMV(J) = IMV(I)
1170 REV(I) = TR
1180 IMV(I) = TI
1190 K = ND2
1200 IF K > J THEN GOTO 1240
1210 J = J - K
1220 K = K / 2
1230 GOTO 1200
1240 J = J + K
1250 NEXT I
1260 '
1270 FOR L
= 1 TO M 'Loop for
each stage
1280 LE = CINT(2 ^ L)
1290 LE2 = LE / 2
1300 UR = 1
1310 UI = 0
1320 SR = COS(PI /
LE2) 'Calculate sine &
cosine values
1330 SI = -SIN(PI / LE2)
1340 FOR J = 1 TO LE2 'Loop for each sub DFT
1350 JM1 = J - 1
1360 FOR I = JM1 TO NM1 STEP LE
'Loop for each butterfly
1370 IP = I + LE2
1380 TR = REV(IP) * UR - IMV(IP) *
UI'Butterfly calculation
1390 TI = REV(IP) * UI + IMV(IP) * UR
1400 REV(IP) = REV(I) - TR
1410 IMV(IP) = IMV(I) - TI
1420 REV(I) = REV(I) + TR
1430 IMV(I) = IMV(I) + TI
1440 NEXT I
1450 TR = UR
1460 UR = TR * SR - UI
* SI
1470 UI = TR * SI + UI
* SR
1480 NEXT J
1490 NEXT L
1500 '
1510 RETURN
1800 VIEW
(1, 225)-(638, 440), , 1: WINDOW (1, 5000)-(256, 0)
2000 FOR I
= 1 TO 512
2010 REV(I)
= V(I)
2020 NEXT I
2030 GOSUB
1050
2040 FOR I
= 1 TO 256
2050
TTFV(I) = SQR(REV(I) ^ 2 + IMV(I) ^ 2)
2060 NEXT I
2070 FOR I
= 1 TO 255
2080 LINE
(I, TTFV(I))-(I + 1, TTFV(I + 1))
2090 NEXT I
2100 RETURN
2500 I = 80
2510 IF
(V(I) > -2 AND V(I) < 2) AND DV(I) > 0 THEN GOTO 2530
2520 I = I
+ 1: GOTO 2510
2530
FIRSTZERO = I
2540 I =
FIRSTZERO
2550 IF
W(I) > -2 AND W(I) < 2 THEN GOTO 2570
2560 I = I
+ 1: GOTO 2550
2570
SECONDZERO = I
2580 PHASE
= (SECONDZERO - FIRSTZERO) * 360 / (VFIN - VSTART)
2590 LOCATE
4, 2: PRINT USING "##.#ø PHASE"; PHASE
2600 RETURN
Here are a few pictures of my setup:
My old Aspire AMD K5 (Black one) |
555 biestable oscillator for test |
Cable with two analog inputs and one output. |
ISA card. Two analog channel inputs And one output channel (room for second one J) |
Close up (bad picture L) |
Signal analysis. (Sawtooth and square) Mean values, and
frequency measurement on upper half, and FFT on bottom of channel #1 |