Introduction to Displays 1

Today we’re going to be playing with a 4 character seven segment display.  It’s intended for displaying any number with 4 characters.

What you’ll need

  • Arduino UNO
  • Soderless Breadboard
  • Four character seven segment display
  • Wires
  • USB cable
  • PC/Laptop connection

When I first got my package of ELEC-0084 seven segment display, there were no documents to explain how they worked. Hm. That’s rather unfortunate. SSDs are the classic number displays you probably remember from Back to the Future. You can use them in a class to help your students learn about problem solving.

The first thing I did was examine the device. The front has 7 segments + 1 decimal dot – and there are 4 characters, so we come out to a total of 32 lights. The back only has 12 pins. This means that since the electricity going in also has to come out, it’s probably 8 pins to turn on the segments and 4 pins to control the characters.

Let me search on google – https://e-radionica.com/productdata/LD3361BS.pdf.

Page 36 shows a 4 character SSD. It seems to confirm the guess.

Unfortunately, the outside of the SSD doesn’t say which pin is which, so we’ll have to figure it out on our own. We’ll have to connect the pins and send power through each one. If we send power the wrong way, then nothing will happen. By tracking which pin is which we can separate anodes and cathodes from each other start to gain control over this thing.

Anodes and Cathodes

Let’s go ahead and put the SSD in the middle of our breadboard. Starting with the bottom right corner of the SSD pins, I connected the wires in a clockwise order to our Arduino UNO’s digital pins 2 through 13, inclusive. We also need to plug all of this into our computer, so let’s do that.

Now, it’s a good time to check out our code.

#define NUM_PINS 12
int pins[NUM_PINS] = {2,3,4,5,6,7,8,9,10,11,12,13};
void setup() {
  Serial.begin(57600);
  
  int i;
  for(i=0;i<NUM_PINS;++i) {
    pinMode(pins[i],OUTPUT);
    pinOff(i);
  }
}

void pinOn(int i) {
  digitalWrite(pins[i],HIGH);
}

void pinOff(int i) {
  digitalWrite(pins[i],LOW);
}

void loop() {
  int i;
  
  for(i=0;i<NUM_PINS;++i) {
    Serial.print("pin ");
    Serial.println(pins[i]);
    
    pinOn(i);
    delay(2000);
    pinOff(i);
  }
}

Open up the serial window! Every 2 seconds, the serial window tells me which pin is “on”, and I watch to see if the pins actually light up. I figured out that pins 2, 8, 11, and 12 are anodes, and that the rest were cathodes.

Mapping

Okay, now we’ve got arduino pin > anode and arduino pin > cathode. We need to map them in a way that it makes it easy to start drawing digits.

#define NUM_CHAR_PINS 4
#define NUM_SEG_PINS  8

                  // thousands, hundreds, tens, ones.
int characterPins[NUM_CHAR_PINS] = {2,8,11,12};

                  // I want this order
                  // aaa
                  //f   b
                  //f   b
                  // ggg
                  //e   c
                  //e   c
                  // ddd  h
                  // but I have this.  Rearrange the numbers in the {} to get the correct 
                  // sequence.
int segmentPins[NUM_SEG_PINS] = {3,4,5,6,7,9,10,13};

void setup() {
  Serial.begin(57600);
  
  int i;
  for(i=0;i<NUM_SEG_PINS;++i) {
    pinMode(segmentPins[i],OUTPUT);
    segmentPinOff(i);
  }
  
  for(i=0;i<NUM_CHAR_PINS;++i) {
    pinMode(characterPins[i],OUTPUT);
    charPinOff(i);
  }
}

void segmentPinOn(int i) {
  digitalWrite(segmentPins[i],HIGH);
}

void segmentPinOff(int i) {
  digitalWrite(segmentPins[i],LOW);
}

void charPinOn(int i) {
  digitalWrite(characterPins[i],LOW);
}

void charPinOff(int i) {
  digitalWrite(characterPins[i],HIGH);
}

void loop() {
  int i,j;
  for(j=0;j<NUM_CHAR_PINS;++j) {
    charPinOn(j);
    for(i=0;i<NUM_SEG_PINS;++i) {
      Serial.print("seg pin ");
      Serial.println(i);
      
      segmentPinOn(i);
      delay(100);
      segmentPinOff(i);
    }
    charPinOff(j);
  }
}

