Ghosting issue with multiplexing

Hi. I’m a bit of a novice with Arduino, but I’m trying to make a timer up to 90 minutes (00:00:) using the millis option rather than delay (to see how accurate I can get it). I realise there are other modules that do this, however I’m trying to experiment.

I’ve written code to do the timing with delays for multiplexing 4 digits. The display and increment comes out perfectly. I found however of course this affects the clock time and the 4ms delay between each digit affects the 1 second advance time

I then tried to replay the “delay” function with the “millis” function. What I’m finding is a bit of a “ghost flashing” is the best way I could explain it. As the digits change (say the seconds from 00:15 to 00:16, some of the other segments that are off, flash on/off but really quickly and dimmly. This happens only when the time increments each second. I realise it is probably my poor coding, but I’ve spend a day and can’t nut it out. Could someone please check my code below to see if you can point out the error.

Thanks in advance.

//--------------------------------------------------------------------------------------------

int A = LOW; // Set to 0 for common anode digits. Set to 1 if common cathode

int B = HIGH; // Set to 1 for common anode digits. Set to 0 if common cathode

int sec_ones = 0; // Used to indicate what number the digit is set to

int sec_tens = 0; // Used to increment the tens unit

int min_ones = 0; // Used to increment the min_ones units

int min_tens = 0; // Used to increment the min_tens units

long time2 = 0; // Used in delaying the increment clock time

long SecondDuration = 1000; // One second increment clock time

unsigned long currentMillis = 0;

unsigned long previousMillis = 0;

int stepMultiplex = 1;

int delayMp = 3;

// the following array is used to define each led common

byte commons [4] = {9,10,11,12}; // pins to each digit common

// the following array is used to define each led segment for number 0 to 9

byte sevenSegmentPin[7] = {

2,3,4,5,6,7,8};

byte sevenSegment[10][7] = {

{B,B,B,B,B,B,A} , // this is 0

{A,B,B,A,A,A,A} , // this is 1

{B,B,A,B,B,A,B} , // this is 2

{B,B,B,B,A,A,B} , // this is 3

{A,B,B,A,A,B,B} , // this is 4

{B,A,B,B,A,B,B} , // this is 5

{B,A,B,B,B,B,B} , // this is 6

{B,B,B,A,A,A,A} , // this is 7

{B,B,B,B,B,B,B} , // this is 8

{B,B,B,A,A,B,B} , // this is 9

};

//--------------------------------------------------------------------------------------------

void setup()

{

for (byte i=0; i<7; i++)

pinMode(sevenSegmentPin*,OUTPUT); // this sets pins 2 to 8 as outputs*
for(byte i=0; i<4; i++)
pinMode(commons, OUTPUT); // this sets pins 9 to 12 as outputs
for (byte i=0; i<7; i++) {
digitalWrite(sevenSegmentPin, sevenSegment[0]); // this sets pins 2 to 8 as 0
}
}
// This is code for displaying the incremental digit for the “sec_ones”
void sevenSegWrite_1(byte sec_ones) {
for (byte i=0; i<7; i++) {
digitalWrite(sevenSegmentPin, sevenSegment[sec_ones]);
}
}
// This is code for displaying the incremental digit for the “sec_tens”
void sevenSegWrite_2(byte sec_tens) {
for (byte i=0; i<7; i++) {
digitalWrite(sevenSegmentPin, sevenSegment[sec_tens]);
}
}
// This is code for displaying the incremental digit for the “min_ones”
void sevenSegWrite_3(byte min_ones) {
for (byte i=0; i<7; i++) {
digitalWrite(sevenSegmentPin, sevenSegment[min_ones]);
}
}
// This is code for displaying the incremental digit for the “min_tens”
void sevenSegWrite_4(byte min_tens) {
for (byte i=0; i<7; i++) {
digitalWrite(sevenSegmentPin, sevenSegment[min_tens]);
}
}
//-----------------------------------------------------------------------
void loop()
{
currentMillis=millis();
if(stepMultiplex == 1 && (currentMillis - previousMillis) >= delayMp) {
digitalWrite(commons [3],B);
sevenSegWrite_2(sec_tens);
digitalWrite(commons [0],B);
digitalWrite(commons [1],B);
digitalWrite(commons [2],A);
digitalWrite(commons [3],B);
previousMillis=currentMillis;
stepMultiplex=2;
}
if(stepMultiplex == 2 && (currentMillis - previousMillis) >= delayMp) {
digitalWrite(commons [2],B);
sevenSegWrite_3(min_ones);
digitalWrite(commons [0],B);
digitalWrite(commons [1],A);
digitalWrite(commons [2],B);
digitalWrite(commons [3],B);
previousMillis=currentMillis;
stepMultiplex=3;
}
if(stepMultiplex == 3 && (currentMillis - previousMillis) >= delayMp) {
digitalWrite(commons [1],B);
sevenSegWrite_4(min_tens);
digitalWrite(commons [0],A);
digitalWrite(commons [1],B);
digitalWrite(commons [2],B);
digitalWrite(commons [3],B);
previousMillis=currentMillis;
stepMultiplex=4;
}
if(stepMultiplex == 4 && (currentMillis - previousMillis) >= delayMp) {
digitalWrite(commons [0],B);
sevenSegWrite_1(sec_ones);
digitalWrite(commons [0],B);
digitalWrite(commons [1],B);
digitalWrite(commons [2],B);
digitalWrite(commons [3],A);
previousMillis=currentMillis;
stepMultiplex=1;
}
if (millis() - time2 > SecondDuration) {
sec_ones++;
if(sec_ones >9) {
sec_ones=0;
sec_tens++;
}
if(sec_tens>5) {
sec_tens=0;
min_ones++;
}
if(min_ones>9) {
min_ones=0;
min_tens++;
}
if(min_tens>5) {
sec_ones=0;
sec_tens=0;
min_ones=0;
min_tens=0;
}
sevenSegWrite_1(sec_ones);
sevenSegWrite_2(sec_tens);
sevenSegWrite_3(min_ones);
sevenSegWrite_4(min_tens);
time2 = millis();
}
}

What I’m finding is a bit of a “ghost flashing” is the best way I could explain it. As the digits change (say the seconds from 00:15 to 00:16, some of the other segments that are off, flash on/off but really quickly and dimmly. This happens only when the time increments each second. I realise it is probably my poor coding, but I’ve spend a day and can’t nut it out. Could someone please check my code below to see if you can point out the error.

Haven’t read through the code but wanted to point out that this could be a hardware issue as well. Do you have schematic of the setup? Some misplaced caps can cause this issue.

Late last night I worked out the issue. I called up the writing of the 4 digits twice - once in the middle of the code and a second time at the very end. Sorry, I don’t know how I missed that. Have to loose that tunnel vision!