KinectDuino

Kinect and Arduino one step ahead to Computer Science

How to Drive 4 Seven-Segments using IC 74HC595

In this post, I will share how to drive 4 seven-segments using IC 74HC595. The purpose of this circuitry is to count any object passing by the IR Switch Sensor and display it on 7 segments.

But, why using IC Shift Register 74HC595?

Basically, if you would like to drive 1 seven-segments, you need at least 9 pins wired to Arduino, it means 2 seven-segments = 18 pins, it is too much and not efficient for Arduino. By using this IC, I need only 3 pins to drive 1 or more seven-segments, so I can drive numbers to 2 or 23 or 234 or 2345, etc, such an wonderful convention I think.

Here, I will show you only 4 digits 7 segments, it is enough for you as an example if you would like to add or substract easily.

This is actually from BareBone Arduino, if you have ISIS Proteus Professional, I can give you the Arduino circuit like below, you can do simulation before buying the components.

Notice the pins below, they are all the same with your Arduino UNO. Remember to make pull dow circuit, why? Here you go.

My circuits is powered by external DC Power Supply 2.1 V, and my Arduino is powered by USB cable only, so we can see the ground is not connected, LOL, it is some confusing also.

This is the IR Switch Sensor I use, here the datasheet E18-D80NK-Manual-EN

Notice the pins wired to the Shift Register, I use 7Segments Common Cathode, no need converter anymore to light it. Datasheet

Here is the datasheet for IC 74HC595 (PHI): sn74hc595, Notice amount of IC used equal to number of 7 segments.

Here is the sourcoder works well on Arduino 1.0 IDE:

</p>
<p style="text-align: left;">

void setup();
void loop();
void increment (int line);
void show(int numberToDisplay,int fromLine);
void sendSerialData (byte registerCount,byte *pValueArray,int fromLine);
void sendSerialDatainitial(byte registerCount,byte *pValueArray,int fromLine);

// ALL INPUT PINS

int IRdetectPin0 = A0;

int switchPin0 = A3;

int laststate0 = LOW;

int no1=0;

// ALL OUTPUT PINS

// This pin gets sets low when I want the 595s to listen
const int  pinCommLatch1 = 5;
;

// This pin is used to pass the next bit
const int  pinData1    = 8;

// This pin is used by ShiftOut to toggle to say there's another bit to shift
const int  pinClock1     = 11;

// Definitions of the 7-bit values for displaying digits
byte g_digits [10];

//Machine Config in integer array
int MachineConfig[3][3];

// Current number being displayed
int g_numberToDisplay = 1;

// Number of shift registers in use
const int g_registers = 4;

// Array of numbers to pass to shift registers
byte g_registerArray [g_registers];

void setup()
{

pinMode (IRdetectPin0,INPUT);

pinMode (pinCommLatch1,OUTPUT);
pinMode (pinData1,OUTPUT);
pinMode (pinClock1,OUTPUT);

pinMode (switchPin0,INPUT);

//config for line 1
MachineConfig[0][0]=5;   //pinCommLatch line   1
MachineConfig[0][1]=8;   //pinData line        1
MachineConfig[0][2]=11;  //pinClock line       1

// Setup the digits array
g_digits [0] = 1 + 2 + 4 + 8 + 16 + 32 + 00;
g_digits [1] = 0 + 2 + 4 + 0 + 00 + 00 + 00;
g_digits [2] = 1 + 2 + 0 + 8 + 16 + 00 + 64;
g_digits [3] = 1 + 2 + 4 + 8 + 00 + 00 + 64;
g_digits [4] = 0 + 2 + 4 + 0 + 00 + 32 + 64;
g_digits [5] = 1 + 0 + 4 + 8 + 00 + 32 + 64;
g_digits [6] = 1 + 0 + 4 + 8 + 16 + 32 + 64;
g_digits [7] = 1 + 2 + 4 + 0 + 00 + 00 + 00;
g_digits [8] = 1 + 2 + 4 + 8 + 16 + 32 + 64;
g_digits [9] = 1 + 2 + 4 + 8 + 00 + 32 + 64;

sendSerialDatainitial(g_registers, g_registerArray);
}

void loop()
{

if (digitalRead(switchPin0))// START BUTTON LINE 1
{
detect(0);
}</p>
<p style="text-align: left;">}

