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.
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
an interrupt 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
potentiometer
type joystick. 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 / | |
IORQ - 9)_____/
| IN1 |27 ------- CH2 see IN7
MREQ --------------------- 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