Sketch works intermittently

I’m fairly new to arduino and C, and set myself the challenge of making a 7 segment display count to ten. I’ve connected the leds to the arduino, not via a shift register.

I have been mostly successful, but have a weird bug; when I first upload the sketch, it goes through the little set up flash I wrote within setup void(), but does not display the numbers… but when I press the hardware rest button, it works perfectly. Press it again and it fails, again and it it works, and so on! i.e. pressing the hard reset flip-flops the arduino between running the code correctly and incorrectly (or at least incompletely).

There are some other refinements I will make, the main one being to ballance the brightness of displaying different numbers (digits with few segments, e.g. 1 appear more bright than digits with more segments (8)… I’m sure I can make the code more efficient/elegant too, but this flip flop bug I have no clue about.

Here is my sketch:

void setup () {

//Serial.begin(9600);

for ( int a = 2; a < 10; a++ ) {
pinMode(a,OUTPUT);
digitalWrite(a,LOW);
delay(50);
digitalWrite(a,HIGH);
}
}

void loop () {

for ( int i=0; i<10; i++){
sevenseg ( i , 300 );
}
//sevenseg( 6, 1000 );

delay (200);
//for ( int v=0 ; v<=9 ; v++ ){
//sevenseg ( v , 1000 );
//}

}

void sevenseg ( int value, unsigned long time ){ //displays the number ‘value’ for a length of ‘time’ in ms.
const int Pinouts[8] = {
2,3,4,5,6,7,8,9 };

int Pins = 8;
int onoff;
int thispin=0;

int segs[10][8] = {
//A B C D E F G dp - This matrix says which LEDs to turn on to create each number
1,1,1,1,1,1,0,0, //0
0,1,1,0,0,0,0,0, //1
1,1,0,1,1,0,1,0, //2
1,1,1,1,0,0,1,0, //3
0,1,1,0,0,1,1,0, //4
1,0,1,1,0,1,1,0, //5
1,0,1,1,1,1,1,0, //6
1,1,1,0,0,0,0,0, //7
1,1,1,1,1,1,1,0, //8
1,1,1,1,0,1,1,0, //9
};

unsigned long startDisp = millis();
unsigned long endDisp = startDisp + time;
unsigned long timecheck;

while ( timecheck < endDisp ){
Serial.println(startDisp);
Serial.println(endDisp);
Serial.println( timecheck );
for (int whichpin=0; whichpin<Pins; whichpin++ ){
thispin=Pinouts[whichpin];
onoff = segs[value][whichpin];
if (onoff==1)
{
digitalWrite (thispin, HIGH);
digitalWrite (thispin, LOW);
}
}
timecheck=millis();
}
for (int off=0; off<9 ; off++){
digitalWrite (off, HIGH);
}
}

void setup () {

//Serial.begin(9600);

for ( int a = 2; a < 10; a++ ) {
pinMode(a,OUTPUT);
digitalWrite(a,LOW);
delay(50);
digitalWrite(a,HIGH);
delay(50); // < -------------------------------- add delay here
}
}

have a look on the while loop syntax : do - while

Thanks, that solved it!

However, I don't quite understand what's causing the behavior I'm seeing.

Am I right in thinking that it could be to do with the way the arduino is assigning, writing and reading the variables to it's memory, and this is persistent between resets? I updated my code with the following (using the original while loop), which also solved the problem.

unsigned long startDisp = 0;
startDisp = millis();
unsigned long endDisp = startDisp + time;
unsigned long timecheck = 0;

Which, I think, solved the problem by overwriting the timer variables every time the function is called. Is that correct?

The timer variable should be a global variable, which will make it accessible from where ever you are in your code.

If you do a reset, everything will be initialised again, as then your code will restart in the setup section.
And then your code is "brain flushed".

And YES - your variables are reset everytime you call the function.
These are the variables that preferably should be declared as globals, in the very top of your code as the first lines.

Your code to turn off all the segments at the end, is writing to the wrong pins.

Also, your method of calculating the time is potentially wrong, when millis( ) rolls over. You are better off calculating the time since the start time, instead of the time until the end time.

Thanks to both of you, really useful stuff!