Arduino: Using C to write 7 Segment 4 Bit Display Driver

I have started re-learning C using the “C Head First Book” after doing it at university a number of years ago and decided to purchase an Ardunio (Well Genunio as I am not in the USA). The first lab in the book was to create a moisture sensor for detecting if a plant needed watering and write the output to the serial port to display on the PC. I purchased quite a few components from Banggood including this 4 bit 7 segment display. I found some driver code via the bang good forums which worked but decided to write my own as I wasn’t a fan of how it was written. It is also far better to write it from scratch if you want to learn exactly how it works and not just pass variables into a pre-defined function.

How the 7 segment display works

The banggood display module has two 74HC595 shift registers on the back which controls the individual led segments on the display. A shift register is simply put a way of expanding the pins of a micro-controller, this means the display only needs 3 input PINS. The display is a 4 bit display because it has four blocks of 7 segments (excluding the dot). The schematic diagram I found for the display shows which pins of shift registers control which segments on the display. The display segments are labelled using letters A-G and DP. The below image shows which letters correspond to which segment.

Display Segments

The display has 5 wires to connect; VCC (5 or 3.3v), GND, DIO (Data PIN), SCLK (Serial Clock) and RCLK (Register Clock). The pins from QA-QH are the output pins on the shift registers. The first step is to set the register clock low which allows data to be sent to registers. Then the serial clock is set to low, data is sent in (say bit 0 or 1) and the serial clock is set to high. When the serial clock is set to high it shifts the values to the right. This is repeated as many times as needed to get the right data in the chip (0’s and 1’s), once all the data is in the right place then the register clock is set to high. This copies all the data to the display registers to be displayed; effectively turning on the display. This is a brief explanation but more information can be found here The 74HC595 Register.

Shift RegistersSending information to the display

We can use the arduino shiftout function to shift bits to the display and the digitalWrite function to set the pins high/low. The display is made up of 8 segments and each one is turned on/off by a bit. The first bit sent to the register is segment ‘A’ at the right hand side and segment ‘DP’ at the left most side. For example this byte will be sent to display ‘C’. The zero’s are on and the 1’s are off because the display is a common anode display (CAD).

C = 0b11000110

There are two 74HC595 shift registers so we need to send 16 bits (two bytes) to the chip. The diagram above shows the first  register controls which display unit to show the information on. This is the pins QA, QB, QC and QD while the rest are blank and can be any value. This is not inverted so ‘1’ is now on and ‘0’ is now off.

For example:

0b11111001 will turn on the first (right most) and last (left most) display unit. So it will be “C OFF OFF C”.
To display just one C on the right then it will be:

The code

The smallest code required to send a C to the display can be seen below.


This is not useful on it’s own. The code needs to be able display lots of different values. This is where it got a little tricky to work out until I got the pen and paper out and could draw out how C handles arrays and pointers. The first step is a function that returns the required byte for the values 0-F (Hex). I decided to create a switch statement. The first part check if it is a capital C or lower case because I wanted to be able to display temperature. If it is not a lower case C then it capitalises it to match on the switch statement.

This still limits us to one number/letter at a time. Just modify the loop function:

We can display multiple values at once by using the following code.

You probably noticed this line:

This is used instead of the second byte. The numbers control the display to light up, 8 is left and 1 is right.

The above code will work correctly however it will only justify the values left which doesn’t look quite right to me, I found code elsewhere but that seemed a bit excessive. I wrote some code to reverse the value string and then reversed the digital pin values. Modify the loop to look like this:

You should now have working code that can be used to display values on the display. I have created an arduino library which you can add to your IDE by simply copying the folder to the libraries directory and then “Sketch – Manage Library”.

Ardunio Library

This has been converted to C++ as instructed in the Ardunio documentation.

The header file:

The C++ File

Example Use Code

Display Value

Temp Monitor (DS18B20)

I’ll write a post about this soon but here the code.

Moisture Sensor

The first part of the code is for interrupts to stabilise the display because of the number of value changes in the moisture function. This means the function is only called every half a second.

Finally….What it looks like


Resources and References

Library Download

Schematic Diagram

Shift Register Datasheet

The 74HC595 Register

Brainy Bits – 4-bits-7-segment-led-display-with-arduino

Arduino Timer Interrupts

Display Decoder

Arduino ShiftOut



Please share 🙂
  • Pingback: Weather Station using Raspberry Pi & Arduino | Monotok()

  • DisplayDriver

    Very nice write up Christopher. When you have 2 shift registers daisy chained together via pin 9 and pin 14 I wondered what data would be available from pin 9 on the second shift register? As you are probably aware these 7 segment displays have the second pin 9 broken out and available to Arduino. Would it simply be a case of connecting this pin to the serial RX pin on the Arduino and trying to read the data? What would you expect to see in Arduino’s Serial Monitor from this pin?