Great. The lights in each segment now turn on one at a time. By changing the order and of the numbers in characterPins(8, 11, 12, 2) and segmentPins(9, 13, 4, 6, 7, 10, 3, 5), we’re able to get the mapping we want.

Drawing a Digit

We’ve now got control of each individual map and we’ve built a map that looks like this:

 aa
f  b
f  b
 gg
e  c
e  c
 dd  h

Now, let’s try to get all of our numbers running.

#define NUM_CHAR_PINS  4
#define NUM_SEG_PINS   8
#define NUM_DIGITS    10
                          // thousands, hundreds, tens, ones.
int characterPins[NUM_CHAR_PINS] = {8,11,12,2};
                          // aaa
                          //f   b
                          //f   b
                          // ggg
                          //e   c
                          //e   c
                          // ddd  h
                          //      a, b, c, d, e, f, g, h
int segmentPins[NUM_SEG_PINS] = { 9,13, 4, 6, 7,10, 3, 5};
                          // new!
int        zero[NUM_SEG_PINS] = { 1, 1, 1, 1, 1, 1, 0, 0};
int         one[NUM_SEG_PINS] = { 0, 1, 1, 0, 0, 0, 0, 0};
int         two[NUM_SEG_PINS] = { 1, 1, 0, 1, 1, 0, 1, 0};
int       three[NUM_SEG_PINS] = { 1, 1, 1, 1, 0, 0, 1, 0};
int        four[NUM_SEG_PINS] = { 0, 1, 1, 0, 0, 1, 1, 0};
int        five[NUM_SEG_PINS] = { 1, 0, 1, 1, 0, 0, 1, 0};
int         six[NUM_SEG_PINS] = { 1, 0, 1, 1, 1, 1, 1, 0};
int       seven[NUM_SEG_PINS] = { 1, 1, 1, 0, 0, 0, 0, 0};
int       eight[NUM_SEG_PINS] = { 1, 1, 1, 1, 1, 1, 1, 0};
int        nine[NUM_SEG_PINS] = { 1, 1, 1, 1, 0, 1, 1, 0};
                          // new!
int *digits[NUM_DIGITS] = {zero,one,two,three,four,five,six,seven,eight,nine};

void setup() {
  Serial.begin(57600);
  
  int i;
  for(i=0;i<NUM_SEG_PINS;++i) {
    pinMode(segmentPins[i],OUTPUT);
    segmentPinOff(i);
  }
  
  for(i=0;i<NUM_CHAR_PINS;++i) {
    pinMode(characterPins[i],OUTPUT);
    charPinOff(i);
  }
}

void segmentPinOn(int i) {
  digitalWrite(segmentPins[i],HIGH);
}

void segmentPinOff(int i) {
  digitalWrite(segmentPins[i],LOW);
}
                            // new!
void segmentPinsAllOff() {
  int i;
  for(i=0;i<NUM_SEG_PINS;++i) {
    segmentPinOff(i);
  }
}
                            // new!
void displayDigit(int i) {
  int *segmentList = digits[i];

  int j;
  for(j=0;j<NUM_SEG_PINS;++j) {
    if(segmentList[j]==1) {
      segmentPinOn(j);
    }
  }
}

void charPinOn(int i) {
  digitalWrite(characterPins[i],LOW);
}

void charPinOff(int i) {
  digitalWrite(characterPins[i],HIGH);
}

void loop() {
  int i,j;
  for(j=0;j<NUM_CHAR_PINS;++j) {
    charPinOn(j);
    for(i=0;i<NUM_DIGITS;++i) {
      Serial.print("digit ");
      Serial.println(i);
      
      displayDigit(i);
      delay(100);
      segmentPinsAllOff();
    }
    charPinOff(j);
  }
}

This’ll make your display run through the numbers 0 to 9 on each of the four characters. Check out the video below to see if yours works like mine.

Multidigits

Let’s move up another level. Let’s try drawing multi-digit numbers.

#define NUM_CHAR_PINS  4
#define NUM_SEG_PINS   8
#define NUM_DIGITS    10
                           // thousands, hundreds, tens, ones.
