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.