Pages: [1]   Go Down
Author Topic: four digit LED display  (Read 2253 times)
0 Members and 1 Guest are viewing this topic.
Australia
Offline Offline
Full Member
***
Karma: 7
Posts: 210
AVR Microcontrollers
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
// 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/
Logged

Australia
Offline Offline
Full Member
***
Karma: 7
Posts: 210
AVR Microcontrollers
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Need to change two lines:

Code:
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:
#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:
 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/
Logged

Pages: [1]   Go Up
Jump to: