Season's greetings to all SINCLAIR fans, As promised, another little project on the old ZX81 breadboard is finished and presented here to be shared by one and all! A ZX81 BREADBOARD PROJECT 8 CHANNEL / 8 BIT ADC 1996 wilf rigter WHAT IT IS Here is the next installment in a series of simple hardware projects for the ZX81 this time an 8 channel 8 bit Analog to Digital Converter (ADC). The simplest version is shown in FIG 1 using the widely available ADC808 and a 74HC4002 dual 4 input NOR gate. The hardware is pretty useless without some software and to make things easy a have written a little interrupt driven routine, shown in listing 1, which automatically converts each analog channel to binary data and stores the converted data in a BASIC string variable. The unit uses the ZX81 +5V supply for reference to provide a 0 to +5V analog input voltage range. This is fine for ratiometric measurements like sensing the position of a joystick potentiometer. If absolute measurements are required, a software calibration factor can be used or better accuracy can be obtained by using a seperate LM317 voltage regulator trimmed to +5V. THE HARDWARE The circuit in FIG 1 decodes the I/O address 5F (plus echos) with IORQ, A7 and A5 together with RD and WR to generate the required active high control signals. The WR signal is used to load the analog channel address and start the ADC808 A/D conversion and the RD signal is used to read the ADC808 data. In order to keep the circuit simple, the MREQ line is used as the clock source. With the MREQ line used for the clock source, the actual conversion time is uncertain but can be determined by sensing the End Of Conversion (EOF) line. The EOF signal is normally tied to the INT line to tell the CPU when conversion is completed. However the ZX81 INT and NMI lines are not available. Rather than convert and poll the EOC line to determine when data is ready, I put a small hook into the video routines to convert and transfer the ADC data in the "background". All 8 channels are converted about 8 times per second and automatically stored in A$. The typical low pass filter shown on ch7 will clean up noisy input lines. VCCand GND of the ADC808 should be bypassed with a 1 uF tantalum cap in parallel with a 0.1 uF ceramic. The +5V line is also connected to pin 14 of the 74HC4002 and 0V goes to pin 7. FIG 1 - 8 ch / 8 bit ADC for the ZX81 (and SPECTRUM) ADC808 _____ _________ RD --- 2) \ | VCC |11-------- +5V A5 --- 3) 74HC \ 1________ 9| OE +REF |12-------- +5V A7 --- 4) 4002 / | -REF |16-------- 0V IORQ - 5)_____/ | GND |13-------- 0V _____ ___ 6| START | WR -- 12) \ | | EOC |7 -------- not used A5 -- 11) 74HC \ 13___|__ 22| ALE IN0 |26 ------- CH1 see IN7 A7 ---10) 4002 / | | ORQ --- 9)_____/ | IN1 |27 ------- CH2 see IN7 REQ ----------------------- 10| CLK | D0 ----------------------- 25| A0 IN2 |28 ------- CH3 see IN7 D1 ----------------------- 24| A1 | D2 ----------------------- 23| A2 IN3 |1 -------- CH4 see IN7 D0 ----------------------- 17| D0 | D1 ----------------------- 14| D1 IN4 |2 -------- CH5 see IN7 D2 ----------------------- 15| D2 | D3 ------------------------ 8| D3 IN5 |3 -------- CH6 see IN7 D4 ----------------------- 18| D4 | D5 ----------------------- 19| D5 IN6 |4 -------- CH7 see IN7 D6 ----------------------- 20| D6 | D7 ----------------------- 21| D7 IN7 |5 ---+----[1k]---> 0-5V |_________| | ANALOG === 0.01 INPUT | 0V THE SOFTWARE The software is for the ZX81 only. The conversion is started by first writing the channel number to I/O address 5F and the converted data can be read sometime later at the same I/O address. The assembly language routine in listing 1 ties the conversion to the video routines, a channel conversion is started and the data for that channel is read once every video frame. The start occurs right after vertical sync and the data is read right after the DFILE display which guarantees that the data conversion is complete when the data is read. Each channel is converted by using the lower 3 bits from FRAMES to select a channel and data is automatically loaded into an element of an 8 byte A$ string variable array. The process is repeated for each channel as the FRAMES counter is incremented each 1/60 second. A DIM A$(8) BASIC line should be the first line after the 1 REM line. The machine code test for A$ as the first variable and skips data storage if not found. If you read all zero data check that A$(8) is the first defined variable. The routine is started with RAND USR 16516 and any BASIC program can easily use the data from the a$ variable. For example this little demo shows how the calibration factor (FACTOR) is calculated. In this case it assumes the ZX81 Vcc is exactly 5V but you can substitute the actual value for greater accuracy). It also illustrates how easily the raw data in the A$ array is accessed and converted to volts and converted to a equivalent string in B$. Next the voltage of each channel is displayed but first the old voltage reading is erased by writing 6 spaces to the appropriate screen location. enjoy wilf BASIC LISTING 1 REM ;this line contains the machine code for conversion 10 DIM A$(8) 20 RAND USR 16516 30 LET FACTOR = 5/256 30 PRINT "CHANNEL 1 - 8 INPUT LEVEL (VOLTS) " 40 FOR N=1 TO 8 50 LET B$=STR$ (CODE A$(N)*FACTOR) 60 PRINT AT N+2,0;" ":AT N+2,0;B$ 70 NEXT N 80 GOTO 40 ASSEMBLY CODE LISTING 1 START LD IX,CONVERT ; ALWAYS START CONVERT ROUTINE HERE RET CONVERT LD A,R ;SET UP THE NORMAL SINCLAIR SCREEN LD BC,1901 LD A,F5 CALL 02B5 ;AND NOW DISPLAY DFILE HL,(4010) ;START OF BASIC VARIABLES LD A,(HL) ;GET VARIABLE NAME CP C6 ;IS IT A$? JR NZ CONV1 ;MUST BE FIRST VARIABLE OR ELSE NO DATA LD A,(4034) ;GET FRAMES AND 07 ;LOWER 3 BITS ADD 06 ;SKIP THE VARIABLE HEADER LD E,A ;PUT IN OFFSET LD D,0 ADD HL,DE ;POINTER TO ELEMENT IN A,5F ;GET DATA LD (HL),A ;STORE IN VARIABLE CONV1 CALL 0292 ;RETURN TO APPLICATION CALL 0220 ;DO VSYNC LD A,(4034) ;GET FRAMES AND 07 ;LOWER 3 BITS OUT 5F,A ;LOAD CHANNEL AND START CONVERSION LD IX,CONVERT ;SAVE THE NEW VIDEO VECTOR IN IX JP 02A4 ;RETURN TO APPLICATION END