Sunteți pe pagina 1din 9

Controlling and Measuring With A Computer

In this page, I'll explain how to control the AC line and relays, input and output voltage levels, and other
similar things with the parallel port. If you are not familiar with the parallel port, and with the program
DEBUG to control it, please refer to DEBUG and the Parallel Port.

On-Off Control

The outputs of the (original) parallel port were specified to be able to drive one LSTTL input. This
implies 20 A output in the high state, and 0.4 mA input in the low state. Many more recent ports are
stronger than this, but you should test to make sure. The parallel port should supply no current itself, and
should not be exposed to voltages outside the range 0 to +5 V. From these properties, we see that the
parallel port must almost always be buffered if it is expected to do any real work.

The easiest interface of all is one to give ON-OFF control of the AC power line. One can use what is
called a solid-state relay for this purpose. A typical one takes 3 - 30 V DC input with very little current,
and controls 6 A at 140 V. The two sides are completely isolated, with two terminals each. The DC must
be applied with the proper polarity. A positive voltage turns the device ON. When the device is off, there
is a small leakage current, so the AC is not completely interrupted. This seldom causes any problem, but
should be kept in mind. All that is required is the relay itself.

It is important to keep in mind safety considerations when using the AC line. The two wires are called
line (L) or "hot," and common or "identified." The line wire often has black insulation, and the common
white. On zip cord, the line has smooth insulation, while the common is ridged. On a polarized plug, the
wide prong is the common. The common wire should be continuous back to the point where it is
grounded at the service entrance, and switches put in the line only. AC components should be put into the
nonconducting wiring boxes that are easily available. Any contact between conductors and any exposed
metal surface should be strictly avoided. When there are exposed metal surfaces, they should be grounded
to the green wire of a 3-prong plug, which is a ground connection. The common wire should never be
used instead (the plug may be reversed, or the wiring installed improperly). The grounding of one side of
the circuit means that the line wire is always "hot" with respect to any grounded object, including water
and the ground. This system is intended to open a protective device (fuse) if the insulation of the hot wire
fails at any point and contacts the grounds that surround it. This prevents fire, but not shock. Take care
not to ground yourself in any way when working with the AC line. There should be no metallic
connection between the AC line and the parallel port.

