- Published: Sunday, 25 July 2010
- Written by Jon Chandler
- Hits: 9261
Most micro-controller projects use port pins for outputs, often to turn on an LED or motor. When using a port pin as an output, we usually think of two states. A low state means the pin is connected to ground, while a high state means the pin is connected to +5V. Depending on how a LED, motor or other component is attached, "on" and "off" may correspond to either high or low. As shown below, if an LED is connected between a port pin and ground, a high state turns the LED on. Conversely, if the LED is connected between V+ and the port pin, a high state turns the LED off.
You may wonder why anyone would design a circuit where "turning on" a port pin would turn off the LED or other load. This is actually a quite common arrangement because some chips can "sink" (connect to ground) more current than they can "source" (connect to V+). The ULN-2003 Graham uses to drive relays is one such chip.
There is another option for outputs that sometimes isn't considered. The third condition is known as tristate. The chip's output is disconnected from the port pin. It's neither high nor low - it's simply not connected. In the case of the two LED configuration shown above, the LED won't be illuminated in either case.
What can this arrangement do for us? Suppose we want to have two different port pins (from different micro controllers?) control a single LED. If we connect the two outputs together and use high/low output levels, the situation shown below might happen. If one port pin wants the LED on, and the other wants the pin off, the two outputs will create a short circuit! One will be trying with all its might to make the output high and the other will be trying to make it low. Bad news. The circuit could be modified slightly by adding a resistor in series with each output; this would eliminate the possibility that the two outputs would damage each other, but the results would still not be what you expect.
A simple code change will easily fix this situation. If an output is tristated when the LED should be off and High when it should be on, there's no conflict between the 2 port pins. If either or both port pins want the LED to be on, it will be. If neither want it on, it will not be illuminated.
Ok, so the concept sounds pretty simple, but how is this accomplished in code? Easy. Just make the port pin an input! The commands for Swordfish and Proton/Amicus will be similar.
A Real World Example
I'm working on a control system for a commercial ice maker. Water drains into a sump and needs to be pumped out when it reaches a level that depends on a number of factors. I'm using a pressure sensor to determine when to start the sump pump. Knowing that micro-controllers may fail for any number of reasons, I want to have a back-up float switch. If the level gets high enough to be concerned about overflowing the sump, a float switch will actuate the pump regardless of the micro-controller state.
I have a 4 position relay board purchased from Electronics Salon on ebay. My initial thought was to have the micro-controller operate one relay to run the pump. A second relay would be controlled directly by the float switch with the relay contacts in parallel with the first relay so that the pump would run if either was actuated.
The relay card and schematic are shown below. The relay is controlled by an FET, and is turned on with a high input. If nothing (or a tristated output) is connected to the relay board input, its internal 300K pulldown resistor will keep the FET and therefore the relay off. Using the tristate trick, I can use a single relay which will be controlled by a port pin in the normal case or by the float switch if the micro-controller fails to start the pump soon enough.
When I want the relay to be actuated and the pump to run, I make the port pin a high-level output. When the pump has run long enough, I make the port pin an input. The pull-down resistor integral to the relay board pulls the line to ground, shutting off the FET and power to the relay.
If the float switch activates, it will pull the input line high, starting the relay. This won't bother the micro-controller port pin as it's either an open circuit (tristated because it didn't start the pump for some reason) or already high itself. I just have to be sure to tristate the port pin when I want the pump off.
Open Collector Outputs
Some chips have open collector outputs. The ULN2003 i\has open collector outputs. The output pin is connected to the collector of a transistor. When the transistor is off, the output pin is essentially floating, much like a tristate output. When the transistor is on, the output pin is connected through the transistor to ground.
Open collector outputs are frequently used as error/interrupt outputs on chips. Consider a fairly complex circuit with a series of I2C chips...say an output expander connected to a keypad, an LED driver chip and a power supply monitor. All of these chips are connected in parallel to the I2C interface, and the micro-controller can read and write data to each of them. The chips each have an interrupt output. The interface expander has an interrupt that indicates that a key has been pressed and the chip needs immediate attention so that keypresses aren't missed. The LED driver chip has an over temperature output to warn of overload and imminent shutdown. And the power supply monitor chip has an output to indicate that battery voltage is low. All of these output signals could take a lot of port pins to monitor! The chip designers have anticipated this - these outputs are open collector outputs (or may be configured that way in a chip register), and are low when active.
The diagram below shows how to connect the interrupt outputs in parallel. If none of the chips require attention, the pullup resistor pulls to line up to +5 volts (high state). If one of the chips needs attention, it activates its open collector output, pulling the line low. The micro-controller can then read the status register of each chip to see which ones need attention.
Notice the leading slash for the interrupt lines. This indicates that the output is active low - the ON condition is a low state. Because these lines are open collector, when they are not activated, they are essentially open circuit and the state of the line is the result of the pullup resistor.