74HC595 digital LED Display Based on Arduino

By on May 26, 2015

Web site:

http://www.instructables.com/id/74HC595-digital-LED-Display-Based-on-Arduino-Code-/

Project Summary:

The Chief Engineer of ICStation R&D department Jack is using ICStation UNO R3 compatible with Arduino to successfully make the 74HC595 drive four digital LED display. We will share the schematic diagram, wiring diagram,making steps,download Diagram and also the useful program code designed by ICStation.

Full Project:

When you develop a project, it often needs to make IO expansion.The 74HC595 shifting register is a good choice. Following will introduce you that use two pieces 74HC595 to realize the display system of four digital LED(of course, can also realize 8 digital LED display) .It only uses three IO (PIN2,3, 5) of Arduino.

Step 1: The wiring diagram:

Step 2: To build the circuit according to the schematic diagram

Because we only do testing, maybe it is not practical.If you want it to have practical use, you should weld it manually which will make the circuit more stable. When you build the circuit by hand the pin header is needed which will help you to change the DuPont line to jumper wires immediately.

Step 3: Download Diagram

Step 4: Code for Your Reference

Designed by ICStation

#define HC_DATA_H digitalWrite(data, HIGH) // data line output high
#define HC_DATA_L digitalWrite(data, LOW) //date line output low
#define HC_RCK_H digitalWrite(rck, HIGH) // rck output high
#define HC_RCK_L digitalWrite(rck, LOW) // rck output low
#define HC_SCK_H digitalWrite(sck, HIGH) // sck output high
#define HC_SCK_L digitalWrite(sck, LOW) // sck output low

unsigned char LED_BCD[16] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e }; //common anode digital tube BCD code
//Define the pin
int data =2;
int rck =3;
int sck =5;
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(data, OUTPUT); //initial data
pinMode(rck, OUTPUT); //initial rck
pinMode(sck, OUTPUT); //initial sck
pinMode(sclr, OUTPUT); //initial sclr

}

// the loop routine runs over and over again forever:
void loop() {

unsigned char dopp =0;
for( unsigned char i=0; i < 4; ++i)
{
if(i ==3) dopp =1;
else dopp =0;
LED_display(i,i,dopp); //Nixie Tube display
}

}

void LED_display(char LED_number,unsigned char LED_display,unsigned char LED_dp)
{
// data analyse
unsigned int hc_disp = 0,hc_ledcode,hc_ledcode_temp=0;

if(LED_display > 15) LED_display = 0;
hc_ledcode = LED_BCD[LED_display] ; //get BCD code
for(unsigned char i=0; i < 8;++i)
{
hc_ledcode_temp <<=1;
if(hc_ledcode&0x01) hc_ledcode_temp |= 0x01;
hc_ledcode >>=1;

}
if(LED_dp) hc_ledcode_temp &= 0xfe;
hc_disp = hc_ledcode_temp;

switch(LED_number)
{
case 0: hc_disp |= 0x8000;break;
case 1: hc_disp |= 0x4000;break;
case 2: hc_disp |= 0x2000;break;
case 3: hc_disp |= 0x1000;break;
}

write_74HC595_ShiftOUTPUT(hc_disp); //74HC595 shifting register data transfer

}

//shift output to 74HC595
void write_74HC595_ShiftOUTPUT( unsigned int data_a) //communication with 74HC595
{
char look =0;
HC_RCK_L; //latch open
HC_SCK_L;

for (;look < 16; ++look)
{
if(data_a&0x0001) {HC_DATA_H;}
else {HC_DATA_L;}
HC_SCK_H;

HC_SCK_L;
data_a >>= 1;
}
HC_RCK_H;
}

———————————————————————————————————

Circuit diagram:

Bill of Materials:

1. ICStation UNO development board  $12.69 ( Or Arduino UNO development board)
2.2PCS 74HC595
3.DuPont line: 30PCS
4.four digital LED display with the same anode
5. 20 PCS 20mm pin header
6.Bread board
7.USB Cable
8.4PCS 47Ω resistance

Firmware:

#define HC_DATA_H digitalWrite(data, HIGH) // data line output high
#define HC_DATA_L digitalWrite(data, LOW) //date line output low
#define HC_RCK_H digitalWrite(rck, HIGH) // rck output high
#define HC_RCK_L digitalWrite(rck, LOW) // rck output low
#define HC_SCK_H digitalWrite(sck, HIGH) // sck output high
#define HC_SCK_L digitalWrite(sck, LOW) // sck output low

unsigned char LED_BCD[16] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e }; //common anode digital tube BCD code
//Define the pin
int data =2;
int rck =3;
int sck =5;
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(data, OUTPUT); //initial data
pinMode(rck, OUTPUT); //initial rck
pinMode(sck, OUTPUT); //initial sck
pinMode(sclr, OUTPUT); //initial sclr

}

// the loop routine runs over and over again forever:
void loop() {

unsigned char dopp =0;
for( unsigned char i=0; i < 4; ++i)
{
if(i ==3) dopp =1;
else dopp =0;
LED_display(i,i,dopp); //Nixie Tube display
}

}