void detect(int line)
{
if (line == 0)
{
int state0 = digitalRead(IRdetectPin0);
if (laststate0 == HIGH && state0 == LOW) // only count on a LOW-> HIGH transition
{
increment (0);
}
laststate0 = state0;// remember last state
}
}

void increment(int line)
{
if(line==0)
{
no1++;
g_numberToDisplay = no1;

show(g_numberToDisplay,line);
}
}

void show(int numberToDisplay,int fromLine)
{
if (numberToDisplay < 10)
{
g_registerArray [3] = g_digits [0];
g_registerArray [2] = g_digits [0];
g_registerArray [1] = g_digits [0];
g_registerArray [0] = g_digits [numberToDisplay];
}
else if (numberToDisplay < 100)
{
g_registerArray [3] = g_digits [0];
g_registerArray [2] = g_digits [0];
g_registerArray [1] = g_digits [numberToDisplay / 10];
g_registerArray [0] = g_digits [numberToDisplay % 10];
}
else if (numberToDisplay < 1000)
{
g_registerArray [3] = g_digits [0];
g_registerArray [2] = g_digits [numberToDisplay / 100];
g_registerArray [1] = g_digits [(numberToDisplay % 100) / 10];
g_registerArray [0] = g_digits [numberToDisplay % 10];
}
else
{
g_registerArray [3] = g_digits [numberToDisplay / 1000];
g_registerArray [2] = g_digits [(numberToDisplay % 1000) / 100];
g_registerArray [1] = g_digits [(numberToDisplay % 100) / 10];
g_registerArray [0] = g_digits [numberToDisplay % 10];
}
sendSerialData (g_registers, g_registerArray, fromLine);
}

<br style="text-align: left;" />void sendSerialDatainitial(
byte registerCount,  // How many shift registers?
byte *pValueArray   // Array of bytes with LSByte in array [0]
{
g_registerArray [3] = g_digits [0];
g_registerArray [2] = g_digits [0];
g_registerArray [1] = g_digits [0];
g_registerArray [0] = g_digits [0];

int PINCommLatch=MachineConfig[fromLine][0];
int PINData=MachineConfig[fromLine][1];
int PINClock=MachineConfig[fromLine][2];

pinMode (PINCommLatch, OUTPUT);
pinMode (PINData, OUTPUT);
pinMode (PINClock, OUTPUT);

// Signal to the 595s to listen for data
digitalWrite (PINCommLatch, LOW);

for (byte reg = registerCount; reg > 0; reg--)
{
byte value = pValueArray [reg-1];

for (byte bitMask = 128; bitMask > 0; bitMask >>= 1)
{
digitalWrite (PINClock, LOW);

digitalWrite (PINData, value & bitMask ? HIGH : LOW);

digitalWrite (PINClock, HIGH);
}
}
// Signal to the 595s that I'm done sending
digitalWrite (PINCommLatch, HIGH);
}  // sendSerialData

// Simple function to send serial data to one or more shift registers by iterating backwards through an array.
// Although g_registers exists, they may not all be being used, hence the input parameter.
void sendSerialData (
byte registerCount,  // How many shift registers?
byte *pValueArray, // Array of bytes with LSByte in array [0]
int  fromLine)
{
int PINCommLatch=MachineConfig[fromLine][0];
int PINData=MachineConfig[fromLine][1];
int PINClock=MachineConfig[fromLine][2];

// Signal to the 595s to listen for data
digitalWrite (PINCommLatch, LOW);

for (byte reg = registerCount; reg > 0; reg--)
{
byte value = pValueArray [reg - 1];

for (byte bitMask = 128; bitMask > 0; bitMask >>= 1)
{
digitalWrite (PINClock, LOW);

digitalWrite (PINData, value & bitMask ? HIGH : LOW);

digitalWrite (PINClock, HIGH);
}
}
// Signal to the 595s that I'm done sending
digitalWrite (PINCommLatch, HIGH);
}  // sendSerialData

If there is any mistaken or confusion, do not hesitate to comment below.

Finally, now you can make your own any display using Arduino + 7Segments + IC 74HC595, have a good work !

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Information

This entry was posted on July 11, 2012 by in Arduino and tagged , , , , .
%d bloggers like this: