Go Down

Topic: four digit LED display (Read 2 times) previous topic - next topic

carl47

This is a general purpose 4 digit 7 segment LED display.

It uses two 16 bit serial input constant-current LED
drivers with four 7 segment displays.

It uses 3 digital pins from the arduino.

The code is all in a class which has 4 functions:

SEVEN.displayI(int number)
This displays numbers in the range -999 to 9999.
The number is left justified. If it is not in
the range "EEEE" will be displayed.

SEVEN.displayF(float number)
This displays numbers in the range -99.9 to 999.9.
One decimal point is displayed.
The number is left justified. If it is not in
the range "EEEE" will be displayed.

SEVEN.displayP(long picture)
Picture is 32 bits which map to each segment.

SEVEN.displayA(long origional,unsigned char addition)
This is designed to be used with displayI or displayF.
It adds the right hand character to the display.

An example program showing use of the class

Code: [Select]
// simple program to show uses

#include <SEVEN.h>

void setup()   {    }

void loop()      
{  
SEVEN.displayI(789);  //displays "789_"
delay(1000);
SEVEN.displayF(-1.234);  //displays "-1.2_"
delay(1000);
SEVEN.displayP(0x1e5f4138);  //displays "FAIL"
delay(1000);
SEVEN.displayA(SEVEN.displayF(25.7),0x3a);  //displays "25.7C"
delay(1000);
}


The connections and the 7 segment display I use give
the following bit connection diagram.  

               D1
          ____________
         
         |                    |
         |                    |
    D3 |                    | D0
         |                    |
         |                    |
               D2
          ____________

         
         |                    |
         |                    |
    D4 |                    | D6
         |                    |
         |                    |
          ____________
                                      __
               D5                  |dp| D7
                                       --  


To display a "3" the bits are:

D7 D6 D5 D4 / D3 D2 D1 D0
0   1    1   0   / 0   1    1   1  = 0x67

The reason for the functions in the class is that I am
using them all for my Arduino  indoor weather station:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1265087241

I use the PC to display the weather data and the arduino is
just a box with two LEDs. Looking through forum I found
a multiple LED display using three digital pins.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264989981/0#8

I decided to use an extra pin and make the arduino
more interesting by showing the current data using 4 LEDs.
The arduino has a good tutorial for this type of circuit.

http://www.arduino.cc/en/Tutorial/ShiftOut

The 74HC595 is not designed to drive LEDs. It will work within
specification if you limit the current through each segment to
(75/8) 9.3 mA. The 220 ohm limiters in this circuit give a
maximun load current of 109 mA for 2v LEDs.
This exceeds the spec of 75mA.
With all segments on the poor little thing will be stretched.
If you put a 220 in the common leg only you get different
intensitys for the segment patterns.

The artical also suggests the STP16C596 with built-in constant
current sources. I chose to go with a A6276:

http://www.farnell.com/datasheets/87640.pdf

I set the current limit to 10mA per segment. This gives a maximun
of 320mA which can be handled by the USB.

The 7 segment display I used is a HDSP-521E:

http://www.farnell.com/datasheets/95204.pdf

The programs and other files are at the site given below.
Download fourdigitLED.zip

http://sourceforge.net/projects/arduinoweather/files/

carl47

Thanks for the email on the bug in SEVEN.displayF.

Need to change two lines:

Code: [Select]
if (numInt > 1)   //point must move
//
if (numInt > 10)   //point must move
//
//change to:
//
if (numInt >= 1)   //point must move
//
if (numInt >= 10)   //point must move


To use this display in my weather station I made some changes.

In the software I used PORT instructions rather than the
digital.write functions. This saves 380 bytes.

So in the .h file we have:

Code: [Select]
#define setupD8 DDRB |=0x01;   // data pin 8 is set to output
#define setupD7D6 DDRD |= 0xC0;   // data pin 7 and 6 is set to output
#define latchpinLOW PORTB &= ~0x01;  //set latch pin 8 to low
#define latchpinHIGH PORTB |= 0x01;  //set latch pin 8 to high
#define clockpinLOW PORTD &= ~0x80;  //set clock pin 7 to low
#define clockpinHIGH PORTD |= 0x80;  //set clock pin 7 to high
#define datapinLOW PORTD &= ~0x40;  //set data pin 6 to low
#define datapinHIGH PORTD |= 0x40;  //set data pin 6 to high
//
//  not as before
//
const int latchPin =  8;    // digital pin to latch 8 bits to parallel register
const int clockPin =  7;    // digital pin to clock data through serial reg
const int dataPin =  6;    // digital pin to send data to registers


In the .cpp file we have:

Code: [Select]
 setupD8;    //pin 8 to output
 setupD7D6;  //pin 7 and 6 to output
 unsigned long mask = 0x01;  //mask for display digit bit
 latchpinLOW;   //ready to latch data
 while (mask != 0)  //send each bit to register 32 bits total
 {  
 clockpinLOW;  //ready to clock data
 datapinHIGH;  //lets assume the data is high
 if ((display & mask) == 0)
 datapinLOW;   //wrong the data was low
 mask = mask<<1;  //look at next bit in digit display
 clockpinHIGH;  //clock the data line into the reg
 }//end of send 32 bits
 latchpinHIGH;   //latch the 8 bits to output register
//
//  not as before
//
 pinMode(clockPin, OUTPUT);
 pinMode(latchPin, OUTPUT);
 pinMode(dataPin, OUTPUT);
 unsigned long mask = 0x01;  //mask for display digit bit
 digitalWrite (latchPin, LOW);   //ready to latch data
 while (mask != 0)  //send each bit to register 32 bits total
 {  
 digitalWrite (clockPin, LOW);  //ready to clock data
 digitalWrite (dataPin,((display & mask) > 0 ? HIGH : LOW)); //C++ only ternary operator
 mask = mask<<1;  //look at next bit in digit display
 digitalWrite (clockPin, HIGH);  //clock the data line into the reg
 }//end of send 32 bits
 digitalWrite (latchPin, HIGH);  //latch the 8 bits to output register


For the hardware I had to make some changes as I do not use the USB supply.

I have a battery backed 12V supply. I wanted to keep the current for the display seperate from the sensitive sensors supplies.
To do this I gave the LED supply its own regulator. It is also wired so
that if power fails and the battery supplies power the display does
not operate. It draws to much current from the battery.

The new programs and circuit diagrams are available from:
Download fourdigitLED1.zip

http://sourceforge.net/projects/arduinoweather/files/

Go Up