int characterPins[NUM_CHAR_PINS] = {8,11,12,2};
                           // aaa
                           //f   b
                           //f   b
                           // ggg
                           //e   c
                           //e   c
                           // ddd  h
                           //     a, b, c, d, e, f, g, h
int segmentPins[NUM_SEG_PINS] = { 9,13, 4, 6, 7,10, 3, 5};
int        zero[NUM_SEG_PINS] = { 1, 1, 1, 1, 1, 1, 0, 0};
int         one[NUM_SEG_PINS] = { 0, 1, 1, 0, 0, 0, 0, 0};
int         two[NUM_SEG_PINS] = { 1, 1, 0, 1, 1, 0, 1, 0};
int       three[NUM_SEG_PINS] = { 1, 1, 1, 1, 0, 0, 1, 0};
int        four[NUM_SEG_PINS] = { 0, 1, 1, 0, 0, 1, 1, 0};
int        five[NUM_SEG_PINS] = { 1, 0, 1, 1, 0, 1, 1, 0};
int         six[NUM_SEG_PINS] = { 1, 0, 1, 1, 1, 1, 1, 0};
int       seven[NUM_SEG_PINS] = { 1, 1, 1, 0, 0, 0, 0, 0};
int       eight[NUM_SEG_PINS] = { 1, 1, 1, 1, 1, 1, 1, 0};
int        nine[NUM_SEG_PINS] = { 1, 1, 1, 1, 0, 1, 1, 0};

int *digits[NUM_DIGITS] = {zero,one,two,three,four,five,six,seven,eight,nine};

void setup() {
  Serial.begin(57600);
  
  int i;
  for(i=0;i<NUM_SEG_PINS;++i) {
    pinMode(segmentPins[i],OUTPUT);
    segmentPinOff(i);
  }
  
  for(i=0;i<NUM_CHAR_PINS;++i) {
    pinMode(characterPins[i],OUTPUT);
    charPinOff(i);
  }
}

void segmentPinOn(int i) {
  digitalWrite(segmentPins[i],HIGH);
}

void segmentPinOff(int i) {
  digitalWrite(segmentPins[i],LOW);
}

void segmentPinsAllOff() {
  int i;
  for(i=0;i<NUM_SEG_PINS;++i) {
    segmentPinOff(i);
  }
}

void displayDigit(int i) {
  int *segmentList = digits[i];

  int j;
  for(j=0;j<NUM_SEG_PINS;++j) {
    if(segmentList[j]==1) {
      segmentPinOn(j);
    }
  }
}

void charPinOn(int i) {
  digitalWrite(characterPins[i],LOW);
}

void charPinOff(int i) {
  digitalWrite(characterPins[i],HIGH);
}
                                          // new
void displayNumber(int value) {
  int maxValue = pow(10,NUM_CHAR_PINS);
  value %= maxValue;

  int i;
  for(i=0;i<NUM_CHAR_PINS;++i) {       //if(i>0 && value==0) break;  
                                          // uncomment to hide leading zeros
    int digit = value % 10;
                                          // turn on
    charPinOn(NUM_CHAR_PINS-1-i);
    displayDigit(digit);

    value-=digit;
    value/=10;
                                          // turn off (clean up for next digit)
    segmentPinsAllOff();
    charPinOff(NUM_CHAR_PINS-1-i);
  }
}
                                          // changed
void loop() {
  int maxValue = pow(10,NUM_CHAR_PINS);
  
  int i;
  for(i=maxValue-1;i>=0;--i) {
    Serial.println(i);
    int t = millis()+20;                  // show for 20ms
    while(millis()<t) {
      displayNumber(i);
    }
  }
  
  while(1) {
    int t = millis()+200;                 // show for 200ms
    while(millis()<t) {
      displayNumber(0);
    }
                                          // turn off
    segmentPinsAllOff();
    delay(200);
  }
}

What have we got now?

If you’ve missed any of the code, you can find it all from the the github here:

https://github.com/MarginallyClever/ArduinoStarterKit/tree/master/SevenSegment4Character

Your turn

  • Learn how to use a potentiometer, attach the two together, turn the potentiometer to change the number on screen.
  • Learn how to use a DC motor. Learn how to use an Encoder. Put these parts together, display the motor RPM on the display.
  • Share with your friends and hashtag @marginallyc so we can cheer for you.