Couple things:
Set up your segments in the standard way:
a
f b
g
e c
d DP
and have the fonts defined to turn on the digits
byte fontArray = {
0b00111111, // 0, turns on segments f-e-d-c-b-a
0b00000110, // 1, c-b are on
0b01011011, // 2, g-e-d-b-a are on
0b01001111, // 3, g-d-c-b-a
// etc. up thryu 9
Also, have a segment mask array, this will determine which segment gets turned on
byte segmentMask = {
0b00000001, // a
0b00000010, // b
0b00000100, // c
0b00001000, // d
0b00010000, // e
0b00100000, // f
0b01000000, // g
0b10000000, }; // DP
Then have a byte for each segment:
byte digit0;
byte digit1;
and put the pins used for the segment into an array
byte pinArray = {9,8,7,6,5,4,3,2,}; // the segment IO pins you listed, from DP-g-f-e-d-c-b-a
(this order may need adjusting) for the anodes of the display
Next write a multiplexing loop that enables 1 GND and 1 Segment, leave a segment on for 1mS, then move on to the next one. That way all segments are refreshed every 14mS for 70+Hz refresh rate, will be bright & flicker free as up to 20mA can sourced into each segment. Use blink without delay style programming.
void loop(){
// first 4 lines here are the heart of blink without delay
currentMillis = millis(); // all time elements are type unsigned long
elapsedMillis = currentMillis - previousMillis;
if (elapsedMillis >= 1mS){
previousMillis = previousMillis + 1mS;
// ok, 1 mS has passed turn off the prior segment and turn on the next one.
// written as a loop within a loop - outer loop is the digit select, inner loop is the segment select
// but - loop counters are seperately tracked (vs using a for loop) so the count can be mixed with the time tracking:
// turn off prior segment (whether it was on or off)
digitalWrite (pinArray[segmentCount], LOW);
digitalWrite (gnd1, HIGH); // whatever you called those
digitalWrite (gnd2, HIGH);
// update the segment to be updated
segmentCount = segmentCount +1;
if (segmentCount == 8){ // or 7 if not using Decimal Point
segmentCount = 0; // reset to initial segment - the "inner loop"
digitCount = digitCount + 1;
if (digitCount == 2){
digitCount = 0; // reset to initial digit - the "outer loop"
}
}
// now, the segment to light up in a digit has been selected.
// look up the font for the byte to be displayed,
// mask off the value of a particular segment, and turn it on if it's a 1:
if (digitCount == 0){ // first digit
if ( (segmentMask[segmentCount] & fontArray[byte0]) >0){
// so if segmentCount == 3, segmentMask[3] will be 0b00001000
// and if byte0 = 3, then fontArray[3] = 0b01001111, the & will result on 0b00001000,
// which is >0, (just looking for 0 or not 0; and >0 is same as not 0) so turn on segment D
digitalWrite (pinArray[segmentCount], HIGH);
// and turn the Gnd back on
digitalWrite (gnd1, LOW);
}
}
// if not the first digit, must be the 2nd
else{ // digitCount ==1
if ( (segmentMask[segmentCount] & fontArray[byte1]) >0){
// so if segmentCount == 3, segmentMask[3] will be 0b00001000
// and if byte0 = 3, then fontArray[3] = 0b01001111, the & will result on 0b00001000,
// so turn on segment D
digitalWrite (pinArray[segmentCount], HIGH);
// and turn the Gnd back on
digitalWrite (gnd1, LOW);
}
}
}
// now do whatever else you're doing for remainder of 1mS until the next update time
} // end loop
I think that covers it all - got blink without delay, got an array to look up fonts, got an array to look up the segment to turn on.
Take out all the comments, makes a nice little loop.