ESP8266 NodeMCU – Controling 4×7 Segment Multi-Digit Display 5641AH

In this tutorial, we will learn how to control a 4×7 Segment Display. To do so, we will use a 4-digit 7 segment display connected to a 74HC595 shift register to simply show whatever integer number from 0 to 9999 we send from the Serial Monitor of the Arduino IDE. If you want to display some numbers, this tutorial is the right one for you.

Parts Required

To build the global setup you must have the following parts:

Note: You do not need to have a NodeMCU board nor an ESP8266 to follow this tutorial. I am using this board because it is very famous and also because I will post future tutorials using wifi communications. In order to use other boards, you just have to change the pin number.

4×7 Segment Display 5641AH

Figure 1

This kind of displays are similar to single 7-segment displays, but with some tricks. To display information such as the time or temperature, you can use this one instead of connecting multiple single-digit displays side by side. If you want to know more about single 7-segment displays, check our tutorial on this topic.

In multi-digit displays, one segment pin (A, B, C, D, E, F, G, and DP) controls the same segments in all the digits, as you can see in figure 2. Multi-digit displays also have separate common pins for each digit. These are the digit pins. You can turn a digit on or off by switching the digit pin. The digit pins (D1 … D4) in our case, are common cathode. So to turn on a digit, pull the pin to GND.

Figure 2

Therefore, we are obligated to write to every digit at the same time. To control each digit individually, we need to use the digit pin (D1… D4) to turn on and off the respective digit. For example, in figure 3 we can see that by pulling to GND the pin D4, we turn on the right digit. Therefore, to write a 4 digit number, like 1230, we have to follow some steps, starting from the right digit:

  • Turn off the digits D1, D2, and D3, by pulling them to Vcc;
  • Turn on the segments A,B,C,D,E,F, to write the number 0;
  • Wait some time;
Figure 3

Now, repeat the step above, but now for the digit D3 until you reach the digit D1.

Figure 4

This is an indication that we need to turn on and off and switch between digits very fast to be able to write something. For those who think that they will see the flickering effect provoked by switching the digits, do not worry because this operation occurs very fast and your eye is not capable of detecting the transitions (Persistence of vision).

Shift Register 74HC595N

Figure 5

A shift register is a circuit you can use to control many outputs (8 here) at the same time while only using a few pins (3 here) of your board. It works on Serial IN Parallel OUT protocol. It receives data serially from the microcontroller and then sends out this data through parallel pins.

Thankfully Arduino provide a helper function specifically for shift registers called shiftOut(), which allows to simply shift the bits in one call.

Figure 6

As you can see in figure 6, pins marked as Q0-Q7 (15 and 1-7) are the output pins. Pin16 is connected to (VCC) 3.3V, whereas pins 8 and 13 are connected to the ground and pin 10 to (VCC) 3.3V. Finally pins 14, 12 and 11 are data, latch and clock pins and are the ones used by NodeMCU to pass data to the shift register.

For further understanding of the logic and function tables of this circuit, you can visit the datasheet, and can also visit an older tutorial on this circuit.

Circuit with Shift Register

Figure 8

Now, let’s go to the fun part! To start, we can connect pins 16 (VCC) and 10 () of the shift register to the NodeMCU 3V3 pin and pins 8 (GND) and 13 () to its GND pin.

Then, connect the clock (SRCLK), latch (RCLK) and serial data (SER) pins of the shift register to the NodeMCU digital pins D5, D8 and D7 respectively.

All the parallel data output pins of the shift register (QA – QH) should be connected to the segments of the display (A – DP) by order.

Finally, connect the digit pins to the NodeMCU digital pins D1, D2, D3 and D4. Note that the digit pins need to be connected to current limiting resistors (220Ω) since they are the common terminals of the digits.

In the end, your circuit should be similar to the diagram represented in Figure 8.

Installing Timer Library

In order for us to apply the multiplexing method in our code, it is necessary to install the Timer.h library before we compile it. To do so, we first need to download the library by clicking on the following link:

https://github.com/JChristensen/Timer/archive/master.zip

Then, we need to install it into our Arduino library. Open the Arduino IDE and then select Sketch > Include Library > Add .ZIP Library… and search for the .zip file you have just downloaded, which should be in the Downloads folder (see Figure 9). Once installed, will appear the following message in the Arduino IDE message area: “Library added to your libraries. Check “include library” menu”.

Figure 9

