Overview:
This acitivity explains how to use the 74HC595 to drive the 7-segment display, and to create Arduino functions.
Hardware Used:
Software Used:
- Arduino IDE
Application Discussion:
Up/Down Counters are useful in various applications. They are especially effective as timers that whenever it reaches a certain number, (in most cases 9 or 0), a function occurs such as a lock opening or closing, a switch redirecting current, and other similar effects.
The 74HC595 IC
The 74HC595 is a serial-in, serial or parallel-out shift register with output latches. It is a popular IC used in the field of microcontrollers because of it's ability to lessen the number of pins used. It could be observed in this project, where instead of using eight arduino pins to drive the 7-segment display, it was lessened to three pins (data, latch, and clock).
Driving a 7-Segment Display 1-Digit Display Tube
The 7-Segment Display has 7 LEDS that is structured to form numbers from 0-9. The 7-Segment Display in the Upgraded Arduino Kit has the common cathode configuration. This means that the middle pins are to be connected to a common ground to power the LEDs. The LEDs could be lit up by adding current to specific pins and could be formed into shapes as shown in the table below:
a | b | c | d | e | f | g | dp | OUTPUT |
1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
1 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 2 |
1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 3 |
0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 4 |
1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 5 |
1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 6 |
1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 7 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 8 |
1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 9 |
In order to drive them, the 7-Segment Display, the following pins should be connected:
|
|
*middle pins of 7-Segment Display is connected to GND of the Arduino
Hardware Setup:
This is the breadboard configuration of the system. All parts are included in the Arduino Upgraded Starter Kit.
Software Setup:
Open the Arduino IDE and upload the code on the Arduino Uno Board.
Code:
const int dataPin = 2;
const int latchPin = 4;
const int clockPin = 7;
const int upButton = 8;
const int downButton = 12;
int upButtonState = 0;
int downButtonState = 0;
int controlVar = 0; //0-upCount; 1-downCount
int countVar = 0;
void setup() {
pinMode(dataPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(upButton, INPUT);
pinMode(downButton, INPUT);
byte bits = myfnNumToBits(countVar) ;
myfnUpdateDisplay(bits);
delay(1000);
}
void loop() {
if (controlVar == 0){
upCount();
}
if (controlVar == 1){
downCount();
}
}
void upCount(){
countVar++;
if (countVar > 9) {
countVar = 0;
}
byte bits = myfnNumToBits(countVar) ;
myfnUpdateDisplay(bits);
delay(1000);
buttonRead();
}
void downCount(){
countVar--;
if (countVar < 0) {
countVar = 9;
}
byte bits = myfnNumToBits(countVar) ;
myfnUpdateDisplay(bits);
delay(1000);
buttonRead();
}
void buttonRead() {
upButtonState = digitalRead(upButton);
downButtonState = digitalRead(downButton);
if (upButtonState == HIGH) {
controlVar = 0;
}
if (downButtonState == HIGH) {
controlVar = 1;
}
}
void myfnUpdateDisplay(byte eightBits) {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, eightBits);
digitalWrite(latchPin, HIGH);
}
byte myfnNumToBits(int someNumber) {
switch (someNumber) {
case 0:
return B11111100;
break;
case 1:
return B01100000;
break;
case 2:
return B11011010;
break;
case 3:
return B11110010;
break;
case 4:
return B01100110;
break;
case 5:
return B10110110;
break;
case 6:
return B10111110;
break;
case 7:
return B11100000;
break;
case 8:
return B11111110;
break;
case 9:
return B11110110;
break;
default:
return B10010010; // Error condition, displays three vertical bars
break;
}
}
Code Breakdown:
- setup()
byte bits = myfnNumToBits(countVar) ;
myfnUpdateDisplay(bits);
delay(1000);
- loop()
This is also a default Arduino function. Any commands set here will be looped indefinitely. This function has an if statement that bases on the variable called controlVar.
- upCount()
This function is called the moment the controlVar variable is set to 0. It is set to count up (count++) from the last number shown on the 1-digit display tube, and will keep doing so until it runs buttonRead() once again and the controlVar variable changes.
- downCount()
This function is called the moment the controlVar variable is set to 1. It is set to count down (count--) from the last number shown on the 1-digit display tube, and will keep doing so until it runs buttonRead() once again and the controlVar variable changes.
- buttonRead()
The moment this function is called, it identifies if the push buttons were pressed or not through the digitalRead() function. Once it identifies what button has been pushed through the (state) variables, it will assign the controlVar variable a number (0 for up, 1 for down).
- myfnUpdateDisplay()
This function originated from Lester's code. It is the function that allows the 74HC595 to drive the 1-digit display tube. It takes the bits that were converted from the myfnNumToBits() function and updates the display.
- myfnNumToBits()
Like myfnUpdateDisplay(), this function also originated from Lester's code. It turns the variable count to bits in the format that follows the table above.
Now try making a function!
Now that the code has been discussed, we see this instance repeat three times. One in setup(), another in upCount(), and finally in downCount().
byte bits = myfnNumToBits(countVar) ;
myfnUpdateDisplay(bits);
delay(1000);As explained before, this set of code is used to allow the 7-Segment Display to show the current value of the countVar variable. In order to organize the code a bit more, it is best to make a new function for this code.
The new function can be named anything but for uniformity purposes, it will be named showCount(). Make sure not to input this inside any existing function.
void showCount() {
byte bits = myfnNumToBits(countVar);
myfnUpdateDisplay(bits);
delay(1000);
}
void setup() {
pinMode(dataPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(upButton, INPUT);
pinMode(downButton, INPUT);
showCount();
}
Now do the same in upCount() and downCount(). Running the program will produce the same results but with a much cleaner code.
Output:
This is the video output of the project.
Conclusion:
Now that the basics of driving a 7-segment display and creating an Arduino functions have been discussed, this knowledge is useful in other applications.
Projects that utlizes the idea of driving the 7-Segment Display is the Password-based Door Lock using 9g Servomotor, 4x4 Keypad, and 4-Digit Display Tube.
References:
https://create.arduino.cc/projecthub/meljr/7-segment-led-displays-102-using-a-shift-register-6b6976