void LED_display(char LED_number,unsigned char LED_display,unsigned char LED_dp)
{
// data analyse
unsigned int hc_disp = 0,hc_ledcode,hc_ledcode_temp=0;

if(LED_display > 15) LED_display = 0;
hc_ledcode = LED_BCD[LED_display] ; //get BCD code
for(unsigned char i=0; i < 8;++i)
{
hc_ledcode_temp <<=1;
if(hc_ledcode&0x01) hc_ledcode_temp |= 0x01;
hc_ledcode >>=1;

}
if(LED_dp) hc_ledcode_temp &= 0xfe;
hc_disp = hc_ledcode_temp;

switch(LED_number)
{
case 0: hc_disp |= 0x8000;break;
case 1: hc_disp |= 0x4000;break;
case 2: hc_disp |= 0x2000;break;
case 3: hc_disp |= 0x1000;break;
}

write_74HC595_ShiftOUTPUT(hc_disp); //74HC595 shifting register data transfer

}

//shift output to 74HC595
void write_74HC595_ShiftOUTPUT( unsigned int data_a) //communication with 74HC595
{
char look =0;
HC_RCK_L; //latch open
HC_SCK_L;

for (;look < 16; ++look)
{
if(data_a&0x0001) {HC_DATA_H;}
else {HC_DATA_L;}
HC_SCK_H;

HC_SCK_L;
data_a >>= 1;
}
HC_RCK_H;
}

———————————————————————————————————

About

4 Comments

  1. rmoore

    January 24, 2016 at 6:34 AM

    This is a nice project. I got it going with minimal trouble. The code example was pretty “dense” (or maybe it’s just me). Anyway, I have modified the code so it is easier for amateur Arduino C/C++ programmers like myself can understand it, and I added code for a sensor input on the Arduino’s A0 port. The actual sensor used was a 10K ohm potentiometer which emulates a sensor pretty well. In includes code to convert the integer input into 4 individual numeric characters which can then be processed by the original code. Now the question is can I upload the modified code into this comment filed. Guess I’ll find out by trying…

    ==============
    // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // Source: “74HC595 digital LED Display Based on Arduino”

    // http://www.open-electronics.org/guest_projects/74hc595-digital-led-display-based-on-arduino/
    //
    // This project uses two 74HC595 shift register/latch chips to interface a 4-Digit 7-Segment Display to an Arduino uC.
    // One shift register handles the segment data required to represent the numbers being displayed while the second
    // shift register handles the control lines required to multiplex the segment data onto the correct digit display.
    // The display used in this poject was a Hitachi “HS410561K-32” which is a common anode display.
    //
    // The original code was pretty dense, so I’ve re-written it, added comments and added more meaningful variable names
    // so the code will be more understandable to your average programmer.
    //
    // The original “rck”, “sck” and “data” nomenclature still exist in the form of rckPin, sckPin and dataPin.
    // These 3 terms are more fully described here:
    // “rck” = “register clock” = “latch” = “ST_CP” = pin 12 on ‘595
    // “sck” = “shift clock” = “clock” = “SH_CP” = pin 11 on ‘595
    // “data” = “DS” = “Data Serial” (or “Serial Data”) = pin 14 on ‘595
    //
    // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // ========================================================
    // Define BCD code for common anode 7-Segment LED display:
    // ========================================================

    // Note: the BCD for common anode must use inverse logic (e.g. a “0” lights up a segment, a “1” turns it off):
    // If your display is common cathode, will need to invert these codes. Other code changes may also be needed,
    // especially those pertaining to the decimal point. This code has not been tested with common cathode.

    // Here’s the original coding with segment data densely packed in Hex:

    // char LED_BCD[16] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e };

    // Here’s the same segment data coded in Binary with detailed comments:

    char LED_BCD[16] = {
    0b11000000, // Light up segments a,b,c,d,e,f, but not g nor decimal point ==> “0”
    0b11111001, // Light up segments b & c, but not a,d,e,f,g nor d.p ==> “1”
    0b10100100, // Light up segments a,b,d,e & g, but not c, f nor d.p ==> “2”
    0b10110000, // Light up segments a,b,c,d & g, but not e,f nor d.p ==> “3”
    0b10011001, // Light up segments b,c,f & g, but not a,d,e nor d.p ==> “4”
    0b10010010, // Light up segments a,c,d,f & g, but not b,e nor d.p ==> “5”
    0b10000010, // Light up segments a,c,d,e,f & g, but not b nor d.p ==> “6”
    0b11111000, // Light up segments a,b & c, but not d,e,f,g nor d.p ==> “7”
    0b10000000, // Light up segments a,b,c,d,e,f & g, but not d.p ==> “8”
    0b10010000, // Light up segments a,b,c,d,f & g, but not e nor d.p ==> “9”
    0b10001000, // Light up segments a,b,c,e,f,g, but not d nor d.p ==> “A”
    0b10000011, // Light up segments c,d,e,f & g, but not a,b nor d.p ==> “b”
    0b11000110, // Light up segments a,d,e & f, but not b,c,g nor d,p ==> “C”
    0b10100001, // Light up segments b,c,d,e & g, but not a,f nor d.p ==> “d”
    0b10000110, // Light up segments a,d,e,f & g, but not b,c nor d.p ==> “E”
    0b10001110, // Light up segments a,e,f & g, but not b,c,d nor d.p ==> “F”
    };

    // Define the 3 Arduino dio pins used to control the two ‘595 shift registers
    int dataPin = 2; // Aka “DS”, goes to pin 14 on the first ‘595 shift register.
    int rckPin = 3; // Aka “latch” or “ST_CP”, goes to pin 12 on both ‘595 shift registers.
    int sckPin = 5; // Aka “clock” or “SH_CP”, goes to pin 11 on both ‘595 shift registers.

    int sensorPin = 0; // The sensor input will be plugged into the Arduino at analog pin 0.

    int sensorValue = 0; // Define a variable to store the value read from the sensor input pin.

    void setup() {

    // initialize the digital pin as an output.
    pinMode(dataPin, OUTPUT); // Set “dataPin” dio pin to output mode.
    pinMode(rckPin, OUTPUT); // Set “rckPin” dio pin to output mode.
    pinMode(sckPin, OUTPUT); // Set “sckPin” dio pin to output mode.

    // Clear display to 0 and pause 3 seconds to allow user to recognize the reset:

    LED_display(0,’0′,0);
    LED_display(1,’0′,0);
    LED_display(2,’0′,0);
    LED_display(3,’0’,0);
    delay(3000);
    }

    int thousands,hundreds,tens,ones = 0;

    void loop() {
    // ////////////////////////////////////////////////////////////////////
    // I added code to read input sensor and display it here.
    // Read sensor value:

    sensorValue = analogRead(A0);

    // Convert sensor value into separate digits:

    thousands = sensorValue/1000;
    hundreds = sensorValue % 1000 / 100;
    tens = sensorValue % 100 / 10;
    ones = sensorValue % 10 / 1;

    // Display digits on 4-digit 7-Segement LED display
    LED_display(0,char(thousands),0);
    LED_display(1,char(hundreds),0);
    LED_display(2,char(tens),0);
    LED_display(3,char(ones),0);

    // ////////////////////////////////////////////////////////////////////

    /* I commented out the original code…
    char dopp = 0; // Variable “dopp” seems related to decimal point (ledDp)

    // The original code only displays “0123” on my 4-digit 7-segment display…
    for( char i=0; i 15) {
    ledValue = 0;
    }

    ledCode = LED_BCD[ledValue] ; // Get BCD code for number to be displayed.

    for(int i=0; i<8; ++i) {
    ledCode_temp = ledCode_temp <> 1;
    }

    // Check if & where decimal point needs to be displayed

    if(ledDp) {
    ledCode_temp &= 0xfe;
    }

    displayCode = ledCode_temp;
    switch(ledNumber) {
    case 0: displayCode |= 0x8000; break; // displayCode = displayCode | 0x8000… obviously “d.p” for left most digit (D1)
    case 1: displayCode |= 0x4000; break; // Set “d.p” for D2
    case 2: displayCode |= 0x2000; break; // Set “d.p” for D3
    case 3: displayCode |= 0x1000; break; // Set “d.p” for D4
    }
    shiftOut595(displayCode); // Transmit data to 74HC595 shift register/latch
    }

    // Function to shift argument out to 74HC595 shift register/latch.
    void shiftOut595( int data) // Communicate with 74HC595
    {
    digitalWrite(rckPin, LOW); // Make register clock output pin go low
    digitalWrite(sckPin, LOW); // Make shift clock output pin go low

    for (int i=0; i> 1;
    }
    digitalWrite(rckPin, HIGH); // Make register clock output pin go high
    }

    ==============

    That’s it. You should be able to cut and paste this code into your Arduino IDE and try it out using the original circuit layout, plus the added 10K ohm pot (placed between Vcc and GND with the wiper arm going to the A0 pin on the Arduino board.

    If anyone wants to try to modify and test this code for a common cathode you can. If you invert the binary data in the LCD_BCD table the numbers should display okay (but I’ve not tested it). I suspect the decimal point logic will also need modification inverting it’s bit to work with common cathode displays.

    -Rand

    • Leandro Santos

      May 24, 2016 at 10:39 PM

      Thank you so much for your code. It helped me a lot :)

  2. Leandro Santos

    May 24, 2016 at 10:41 PM

    I bought a 4 digit 7-seg display from a Chinese site, that came without any schematics nor references. The schematics and logic you used here helped me to figure out how my module works. Thanks.

  3. Hoang Nguyen Thai

    September 9, 2016 at 5:37 AM

    Would you please add more guild control 8 seven segment led? I tried to do but didn’t success.

Leave a Reply