For anything except a solid-state relay, you will need an interface buffer. There are many choices, but the
2N4401 NPN transistor, the MPSA13 NPN Darlington, and the 74LS05 open-collector inverter, will
handle practically any case. The first thing to do is to see just how much the parallel port can do using a
high (1) state to turn the interface ON. When the computer comes up from cold, the pins usually assume a
noncommittal 1 state (some of the control pins, however, come up 0 since their logic levels are inverted.
This is true of pin 1 on the DB-25 connector, for example. We would really like for the interface to be
OFF in this case, and we'll see how to arrange this later.

First of all, the port can certainly drive a 74LS05. The output can sink up to 8 mA (without coming above
0.2 V). This increases the "sinking" power of the parallel port by 20 times! Since the LS05 is open-
collector, it cannot supply any current in the high state, and acts like an open circuit. This is what we
usually desire. If we are interfacing to digital logic, and not a transistor, then the 74LS04 is the correct
choice. The LS04 can supply up to 0.4 mA in the high state. This is not much, but is a lot more than the
port is rated to do on its own.
On test, my port successfully drove a 2N4401 transistor
supplying about 100 mA, with a collector voltage of 0.22 V.
This is well beyond the call of duty, but shows what can happen
with a good port and a good transistor. More conservative is the
use of a Darlington transistor, which requires very little base
drive, but a base voltage above 1.5 V. The MPSA13 delivered
85 mA with a collector voltage of 0.76 V. Darlingtons will not
pull lower than this, so they are not suitable for driving logic.
The simple circuits for testing the port are shown at the right.
The 50 1/2 W resistor is two 100 , 1/4 W resistors in parallel.
At 100 mA, they will be dissipating close to their limits, and may get warm. Both the 2N4401 and
MPSA13 are based EBC, as shown looking at the flat side.

A relay with a 120 V coil can be driven with a triac optoisolator, itself
driven by a transistor, as shown at the left. A triac optoisolator consists of a
GaAs IR LED and a light-triggered triac switch. The triac switch conducts
in both directions when it is triggered, so it can control an AC circuit.
Conduction ceases when the current passes through zero twice in each
cycle. Triacs will not turn off if you try to use them on DC. Some triacs are
made to switch only at these zero-crossing points, which avoids inductive
effects. The triac optoisolator I used was an H11J3, a very typical type that
should be easily available, if not under this number. It comes in a 6-pin
DIP. The LED has a maximum forward current of 60 mA, though 10 mA is guaranteed to trigger the
triac. The forward voltage is 1.2 V maximum, and the reverse voltage 3 V. The maximum blocking
voltage of the triac is 250 V, and the maximum current is 100 mA rms. This current is not enough to do
anything strong, but can operate a relay or trigger a larger triac. The isolation between the LED and the
triac is 3200 V peak.

The transistor should be selected for high beta at the ON current. Contrary to common belief, not all NPN
TO-92 transistors are alike. Their current gain is optimized for the collector current at which they are to
be used. The 2N4124 has a beta of 120 minimum at 2 mA, the 2N3904 at 10 mA. Both are commonly
used, and are very good transistors, but not for the present purpose. The PN2222A, 2N2907 and 2N4401
guarantee a beta of 100 at 150 mA, so any one of these is suitable for driving relays and other heavy-duty
interfacing. Their beta may be as high as 360, so we are safe in assuming a beta of 100 for our transistors.
A collector current of 100 mA requires, then, a base drive of 1 mA to bring the transistor to the edge of
saturation. By increasing the base drive, the transistor is brought more solidly into saturation. The actual
ratio of collector to base current is called the forced beta, and a satisfactory value in the present case is
25. Therefore, for 100 mA collector current, we should arrange for 4 mA of base current.

Although we have just seen that the parallel port can drive transistor bases directly, it is more
conservative not to rely on this, and use the greater "sinking" power instead. The transistor is turned on in
the normal state by base current supplied by a resistor to +5. A high level from the port does not disturb
this, so an output high level gives a low level at the transistor collector. When the port goes low, it robs
all the base current and the transistor turns OFF.

Since the port can sink 0.4 mA, this is enough for a guaranteed 10 mA output current. An LS05 gives us 8
mA base current, or 200 mA output current (this is about as much as a TO-92 transistor should have to
deal with, but a 2N4401 will do it without difficulty). The base pullup resistor to +5 is 12k in the first
case, 620 in the second. As we have seen, ports and transistors may surprise us a little with their
capacities.

A relay is an excellent device for controlling the AC line. It gives complete isolation to the AC circuits, as
well as complete disconnection on one hand and low-resistance connection on the other. DC relays are
commonly made for +12 and +24 V, but the ubiquity of +5 V logic supplies has given rise to 5-volt relays
as well. Make certain that the contact rating (usually printed on the relay itself) is sufficient for your
intended load. Incandescent lamps have a large turn-on surge (10 X the rated current) but it is brief and
seldom noticed. It occurs when the contacts close, so it does not damage them (unless they bounce).
Special measures should be taken with inductive loads--small motors and such--which do not like to be
turned off, and will cause the contacts to spark.

A DC relay is an inductive load itself. A 12 V


relay can give a 100 V kick when
disconnected, and this must be suppressed
when the relay is switched by a transistor. This
is easily done by a catching diode across the
terminals of the relay coil. The switch-off
transient goes through this diode, so the
inductive kick is completely eliminated. If you
do not use a catching diode, the transistor will
not survive long. Circuits for relay interfaces
are shown at the right. Where +5 is shown, it must be +5. +V is the appropriate voltage for the relay coil,
not over 30 V for the 2N4401 and MPSA13. If higher voltage is required, there are high voltage
transistors that will work well, but at somewhat lower betas. The MPSA42, for example, can take 300 V.

At this point you should have no problem designing interfaces to control the AC line, whether through
solid-state relays or mechanical relays. This is open-loop control, and you have no guarantee that the
lamp actually went on or off. The loop can be closed by detecting the light or its heat, or by detecting the
current in the lamp circuit. For a light detector, see the page Optoelectronics. This alternative has the
problem of interfering lights, but current detection is nearly foolproof. If the lamp is drawing the usual
current, it is probably lit. Let's design a circuit to tell us if the current is flowing.

This is done by passing the current through a small series resistor, robbing a bit of the applied voltage as
the cost of our information. The voltage across this resistor is rectified and smoothed (the smoothing may
be unnecessary, but it is done here for neatness), then used to drive the LED in an optoisolator. The
optoisolator neatly separates the AC voltages from our logic circuit. The output of the optoisolator is then
arranged to be a digital bit, low when the light is on, and high when it is off.

The optoisolator I used is the common 4N28, an


LED-phototransistor combination supplied in a 6-pin
DIP. Similar optoisolators are available under other
part numbers. The 4N28 has a maximum diode
current of 80 mA, with a forward voltage of 1.5 V
maximum, 1.1 V at 10 mA. The maximum reverse
voltage is 3 V, as typical for LED's. All three
terminals of the phototransistor are brought out, but
the base connection at pin 6 is not normally used. The
transfer ratio, Icoll/Idiode is guaranteed to be at least
10%. The maximum VCEO, the voltage between collector and emitter, is 30 V, and the maximum collector
current is 100 mA. The circuit is shown at the left, as arranged for detecting a 60 W light bulb, which
draws about 0.5 A, rms. This gives a rectified voltage of nearly 5 V. The output logic level is 0.22 V,
which is satisfactory.

The circuit must be altered as the AC current is changed, to provide sufficient current for the optoisolator,
but not too much. This can be done by adjusting the main sensing resistor, 10 here, so that the voltage
across it is about 5 V rms. This is not critical, and some freedom exists. The LED current should probably
be kept between 10 mA and 50 mA. The LED resistor can also be adjusted for the proper current. If you
connect an inverter and an LED at the output, the LED will be seen to light when the lamp is off, and go
dark when it is on. This bit can be read from the status port of the parallel port, and it is even possible to
arrange an interrupt when it signals that the lamp is off. I could get the circuit to work with only a 2.5 V
penalty, but this drastically reduces the dynamic current range.

Controlling an Output Voltage


The process of creating an external voltage that can be varied by a program in the computer is usually
called Digital-to-Analog Conversion (D/A conversion). There are lots of ways to do this, but we shall
discuss only one here, that is of general application and satisfies most non-critical requirements. A special
case is producing a rapidly-varying waveform (such as an acoustic signal) where the speed may require
special procedures. We are talking only about slowly-varying voltages here, say below 1 kHz, and even
DC values.

The device to be used is an "8-bit multiplying DAC" that takes 8 data bits and sinks a variable current
proportional to the binary number that they represent. The particular chip used is the MC1408, which, at
least at one time, was very popular and inexpensive. The circuit is supplied with a reference current into
pin 14 given by Vref/R, where R is a resistance in series with the reference voltage Vref. The output
current, which is sunk into pin 4, is given by Vref/R(b7/2 + b6/4 + b5/8 + b4/16 + b3/32 + b2/64 + b1/128
+ b0/256). The converter is called "multiplying" because the output current is proportional to the product
of the reference voltage and the binary input. The output current can be turned into a voltage with the help
of an op-amp, such as the LF411. By choosing the feedback resistor appropriately, it is possible to get any
output voltage in the range of the op-amp.

Preparing the MC1408 for operation is simple. The 8 bits are applied
to pins 5-12 in the order high to low. Pins 1 and 2 are grounded. +5 V
is supplied to pin 13, and the negative supply voltage to pin 3. This
can be anything from -5 to -12 V. It is rather annoying that a bipolar
supply is required, but it is. A resistor connected to the reference
voltage is connected to pin 14. It is recommended to use a reference
supply separate from the +5 V logic supply for the best accuracy. A
2.5 V voltage source is a good choice for this, although we will just
use +5 here for convenience. The reference current must not exceed 4
mA, and 1 or 2 mA are better. A capacitor is connected between pin
16 and the negative supply to compensate (stabilize) the current
amplifier. If the resistor at pin 14 is 1k, the capacitance can be 15 pF,
rising to 75 pF as the resistor value increases to 5k. Pin 15, which is
just a transistor base, is connected to ground through a resistor equal
to the one at pin 14 (but may be omitted). The connections are now complete, and all you have to do is
use the variable current into pin 4. The complete test circuit is shown at the right.

To test the circuit, apply digital levels to the digital inputs, making sure that you use the correct order of
bits. This can be done manually, by wiring the various inputs, but it is much easier if you have hex
switches that allow you to select any 8-bit hexadecimal number. Measure the output voltage with a
DMM. Find the voltage increment per bit. The MC1408 can be connected directly to the parallel port,
since its inputs add less load than LSTTL. The settling time is a few hundred ns, so the speed of
conversion will probably be limited by the speed of the parallel port. It is possible to produce acoustic
signals up to 10 kHz or so, limited by the port speed.

This method of D/A conversion relies on an elegant circuit, the R-


2R ladder, which can provide a series of currents related by factors
of 2 using resistors of all the same size. To see how it works, wire
up the circuit shown at the left, using 1% resistors if you have them.
Measure the voltages that result at nodes a, b, c and d, as well as the
applied voltage. It is more accurate to measure from +5 down rather
than from ground up, as usual. Compute each current from the
voltage drop and resistance. The currents I5 and I6 are the same, and
represent the smallest current increment. In the converter, the
currents for each bit are passed through transistor switches that guide them either to the output pin (for
input data = 1), or else to +5 (for input data = 0). In this way, the currents corresponding to each bit are
summed. The actual circuit is given in the data sheets for the MC1408.

Measuring an External Voltage


The inverse to D/A is Analog-to-Digital Conversion, A/D. There are many ways to do this, all of which
are quite interesting, but we shall concentrate on one commonly-used method, the "successive-
approximation" (SA) converter. The method is straightforward, and uses a chain of 256 resistors that
provide all possible voltages in the range. The input voltage is simply compared with these voltages until
the closest match is found. Then, the digital address of that voltage is the output. Some D/A converters
actually compare with each of the voltages, but the successive-approximation converter uses the rapid
method of a binary search. The voltage to be converted is first compared to V/2. If greater, the bit is 1. If
less, then the bit is 0. This process continues for each bit, each time halving the search interval. After 8
comparisons, we have the complete 8-bit conversion. This gives quite fast conversion, and an ordinary
SA converter can convert in a hundred nanoseconds or so.

The most important warning to the user of SA A/D converters is that the input voltage must remain
absolutely constant during the conversion. This means that in most practical cases, a sample-and-hold
(S/H) circuit must be used in conjunction with the converter. When we test the A/D converter in the
laboratory, we will use constant voltages that bypass the problem. Of course, the input voltage can vary
between conversions; it is only during conversions that it must be held constant. The errors produced by a
varying input voltage can be large; if the voltage crosses V/2 during the conversion, the error can be 50%.
Therefore, in any practical case where accuracy is important, a S/H must be used. A good, inexpensive
circuit is the National LF398, which comes in a 4-pin DIP, and is easy to use. Sample-and-hold circuits
are discussed in Sample-and-Hold.

The precision of an A/D converter is specified by the number of bits, N. The smallest step is then V/2N,
where V is the total range. We'll investigate the inexpensive 8-bit ADC0804LCN from National
Semiconductor, long a familar standby. If you need more accuracy, then converters with 10 and 12 bits or
more can be used, but they provide illusory accuracy unless used with great care, and, of course, with a
good S/H. For high precision and accuracy, other methods are more suitable.

The external voltage to be measured should be translated into the range of the A/D converter by op-amps
or other means. The normal range of the converter is 0 to +5 V. If we are thinking of measuring the
position of a potentiometer slider, for example, then we can apply the same voltage to the potentiometer
as to the A/D converter, so that even if the voltage varies, the relative position will remain the same. This
is the principle of ratiometric conversion that can contribute to accuracy. Alternatively, the range of
conversion can be adjusted by applying a reference voltage of V/2 (usually 2.5 V) to pin 9. When this pin
is not used, simply bypass it to ground with a .01 F capacitor. We will use ratiometric conversion with a
potentiometer for test purposes.

The ADC0804 is designed so that it can be used on a computer bus. This means that its digital output pins
are in a high-impedance state unless the RD (read) pin is pulled low. Also, the chip is disabled unless the
CS (chip select) pin is pulled low. For static tests, we simply ground both pins. If CS is low, and the chip
is active, a low pulse on the WR (write) pin causes a conversion to begin. Nothing is written to the ADC;
this is simply a message that a computer can use quite naturally. When the conversion is finished, a low
level appears on the INTR (interrupt request) pin to signal the fact. It does not have to cause an interrupt,
but can merely be sampled to find out the converter status. If we connect INTR to WR, the end of each
conversion will begin a new one, and the converter will always display the latest data at its output. We
will trigger conversions manually.

The circuit is shown at the right. The 150 pF capacitor and 10k resistor
create an RC oscillator using an internal inverter with hysteresis. These
values give a clock frequency of around 640 kHz, which causes a conversion
to be completed in from 103 to 114 s. 8 clocks are used for each digit, for a
total of 64, plus a variable delay of up to 8 clocks when a conversion is
initiated. The slower the clock, the longer a conversion takes, of course. An
external clock signal can be fed to pint 4 instead of using the internal
oscillator. In this case, the 10k resistor is not used, and pin 19 is left open.
The output bits can be displayed on buffered LED's. Every time the WR pin
is pulsed low, a new conversion will appear. It is convenient to use a
debounced pushbutton if you have one to get just one conversion (but this
does not matter). The voltage step corresponding to one count is (V+ - V-)/(2N - 1). If the total reference
voltage is 5.12 V, then this is 20 mV. Make a series of conversions, then divide the voltage by the counts
to see what you get. It is recommended that the VCC pin be bypassed by a 10 F capacitor to help keep it
steady.

If you have both the A/D and the D/A converters breadboarded simultaneously, connect the digital output
of the A/D to the digital input of the D/A and compare input and output voltages. If you want them to be
the same, both converters must be adjusted to have the same ranges by trimming the feedback capacitor
on the D/A op-amp.

Reading a Byte with the Original Parallel Port

The next problem is getting the 8 bits in the computer, when the parallel port has only 5 input bits. If you
have a bidirectional parallel port, it can be configured for input by setting bit 5 of the control port to 1.
Let's do the harder problem instead and work with just the original 5 input bits. The answer, of course, is
to multiplex the 8 bits into two 4-bit nibbles, and read the nibbles one at a time, then combine them. We
will need a control to strobe the WR input to begin a conversion, as well as a bit to select nibbles. Let's
use pin 1 (of the DB-25 connector) to strobe WR, and pin 14 to select the nibble. These are bits 0 and 1 at
port address 37A, and both are inverted upon output. Presuming the normal state of the other bits is with
00 written to 37A, we start a conversion by writing 01 to 37A, then a 00 to bring things back to normal.
We can use pin 15, bit 3 of the status read at 379, to tell us when INTR goes low and the conversion is
ready for input. Actually, with the present connection INTR just strobes low, so we cannot use it as a
completion flag. Instead, we will simply wait a sufficient length of time for the conversion to be
complete. There will normally be no apparent lag. When we input this byte, the upper four bits will be
one of the nibbles of the conversion. If we use a 74LS157 quad one-of-two data selector, we can put the
other nibble on the line by writing a 02 to 37A, and then read the second byte at 379. Now we have the
two nibbles, and they can be joined by the computer to get the complete byte. This is done by clearing the
lower four bits of the high byte (reading 379 puts it in the upper four bits). The other input byte
containing the low nibble is shifted four places right, and OR'ed with the byte containing the high nibble.

There are two parts to this problem, the circuits and the program. The
two cooperate to give the desired result, and each must be designed
with the other in mind. The program to read a byte from the ADC is
shown at the right in DEBUG assembler format. The circuit for the
interface is shown at the left. For other assemblers, it will be
necessary to put "H" after the hex numbers, but little other
modification should be required. To create the file, start DEBUG and
begin assembling at 0100 with the "a" command. Enter each
instruction in order. At the end, just press Enter without any input.
Now use "u" to disassemble the program, and check that it is correct.
Now execute the command "n readadc.bin" to create the FCB in
DEBUG. Use the "r" instruction to set CX to the length of the file. CX = 0032 allows an extra byte or
two. Now execute "w" and Debug will tell you that it wrote 32 (hex) bytes. The DOS dir display will
show the file as 50 bytes long. The file could be given a .COM extension, and it would run in DOS, but
this would be pointless since the program does not include any way to display the result. The program is
intended only for testing the interface in DEBUG, and as a basis for programs that actually do something
with the result.

The program begins by writing zeros to the control port, which we presume is the normal state, with the
WR signal attached to Pin 1 high. Then we pull Pin 1 low by writing 1, and then restore it to 0. This
triggers a conversion, which now takes place. We now wait for 255 loop cycles of decrementing the CL
register and checking if it is zero. Depending on the processor speed, this should allow enough time for
the conversion. If the program were running on a fast processor, some other way of implementing the
delay would have to be used. I tested the program with a 10MHz 386SX, and the delay seems long
enough. Now the byte containing the high nibble is read from the status port. It is necessary to mask off
the low four bytes (which will be 1's), and then to invert the high-order bit. It is a peculiarity of the
parallel port that this bit is inverted. Now the high nibble is saved in AH. The low nibble is now
addressed by changing the select input of the 74LS157 from 0 to 1, which is done by writing 2 to the
control port. Now the byte containing the low nibble can be read into AL. Bit 7 is inverted, and the byte is
shifted four places right, bringing in zeros at the left, and letting the rubbish fall off at the right. We want
the logical shift right, SHR, and not the arithmetic shift right, SAR, that repeats the high bit for sign
extension. Finally, the nibbles are combined by ORing them into the same byte in AL.

To test the program, start DEBUG with DEBUG readadc.bin


readadc.bin, which will load the file automatically. offset instruction comment
The command g 12e will execute the program, and
stop just before the JMP 0 instruction. Use "r" to 100 mov dx,37a trigger conversion
inspect the value in AL, which should be the 103 mov al,0
conversion. Return to DEBUG by excuting "g." Just 105 out dx,al
excuting "g" from the beginning will not change the
value of AX in the "r" instruction when the program 106 mov al,1
terminates, unfortunately. The command -g=100 12e 108 out dx,al
should give you a conversion, which can be read with 109 mov al,0
the "r" instruction. Just repeat this every time you want
a new value, and don't even use the JMP 0. 10B out dx,al
10C mov cl,ff wait a while
This routine can easily be written in C and embedded 10E dec cl
in a C program to read a conversion and do something
with it. The subroutine for reading a byte as two 110 jnz 10E
nibbles can be used for any similar application. My C 112 mov dx,379
program (1) displays the conversion in hex and 115 in al,dx read high nibble
decimal, and gives the corresponding voltage; (2)
allows input of the reference voltage, something that is 116 and al,f0 mask off lower 4 bits
important for finding the voltage accurately, and (3) 118 xor al,80 fix bit 7
shows the temperature in C and F, using an LM335 11A mov ah,al save high nibble
temperature sensor.
11C mov dx,372 address low nibble
There is much more to A/D and D/A conversion, but 11F mov al,2
the examples given here are practical and should get 121 out dx,al
you started economically. The parallel port, even in its
simplest forms, offers valuable opportunities for 122 mov dx,379
computer control. For digitizing audio signals, a much 125 in al,dx read low nibble
faster converter is required, one that works on different 126 xor al,80 fix bit 7
principles and is optimized for speed rather than
accuracy. A completely different approach is to 128 mov cl,4
convert between voltage and frequency instead, so that 12A shr al,cl
a frequency measurement can be used. This approach 12C or al,ah combine nibbles in al
has many advantages, and is not difficult to
implement. 12E jmp 0 return to debug

If you have more than one byte to read with the


parallel port, an interesting solution uses two
74LS170 4 x 4 register files to permit the
reading of any one of four bytes. The circuit is
shown at the left. Note that the data port is used
for the address information, selecting which
byte is used. The outputs of these chips are
open-collector, and so can be wire-OR'ed (OR
in negative logic). We can load the bytes into
two cascaded chips, then connect
corresponding outputs of the two nibbles,
together with a pull-up resistor, so that either
one nibble or the other can be read, as desired. Of course, the bytes have to be addressed, and this requires
two control lines (which may be manually controlled in a pinch, as can the begin conversion pulse) in
addition to the signal controlling which nibble is read. This line is connected to the read enable of one
LS170, then is inverted and connected to the other. In this case, either one nibble or the other will always
be ready to go, and the nibbles can be exchanged by toggling this line. Two more LS170's give us four
more bytes, and so on. The addressing demands are more complex, and perhaps the data output of the port
can be used for this purpose as 8 additional control lines. In fact, quite an impressive byte input facility
can be created in this way. The arrangment of the write strobes, that store the values, depends on the
application. The /INTR output of the ADC0804 can be used for this purpose.

If you do not need to store conversions on the interface, the solution using LS170's is a bit too complex,
though it shows the use of open-collector ouputs. A simpler solution uses the 74LS125 and 74LS126
quad buffers with 3-state ouputs. These chips are identical except that the LS125 has an active-low output
enable, while the LS126 output enable is active high. This is perfect for selecting one nibble or the other.
The outputs may be tied together since one is always high-impedance and will not contend with the other.

A circuit using the LS125 and LS126


buffers is shown at the right. The 28-
pin ADC0809 has an analog
multiplexer to choose one of eight
inputs, which makes it an interesting
chip for data aquisition. The circuit
shows how an ADC0809 can be
interfaced to the ordinary parallel port
to give eight input analog channels. A
serious design error in the chip was not
bringing the multiplexer output and the
comparator input to external pins, so
that a single sample-and-hold circuit
could be used. The ADC0809 requires
eight separate sample-and-hold circuits,
if they are necessary. The interface
shown assumes the analog signals are
steady, so the conversions will be
accurate. Any of the inputs could be
equipped with a S/H if necessary, controlled, for example, by pin 17, which is still uncommitted. In the
16-channel ADC0816, this error was corrected. Unfortunately, this comes in an even larger, 40-pin DIP.
There is very little discussion of the errors in converting a dynamic or noisy signal in the National data
book, though this is a very nasty problem that must be solved in any practical case. 12-bit converters give
12-bit precision, but usually not 12-bit accuracy!

The ADC0809 has no on-chip oscillator, so an external oscillator is used. Be sure to use an HC chip for
this, not an LS chip. The frequency is not critical; the specifications say 10 kHz to 1.28 MHz, with 640
kHz as a typical value. The circuit uses a chain of 1k resistors forming a voltage divider with 8 taps for
the test input to the converter. Of course, in a practical interface, these would be replaced by 8 terminals
for connecting the desired signals. The pins on the DB-25P parallel port connector are shown. There is
still one uncommitted control bit, and five unused data output bits, that can serve as bit I/O.

My C program for exercising the converter checks the EOC (end of conversion) output to see when the
data is ready. In contrast with the ADC0804, a conversion is begun by cycling the ST input high and then
low again. Conversion starts when ST goes low, and EOC goes low at the same time. EOC remains low
until the conversion is complete, when it goes high again. After initiating a conversion, the conversion
routine examines bit 3 in the status byte, looping until it goes high, then reading the data. If, for some
reason, it never goes high, the loop times out after 100 iterations, and reports the error on the video
screen. The program uses routines to (1) output the channel number and latch it with the ALE signal; (2)
input a byte as two nibbles, making all the necessary corrections; and (3) trigger a conversion, wait until it
is done, and report the value. Menu choices are to read all 8 channels, read a specified channel, set the
reference voltage, and to read a specified channel and interpret the voltage as temperature, assuming an
LM335 sensor. It is very satisfying to see the values of all eight channels appear practically
instantaneously.

Yet another solution is to read the bits in one by one, as they are presented
serially. All that is required is an 8-bit shift register that can be loaded in
parallel (all 8 bits at once) and a shift pulse to control it. Each serial channel
is implemented with one output and one input bit, so the ordinary parallel
port can support five such channels. The same shift pulse can be used for all
channels (be sure to buffer it so it can handle the load). Serial interfaces are,
of course, not news, and their advantages are well known (as in the USB
interface, and the familiar RS-232 serial port). A suitable shift register is the
74LS165 8-bit parallel to serial shift register. The circuit for a serial
interface is shown at the left. Note that the bit output is taken from /Q, since
bit 7 of the byte read from port 379 is inverted. Normally, one would use the Q output at pin 9. A low-to-
high edge on the clock input CK shifts all the bits one place right. There are two CK inputs (2,15) that are
OR'ed internally. The content of the highest-order bit is output at Q (9) and /Q (7) in direct and inverted
form. The byte is loaded by a low level on the PL (parallel load) pin (1). The /INTR pulse at the end of
conversion can be used to load the shift register. This idea can easily be extended to more than eight bits.

In any serial method, it is very important to have a good clock signal, without any ringing or other
disturbances that might be interpreted as extra clock transitions. If you find that the serial input works
improperly, the reason is probably a bad clock. Test this by connecting the DS (serial input) pin to 0 and
seeing if the conversion has extra zeros on the end, and then by connecting it to 1 and looking for extra
1's. When I tried it, it happened that there were as many as six extra clocks among the eight that were
programmed! The clock line happened to be long and dangly on the breadboard, which is the probable
cause. This was cured by grounding the clock line through a .001 F capacitor.

I plan to make a control and data aquisition board based on an ISA bus card with two parallel ports. One
port will have an 8-channel A/D interface as described above, and the other port will have a 2-channel
D/A interface. Any bits left over will be used for bit I/O. The D/A interface will use two LS374 octal D
latches to store two bytes, which will be converted to two analog values. This should stimulate interesting
applications.

S-ar putea să vă placă și