Multipurpose 7-segment Display System (Part 1.)

Here is my latest invention. Arduino compatible multipurpose 7-segment display driver. It can be used in many places. To mention few it can be used in gas station price display, score board display in sport and clock or temperature view on store roof to catch eye.

Controlling format can be any and connection is USB virtual serial port. Power supply needs to supply +12V and +5V. Amperage is in accordance with display count. One display draws max. about 240mA from +12V line when all segments are on.

Main board is populated with all components. Slave modules does not need the atMega328P-PU chip and its related components. Board is connected directly on back of a display element. Display height must be 100mm and connectors distance 106.68-107.00mm.

Data line from last display must connect to the feedback line. Then it is programmatically possible to count displays and it is not necessary to manually import display count to microcontroller. Displays are counted from right to left.

Here is schematics for revision 3.


All components except the display can buy from

Display, KW1-4003ASA, any similar will go and also with reversed polarity. Common pins 1,8 or 3,8. Select with J8.

Unregulated AC/DC power supply can be used with 12V and 5V voltage regulation kits from Tayda:

One 12V regulator is giving enough power for about four displays. 5V power consumption is much less and not need to worry about it. One 5V regulator is enough for most users.

Cable between modules contains 7 wires:

Last display data line and feedback line connection can be made with mini jumper.

Arduino compatible

On final product Arduino bootloader is preinstalled on to atMega328P-PU chip before installing it to board. First prototype works with Arduino Nano and has one display. Below is program code that supports multiple displays.


/* Multipurpose 7-segment Display Driver
 * Juvar's Electronics Corner
 * Juvar
 * Juha-Pekka Varjonen
 * version 1.4
 * Master unit is connected to last display in row
 * Leftmost display data output is connected to feedback line
 * bug in C language:
 * array[0] = cannot write
 * array is zero indexed but cannot save data in to zero position

#define SER 2
#define FB 3
#define OE 4
#define CLK 5

int dispCount;
int pos = 1;

 *   _A_  
 * F|   |B
 *  |_G_|
 *  |   |
 * E|___|C
 *    D

byte num[12] = {
  0b01111110, /* 0 */
  0b00011000, /* 1 */
  0b01101101, /* 2 */
  0b00111101, /* 3 */
  0b00011011, /* 4 */
  0b00110111, /* 5 */
  0b01110111, /* 6 */
  0b00011100, /* 7 */
  0b01111111, /* 8 */
  0b00111111, /* 9 */
  0b00000000  /* space */
byte dataArr[20];

void setup() {
  // make the pins outputs
  pinMode(SER, OUTPUT); // serial data
  pinMode(OE, OUTPUT); // output enable
  pinMode(CLK, OUTPUT); // clock pulse
  // disable display output
  digitalWrite(OE, HIGH);
  // initialize serial

  // count displays
  int i = 0;
  byte temp;
  //set data
  digitalWrite(SER, HIGH);
  do {
    // toggle clock pulse
    digitalWrite(CLK, HIGH);
    digitalWrite(CLK, LOW);
    bitWrite(temp, 0, digitalRead(FB));
    temp = temp << 1;
  } while (temp != 0b11111110);
  dispCount = (i+1)/8;
  // clear data
  digitalWrite(SER, LOW);

void loop() {
  // if there's any serial available, read it
  while (Serial.available() > 0) {
    // read the incoming byte
    char data =;
    // if any numbers
    if (data >= 48 && data <= 57) dataArr[pos++] = num[data-48];
    // if space
    else if (data == 32) dataArr[pos++] = num[10];
    // if dot
    else if(data == 46) {
      if (pos > 1) bitSet(dataArr[pos-1], 7); 
        else bitSet(dataArr[pos], 7);
    // if carriage return
    else if (data == 13) updateDisp();

void updateDisp() {
  //disable display output
  digitalWrite(OE, HIGH);
  //send data to displays
  int i = 1;
  do {

    for (int e = 0; e <= 7; e++) {
      // send segment data
      digitalWrite(SER, bitRead(dataArr[i],e));
      // toggle clock pulse
      digitalWrite(CLK, HIGH);
      digitalWrite(CLK, LOW);

    dataArr[i] = 0; //fill with space
  } while (i <= dispCount);
  // clear data
  digitalWrite(SER, LOW);
  // toggle clock pulse
  digitalWrite(CLK, HIGH);
  digitalWrite(CLK, LOW);
  // enable display output
  digitalWrite(OE, LOW);
  pos = 1;


Prototypes accepts serial data from USB virtual serial port with following format. It mimics check point times from some sort of sport. Second prototype has two displays, so thats why data needs to be short. Otherwise data will be truncated.


Example picture with that data.

Data is displayed immediately after receiving it and stays on display until new data is arrived. It is possible to clear display temporarily by setting Output Enable pin to high state or clear display memory with sending empty character to all displays.

Selectors J6, J7 and J8

J6 and J7 selects display type between common anode and common cathode. They are solid jumper wires. If mode needs to change then must also change all transistors and reverse on board zener diode. When J6 is position 2-3 and J7 is position 1-2 then display is common anode. And when J6 is position 1-2 and J7 is position 2-3 then display is common cathode.

With J8 its possible to select whether connected display common pins are 1, 8 or 3, 8. Virtually all display modules are supported. Jumpers in position 1-3 and 2-4 means that 3, 8 is selected. When jumpers are in position 1-2 and 3-4 then 1, 8 is selected.