If you want to know more about this library, such as viewing some examples and functions, we suggest you consult this link:

http://www.doctormonk.com/2012/01/arduino-timer-library.html

Coding

As mentioned previously, with this code you can send any integer number from 0 – 9999 through the Arduino IDE serial monitor. To open the serial monitor, you can select Tools > Serial Monitor or simply click on the Serial Monitor button at the top right corner. Then type the number you want to see in the display in the small upper box and click on Send.

Regarding the code, the timer object is used to switch between digits. The segment pins are also turned ON and OFF for each number is stored in a byte array.

In the loop() function, the serial values are read, converted to integers and then to long data types. Then, the values in this long data are separated into single digits in the break_number() function.

Multiplexing is done by the timer class every() function and it calls the display_number() function once every millisecond. This uses the shiftOut() function to send signals to the shift register.

The latch pin is turned LOW before data is sent and turned HIGH afterwards. The function called cathode_high() is used to turn off the screen. Have Fun!

#include "Timer.h" //include timer library
Timer t; // craete a timer object

long number = 0; //declear the variables
int digit_1 = 0;
int digit_2 = 0;
int digit_3 = 0;
int digit_4 = 0;
int timer_event = 0;

int cathode_1 = 5;
int cathode_2 = 4;
int cathode_3 = 0;
int cathode_4 = 2;

int latchPin = 15;
int clockPin = 14;
int dataPin = 13;

int count = 0;
int digits[4] ;
int cathodePins[4] = {5, 4, 0, 2};

byte numbers[10] {B11111100, B01100000, B11011010, B11110010, B01100110, B10110110, B10111110, B11100000, B11111110, B11110110};

void setup() {
  Serial.begin(9600); //serial start and pin config
  pinMode(cathode_1, OUTPUT);
  pinMode(cathode_2, OUTPUT);
  pinMode(cathode_3, OUTPUT);
  pinMode(cathode_4, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  digitalWrite(cathode_1, HIGH);
  digitalWrite(cathode_2, HIGH);
  digitalWrite(cathode_3, HIGH);
  digitalWrite(cathode_4, HIGH);
  Serial.println("Please enter a number between 0 and 9999");
}

void loop() {
  t.update(); //timer update
  if (Serial.available()) { // read from serial
    t.stop(timer_event); //stop timer if anything to read
    cathode_high(); // blank the screen
    String s = Serial.readString(); //read the serial value
    number = (long)s.toInt(); //convert it to int
    if (number > 9999) { //check if the number is 0-9999
      Serial.println("Invalid number!\nPlease enter a number between 0 and 9999");
      } else {
      break_number(number);
      timer_event = t.every(1, display_number); // start timer again
    }
  }
}

void break_number(long num) { // seperate the input number into 4 single digits

  digit_1 = num / 1000;
  digits[0] = digit_1;
  int dig_1_remove = num - (digit_1 * 1000);
  digit_2 = dig_1_remove / 100;
  digits[1] = digit_2;
  int dig_2_remove = dig_1_remove - (digit_2 * 100);
  digit_3 = dig_2_remove / 10;
  digits[2] = digit_3;
  digit_4 = dig_2_remove - (digit_3 * 10);
  digits[3] = digit_4;
}

void display_number() { //scanning

  cathode_high(); //black screen
  digitalWrite(latchPin, LOW); //put the shift register to read
  shiftOut(dataPin, clockPin, LSBFIRST, numbers[digits[count]]); //send the data
  digitalWrite(cathodePins[count], LOW); //turn on the relevent digit
  digitalWrite(latchPin, HIGH); //put the shift register to write mode
  count++; //count up the digit
  if (count == 4) { // keep the count between 0-3
    count = 0;
  }
}

void cathode_high() { //turn off all 4 digits
  digitalWrite(cathode_1, HIGH);
  digitalWrite(cathode_2, HIGH);
  digitalWrite(cathode_3, HIGH);
  digitalWrite(cathode_4, HIGH);
}

References

https://osoyoo.com/2017/08/08/arduino-lesson-4-digit-7-segment-led-display/#3.2

https://tttapa.github.io/ESP8266/Chap01%20-%20ESP8266.html

1 thought on “ESP8266 NodeMCU – Controling 4×7 Segment Multi-Digit Display 5641AH

  1. The 4×7 Display used is 8-pin (5641AH). The link however is to the 6-pin 5641AS (one that I have as well) but not for this.

Leave a Reply

Your email address will not be published. Required fields are marked *