From: fdeck@sleepy.helios.nd.edu (francis deck) Subject: CHEAP 8-BIT ADC FOR IBM PC PLANS FOR A 4-CHANNEL 8-BIT ANALOG-TO-DIGITAL CONVERTER FOR PC Francis J. Deck fdeck@grumpy.helios.nd.edu This is an extremely simple ADC for the PC. It connects to the parallel printer port, and runs from a 9V battery. All parts are available from Digi-Key Corporation (1-800-DIGI-KEY), and cost is under $20, including box! Input voltage range is 0 to 5 V. Driver software is in Turbo Pascal. I measured the speed to be roughly 1200 samples/sec on an 8 MHz XT, and 5700/sec on the same PC with a 10 MHz 80286/cache accelerator card turned on. You'll see that this circuit doesn't require a bidirectional 8-bit i/o port. It should work even on the most wild of clones. I've had it going on IBM, Zenith, Jameco, etc. Needless to say, this is not an extreme precision device, but should suffice for many medium-speed application, such as temperature logging or alarms. An LM34 temperature sensor (10 mV/F output) would allow 2 degree resolution, for instance. For signals which are noisy beyond 1 LSB (roughly 20 mV), taking several readings and averaging them will improve the effective resolution by the square root of the number of readings. SCHEMATIC DIAGRAM: ________________ + | | __|__ | ___ 9 V | _____ battery | ___ | | | | | __|__ < ___ > 1 K Resistor _ < > Parallel Printer Port: | (pin numbers shown are | 1 for DB25 male plug) _______|_________ | V+ | 12 2 | clk |----------------o D0 Inputs: | | 2 3 3 | cs' |----------------o D1 A0 o----------| in0 | 13 4 4 | din |----------------o D2 A1 o----------| in1 | 10 10 5 | dout |----------------o Acknowledge A2 o----------| in2 | 7 18 6 | dgnd |----------------o Ground A3 o----------| in3 | | 8 | | | Gnd o----------| agnd | __|__ | | ___ | ADC0833CCN | _ | A to D Conv. | | | | vcc vref/2 | |_________________| | 7 | 9 | | | | +2.5 V __|__ | 0.1 uF _____ | Disc | | Capacitor | | + | ____|___| | | / \ | / \ LM336Z-2.5 | /_____\ Precision Reference IC | | | | - ----------| __|__ ___ _ Note: The pins of the LM336 can be identified as follows: The (+) terminal is the middle pin. Now, look at the lettering on the chip, while holding the chip with pins down and lettering facing you, the (-) terminal is on the right. Some notes: First, V+ is the input to an internal Zener regulator, and power supplies ranging from +9 to +15 V can be used. This makes it convenient to mount the circuit inside an existing powered device, such as a light meter. The circuit can also be powered by eliminating the battery and resistor, and connecting a +5 V supply to the Vcc terminal. I made a tiny little printed circuit board for this device, but it's hardly necessary, considering the low component count. A little piece of perfboard will suffice. Don't use cables longer than 1m to connect to the PC, since raw TTL isn't very good for long-haul data transmission. PARTS LIST [fmg - prices may have changed since the time this was posted!] All the parts come from Digi-Key Corp, 1-800-DIGI-KEY. Component Part # Price --------- ------ ----- ADC0833 ADC0833CCN $5.00 LM336-2.5 LM336Z-2.5 1.05 1k ohm 1.0KQ .26/5 0.1 uF P4311-ND 1.70/10 DB25 male plug 225M-ND 1.08 14-pin IC skt. A9314 .29 9 V batt. snap BS6I-ND .22 9 V batt. P104 1.04 ---------------------------------------- TOTAL: 10.64 DRIVER SOFTWARE LISTING These codes are all written in Turbo Pascal. {-------- ADC driver ANALOG.PAS -------} unit analog; interface {-------- User-modifyable constants ------} const nlpt = 1; {printer port number} vref = 2.5; {reference voltage for ADC} {-------- Read an ADC channel --------} function analog_read (ch: integer): real; implementation var in_addr, out_addr: word; {i/o addresses} const cs = 2; {ADC chip select line} di = 4; {ADC data input line} clk = 1; {ADC clock line} dout = 64; {ADC data output line} a: array[0..3] of byte = {Channel select word, bit #1} (0,di,0,di); b: array[0..3] of byte = {Channel select word, bit #2} (0,0,di,di); {-------- Read an ADC channel --------} function analog_read (ch: integer): real; var result: byte; i: integer; begin {transmit chip setup sequence as per ADC0833 data sheet} port[out_addr] := 0; port[out_addr] := di; port[out_addr] := di + clk; port[out_addr] := di; port[out_addr] := di + clk; port[out_addr] := di; port[out_addr] := a[ch]; port[out_addr] := a[ch] + clk; port[out_addr] := b[ch]; port[out_addr] := b[ch] + clk; port[out_addr] := di; port[out_addr] := di + clk; port[out_addr] := di; port[out_addr] := di + clk; port[out_addr] := 0; {the main conversion loop} result := 0; for i := 1 to 8 do begin result := result*2; port[out_addr] := clk; if port[in_addr] and dout <> 0 then result := result + 1; port[out_addr] := 0; end; port[out_addr] := cs; analog_read := result*vref*7.8125e-3; end; {-------- Initialization Section --------} const base: word = $40; offs: array[1..3] of word = ($08,$0a,$0c); dummy: real; begin {find out where printer port is} out_addr := memw[base:offs[nlpt]]; in_addr := out_addr + 1; {place ADC in idling mode} port[out_addr] := cs; {read ADC a few times to let it settle} dummy := analog_read(0); end. {-------- End of ANALOG.PAS ---------} {-------- Test program TEST.PAS --------} program test; uses crt, analog; var i: integer; begin while not keypressed do begin for i := 0 to 3 do write (analog_read(i):3:3,' '); writeln; delay (500); end; end. {-------- End of TEST.PAS --------} If there is suitable interest in this topic, measured by how much e-mail y'all send me, I will continue to post simple circuits. In the future, I may have to switch to Postscript or HP-GL format for the schematics, which I'd mail to interested persons. [fmg - the above started a heated debate on the format of posted schematics - the result of which seems to have been loss of interested in posting them... bummer] Incidentally, there's a real *gold mine* of inexpensive ICs out there which do all sorts of things, and which, like the ADC0833 above, use *synchronous serial i/o*, meaning that the send and receive data one bit at a time under control of an external clock signal. This kind of i/o is very conducive to parallel port connection, as I've shown. I will soon post a list of such chips which range from ADC and DACs to remote digital peripherals to EEPROMs to graphic equalizers!