Recently I coded a seven segment display for a friend of mine. Hope
this might be helpful for wiring purposes. My task was to correctly display 5 digit number on 5 `seven segments`. So, most of the examples out there including
this module support only
up to 4 segments. So, I wrote my own code from the scratch.
This is the code, I wrote:
const int SEGMENT_RENDER_DELAY_MS=5;//segment rendering delay
const int MAX_NUM_SEGMENTS=5;//store maximum segments
//
String inputString = ""; // a string to hold incoming data
String displayStr="hellO"; //current display string (keep empty to display all zero's!)
//unsigned long digit; // display digit, if you are dealing only with numbers
// a
// =======
// || ||
// f || || b
// || g ||
// =======
// || ||
// e || || c
// || d ||
// =======
byte seven_seg[16][9] = { {0,0, 1,1,1,1,1,1,0 }, // = 0
{0,0, 0,1,1,0,0,0,0 }, // = 1
{0,0, 1,1,0,1,1,0,1 }, // = 2
{0,0, 1,1,1,1,0,0,1 }, // = 3
{0,0, 0,1,1,0,0,1,1 }, // = 4
{0,0, 1,0,1,1,0,1,1 }, // = 5
{0,0, 1,0,1,1,1,1,1 }, // = 6
{0,0, 1,1,1,0,0,0,0 }, // = 7
{0,0, 1,1,1,1,1,1,1 }, // = 8
{0,0, 1,1,1,0,0,1,1 }, // = 9
{0,0, 1,0,0,1,1,1,1 }, // = e
{0,0, 0,0,0,0,1,0,1 }, // = r
{0,0, 0,0,1,1,1,0,1 }, // = o
{0,0, 1,1,1,1,1,1,0 }, // = O
{0,0, 0,1,1,0,1,1,1 }, // = h
{0,0, 0,0,0,1,1,1,0 } // = l
};
byte firstSegmentPos = 0, secSegmentPos = 0,thirdSegmentPos = 0, fourthSegmentPos = 0, fifthSegmentPos = 0;
//
int pin;
void setup() {
// initialize serial:
Serial.begin(9600);
// reserve 200 bytes for the inputString:
inputString.reserve(200);
//define output pins
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
}
void loop() {
updateSegments();
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
//if linebreak found, parse it
if (inChar == '\r'||inChar == '\n') {
//we got a break, parse string
parseCode(&inputString);
inputString="";
}else{
//append the character received
inputString += inChar;
}
}
}
/**
* Parses one line of transaction
* If validation failed-> error displayed Or value displayed
**/
void parseCode(String* receivedLine){
String line = *receivedLine;
line.trim();//remove spaces
//
int lineLength=line.length();//length of the line received
String rv="";
if(lineLength <= MAX_NUM_SEGMENTS){
rv=line;//set to display value
//nSuccessTrans++;
}else{
rv="error";
//nFailTrans++;
}
displayStr=rv;//set to display value
//digit = displayStr.toInt();// if you are dealing only with numbers
}
/**
* Updates Display Segments
**/
void updateSegments(){
/*
fifthSegmentPos = digit / 10000;
digit %= 10000;
fourthSegmentPos = digit / 1000;
digit %= 1000;
thirdSegmentPos = digit / 100;
digit %= 100;
secSegmentPos = digit / 10;
firstSegmentPos = digit % 10;
*/
firstSegmentPos = GetSegmentCharPos(&displayStr,1);
secSegmentPos = GetSegmentCharPos(&displayStr,2);
thirdSegmentPos = GetSegmentCharPos(&displayStr,3);
fourthSegmentPos = GetSegmentCharPos(&displayStr,4);
fifthSegmentPos = GetSegmentCharPos(&displayStr,5);
//Serial.println("first segment");
digitalWrite(9,HIGH);
digitalWrite(10,LOW);
digitalWrite(11,LOW);
digitalWrite(12,LOW);
digitalWrite(13,LOW);
displaySegmentChar(&firstSegmentPos);
delay(SEGMENT_RENDER_DELAY_MS);
//Serial.println("second segment");
digitalWrite(9,LOW);
digitalWrite(10,HIGH);
digitalWrite(11,LOW);
digitalWrite(12,LOW);
digitalWrite(13,LOW);
displaySegmentChar(&secSegmentPos);
delay(SEGMENT_RENDER_DELAY_MS);
//Serial.println("third segment");
digitalWrite(9,LOW);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
digitalWrite(12,LOW);
digitalWrite(13,LOW);
displaySegmentChar(&thirdSegmentPos);
delay(SEGMENT_RENDER_DELAY_MS);
//Serial.println("fourth segment");
digitalWrite(9,LOW);
digitalWrite(10,LOW);
digitalWrite(11,LOW);
digitalWrite(12,HIGH);
digitalWrite(13,LOW);
displaySegmentChar(&fourthSegmentPos);
delay(SEGMENT_RENDER_DELAY_MS);
//Serial.println("fifth segment");
digitalWrite(9,LOW);
digitalWrite(10,LOW);
digitalWrite(11,LOW);
digitalWrite(12,LOW);
digitalWrite(13,HIGH);
displaySegmentChar(&fifthSegmentPos);
delay(SEGMENT_RENDER_DELAY_MS);
}
/**
* Returns position of the rendering `segment character`
**/
static int GetSegmentCharPos(String* strNum, int pos){
String strNumber = *strNum;
if(strNumber.length()==0) return 0;
if(strNumber.length()>=pos){
char c = strNumber.charAt(strNumber.length()-pos);
if(c=='e') return 10;//e
if(c=='r') return 11;//r
if(c=='o') return 12;//o
if(c=='O') return 13;//O
if(c=='h') return 14;//h
if(c=='l') return 15;//l
if(c-'0'>0) return c-'0';//digit [0-9]
}
return 0;
}
/**
* Sketches single digit
**/
void displaySegmentChar(byte* pos) {
int digitPos = *pos;
for(pin = 2;pin < 9; pin++) {
digitalWrite(pin,seven_seg[digitPos][pin]);
}
}
This code holds to be displayed code as a String object i.e. `displayStr` because i needed to display non-numeric characters as well(e.g. `error`). If you only need digits, you may use unsigned long called `digit`. And you can use following code to get segment numbers;
fifthSegmentPos = digit / 10000;
digit %= 10000;
fourthSegmentPos = digit / 1000;
digit %= 1000;
thirdSegmentPos = digit / 100;
digit %= 100;
secSegmentPos = digit / 10;
firstSegmentPos = digit % 10;