Arduino integer overflow headscratcher

I was testing out a piece of Arduino code that someone sent my way. They complained that a globalVariable value increment was not having any effect whatsoever. To better understand see the following sketch. Essentially, if all goes well, once the globalVariableTesting hits a value of 10, the program should stop blinking the LEDs. However, this was not happening. The program would continue blinking the LED forever. This was quite a headscratcher. I thought about it quite a bit and tried various things… It was so simple a program that I started doubting the compiler optimization etc and could not understand it. Finally, after I set the Serial monitor on with values being printed, I started seeing values of the variable being -32768, -32767 and thought oops looks like some corruption and still did not connect the dots. Finally, after spending a good bit more of time, I realized that the if condition takes time because there are delay statements in there. Once the variable goes over 10, there is no delay in the loop function since the if statement is not executed anymore. The loop just blows over the next 32758 values of the global variable in a jiffy given that the arduino oscillator runs at 16Mhz. It then promptly overflows the variable value to -32768 and merrily starts executing the loop again. Aha, so the mystery is finally solved.

To ‘FIX’ the program, just move the globalVariableTesting variable on line 12 in the ‘if’ block so that it does not get incremented after it has reached the value of 10.

Hope this helps you avoid some headscratching.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int globalVariableTesting = 0;
int ledPin = 10;

void setup() {
    // put your setup code here, to run once:
    pinMode (ledPin, OUTPUT);
    //Serial.begin(9600);
}

void loop()
{
    globalVariableTesting++;
    if (globalVariableTesting < 10)
    {
       //Serial.println(globalVariableTesting);
       BlinkLed(500, 500);
     }
}

void BlinkLed(int x, int y)
{
    digitalWrite (ledPin, HIGH);
    delay (x);
    digitalWrite (ledPin, LOW);
    delay(y);
    digitalWrite (ledPin, HIGH);
    delay (x);
    digitalWrite (ledPin, LOW);
    delay(y);
}

Update

Heard from a friend who loves TortoiseGit, that you can do the same in TortoiseGit by selecting “Wincred – current Windows user” in the “credential” section. See screenshot below for better illustration:

tortoisegit

 

Leave a comment

Your email address will not be published. Required fields are marked *