7-segment displays are most popular in panel meters, It can show direct numerical value on display, It’s cost is low and display size bigger than LCD’s. Lets interface four digit display, most of the time four digits are enough to display data.
Problem Statement
We are making a Voltmeter using four digit 7-segment display, for this IC 74HC595 shift register is used instead of 7448 decoder, use of shift register gives few advantages such as you can display sign, few alphabets and control decimal point location.
Based on the digit we want to show on display prepare decoding table, refer figure
Those segments we want to keep on make 1 and remaining 0.
Segment Decoding Table
Number | dp | G | F | E | D | C | B | A | Hex Value |
0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 3F |
1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 06 |
2 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 5B |
3 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 4F |
4 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 66 |
5 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 6D |
6 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 7D |
7 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 07 |
8 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 7F |
9 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 6F |
Arduino Connection with 7-Segment Display
To drive 7-segment display we used 74HC595 as Segment driver, you can use ULN2003 for driving common terminal, If the LED current is more, as we have used 1K Ohm resistor current stays in limit. We used three lines for driving segments and four for common terminal. At a time only one display is in on state.
Arduino Code for Voltmeter using 4-Digit 7-Segment Display
In program we have used TimerOne Library for Display scanning
/* Digital Voltmeter using 4-Digit 7-segment Display www.circuits4you.com */ #include <TimerOne.h> //Define 74HC595 Connections with arduino const int Data=7; const int Clock=8; const int Latch=6; const int SEG0=5; const int SEG1=4; const int SEG2=3; const int SEG3=2; int cc=0; char Value[4]; //Refer Table 4.1 7-Segment Decoding const char SegData[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //============================================================= // Setup //============================================================= void setup() { // initialize the digital pin as an output. Serial.begin(9600); pinMode(Data, OUTPUT); pinMode(Clock, OUTPUT); pinMode(Latch, OUTPUT); pinMode(SEG0, OUTPUT); pinMode(SEG1, OUTPUT); pinMode(SEG2, OUTPUT); pinMode(SEG3, OUTPUT); //Initialize Display Scanner cc=0; Timer1.initialize(50000); // set a timer of length 100000 microseconds (or 0.1 sec - or 10Hz => the led will blink 5 times, 5 cycles of on-and-off, per second) Timer1.attachInterrupt( timerIsr ); // attach the service routine here } //============================================================= // Loop //============================================================= void loop() { char Volt[4]; int Voltage=analogRead(A0); //To get fixed point decimal point we multiply it by 100 Voltage = (500/1024.0) * Voltage; //Scaling of 0 to 5V i.e. 0 to 1023 to 0 to 10 (in 10 steps) //Display Voltage on Segments sprintf(Volt,"%04d",Voltage); //We get ASCII array in Volt Serial.println(Volt); Value[0]=Volt[0] & 0x0F; //Anding with 0x0F to remove upper nibble Value[1]=Volt[1] & 0x0F; //Ex. number 2 in ASCII is 0x32 we want only 2 Value[2]=Volt[2] & 0x0F; Value[3]=Volt[3] & 0x0F; delay(200); } //============================================================= // Generates Bargraph //============================================================= void DisplayDigit(char d) { int i; for(i=0;i<8;i++) //Shift bit by bit data in shift register { if((d & 0x80)==0x80) { digitalWrite(Data,HIGH); } else { digitalWrite(Data,LOW); } d=d<<1; //Give Clock pulse digitalWrite(Clock,LOW); digitalWrite(Clock,HIGH); } //Latch the data digitalWrite(Latch,LOW); digitalWrite(Latch,HIGH); } //=================================================================== // TIMER 1 OVERFLOW INTTERRUPT FOR DISPALY //=================================================================== void timerIsr() { cc++; if(cc==5) //We have only 4 digits {cc=1;} Scanner(); TCNT0=0xCC; } //=================================================================== // SCAN DISPLAY FUNCTION //=================================================================== void Scanner() { switch (cc) //Depending on which digit is selcted give output { case 1: digitalWrite(SEG3,HIGH); DisplayDigit(SegData[Value[0]]); digitalWrite(SEG0,LOW); break; case 2: digitalWrite(SEG0,HIGH); DisplayDigit(SegData[Value[1]] | 0x80); //0x80 to turn on decimal point digitalWrite(SEG1,LOW); break; case 3: digitalWrite(SEG1,HIGH); DisplayDigit(SegData[Value[2]]); digitalWrite(SEG2,LOW); break; case 4: digitalWrite(SEG2,HIGH); DisplayDigit(SegData[Value[3]]); digitalWrite(SEG3,LOW); break; } } //===================================================================
Result
You can observe its output on serial terminal also, the display will show the voltage reading, apply voltage at ADC A0 pin using potentiometer. This code demonstrates how to multiplex multiple displays and concept of 7-segment display.