Wednesday, August 31, 2011

Using a 4511 to drive a 7-segment LED with an Arduino

An Arduino UNO can drive a 7 segment LED digit directly, but it takes seven output pins to do it. Additionally, your program is exposed to how the segments in the digit are wired to the Arduino.

A binary coded decimal (BCD) driver like the 4511 hides this level of detail for you. It takes 4 pins as input, another for latch, and drives the LED segments directly. You "tell" it what number to display, and it figures out which segments to light up.

The flipside to using the 4511 is you have to accept the way it draws digits like 6 and 9 without their tails. Also, it doesn't draw letters like A, b, C, d, etc. Well, using the 4511 is just an exercise, a stepping stone to a more sophisticated driver.

Anyhow, this is the code I whipped up in about an hour. I'm putting it in the public domain, so enjoy!

/*
 * Arduino UNO 4511 BCD to 7-digit LED driver
 *
 * 4511 pins 3 (lamp test), 4 (ripple blanking), and 16 (Vcc)
 * are connected to +5V on the Arduino UNO.
 *
 * 4511 pin 8 is connect to GND on the Arduino UNO.
 * The common cathode on the LED digit also connects to GND.
 * 
 * 4511 pins 9 through 15 connect to the LED digit as
 * appropriate.
 */
#define LATCH_ENABLE  13  // to pin 5 on the 4511
#define DATA1          1  // to pin 7 on the 4511
#define DATA2          2  // to pin 1 on the 4511
#define DATA3          3  // to pin 2 on the 4511
#define DATA4          4  // to pin 6 on the 4511

void setup()
{
  pinMode( LATCH_ENABLE, OUTPUT ) ;
  pinMode( DATA1, OUTPUT ) ;
  pinMode( DATA2, OUTPUT ) ;
  pinMode( DATA3, OUTPUT ) ;
  pinMode( DATA4, OUTPUT ) ;
}

// This macro tests bit 'b' in value 'v' and reports
// high or low as appropriate.
#define T(v,b)  (v & (1<<b) ? HIGH : LOW)

void show( unsigned int value )
{
  if ( value <= 9 )
  {
    // enable the latch so we can write
    digitalWrite( LATCH_ENABLE, LOW );
  
    digitalWrite( DATA1, T(value, 0) );
    digitalWrite( DATA2, T(value, 1) );
    digitalWrite( DATA3, T(value, 2) );
    digitalWrite( DATA4, T(value, 3) ); 
  
    // disable the latch now that we're done writing
    digitalWrite( LATCH_ENABLE, HIGH );
  }
}

void loop()
{
  for ( int i = 0; i <= 9; i++ )
  {
    show( i ) ;
    delay( 1000 ) ;  // msec
  }
}
The 4511 does a fine job driving a single 7-segment LED display, but it's old school compared to the MAX7219 which can drive up to eight of those displays. Here's a well written resource on the 7219. I'm going to try getting one soon.

No comments:

Post a Comment