( 3 Votes )

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.

low_-_high

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.

tri-state

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.

Short_Circuit

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.

tri-state_LED

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.

'To tristate the port pin:
 Input (PORTB.1)

 
'To turn the LED on:
 

Output (PORTB.1)
High (PORTB.1)
 
'To turn the LED off:
 Input (PORTB.1)

 

 

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.

relay

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.

Pump_Control

 

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.

OC_Circuit

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.

Comments 

 
0 #1 Graham 2010-07-26 22:01

Nice Jon - Great breakdown of the terminology and workflow of I\Os

Quote
 
 
0 #2 Keith Parker 2010-08-19 11:20

Could you not simply use a diode?

Quote
 
 
0 #3 Jon Chandler 2010-08-19 23:13

A diode instead of open collector outputs? Yes, that can work with a diode on each output and a pullup resistor.

I've used this to monitor both directions of an RS-232 interface using a third computer. You can't tell which side is sending what messages, but you usually know what to expect from each side.

Quote
 

Forum Feed

New Articles



Not Quite Trivial - A Tip for using the Software UART with the PICKit 2 +

Not Quite Trivial - A Tip for using the Software UART with the PICKit 2
This tip is almost trivial, but it's a D'uh moment too.  Just in case anyone else has missed the obvious. here's a quick tip.   I usually use Swordfish's hardware UART routines and I don't recommend Swordfish's software UART for input, where there...
Author: Jon Chandler

Simulating Analog Sensor Inputs +

Simulating Analog Sensor Inputs
When developing an embedded application using analog sensor inputs, testing at specific sensor levels can be difficult.  For example, in my icemaker controller project, actions need to occur at certain water levels.  Using the actual sensor...
Author: Jon Chandler

Simple Signal Generator - Revised +

Simple Signal Generator - Revised
I recently had use for the simple signal generatorI described before for testing out some piezo buzzers I got for next to nothing.  I reloaded the code onto a TAP-28 board...
Author: Jon Chandler

Reliable Header Connectors +

Reliable Header Connectors
Header pins are ubiquitous on dev boards.  Jumpers can be used to make connections during tests and code development but real-world applications need reliable connections.  Connectors for single row headers have always been a problem for me,...
Author: Jon Chandler

Swordfish Module - NMEA2 +

Swordfish Module - NMEA2
I had a couple of issues when using David Barkers module NMEA.bas on my Big GPS Clock project. In particular, variables were being corrupted making the program very unstable. I'm not familiar...
Author: Graham

10 Keys on One Port Pin? +

10 Keys on One Port Pin?
I'm working on a control system that will have several relays, a bunch of LEDs and a number of switches.  I was rapidly running out of port pins on a TAP-28 board to handle all the desired I/O.  Possible solutions included adding an I2C port...
Author: Jon Chandler
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Member Access



Whos Online

 We have 16 guests and 3 members online


showcase

Jon Chandler shares an ingenious method of interfacing 10 keys on a single pin

More


showcase

Jon looks at the types of boards available and for what situations a given board might be appropriate

More


showcase

Graham explores a popular method for charging NiMH cells - float charging

More

24 Timers!


feature_b_small

One PIC controlling 24 timers, easy! Add visual and audiable indications for each to spice things up

More

Member Access