Just got my board and ran into an interesting issue while doing the blink tutorial. I wanted to change the code up a bit and set it so that it would blink for n(3 for this example/test) number of times and then stop. I was thinking I would use a counter variable that starts at zero and increments every time I go thru the loop() function.
int count;
void setup() {
// initialize the digital pin as an output.
// Pin 13 has an LED connected on most Arduino boards:
pinMode(13, OUTPUT);
count=0;
}
void loop() {
if(count<3)
{
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(1000); // wait for a second
}
count=count+1;
}
So this does not work. The led's blink continuously. Maybe they stop but the loop function is so quick that it runs enough times for the int variable counter to overflow and loop around. I do not detect a delay while/if it does this.
If I change the if statement to a while statement then it works. I can also change int to unsigned long int and it works...... although If this is doing what I said above then if I wanted long enough shouldn't it loop/overflow and blink again.
If I pull the counter=counter+1 into the for loop it will blink the 3 times and stop. Is there anyway to have the counter outside the if statement while inside the loop() function.
Is there anyway to have the counter outside the if statement while inside the loop() function.
Yes.
What is happening is that count is incremented on every pass through loop. So, count is 0, 1, 2, and the LED blinks. Then, count is 4, 5, 6, etc, and nothing happens (very quickly). When count gets to 32,767, the next increment is to -32768, which, of course, is less than 3, so the LED blinks again.
The trick is to only increment count when it is less than 3.
Thats my thinking on it but..... I have it setup now with a long int so that when it overflow/wraps around it will then blink a lot because of the negative value. I have had it running for 30 minutes and after the first 3 blinks it has yet to "wrap/overflow". Is a long that much bigger than an int that I would not see any hesitation in blinking with and int and then experience 30+ min wait with a long.
Also if what you said is the case then why does it act differently when using a while statement in place of the if statement. Shouldn't it loop around and act the same. With a while statement it only blinks 3 times.
nedwards:
Is a long that much bigger than an int that I would not see any hesitation in blinking with and int and then experience 30+ min wait with a long.
To give you an idea on the magnitude difference between an int and a long... Imagine continuously counting seconds starting at 0. It would take you about 18 hours to hit the limit of an int while it would take you 136 years to hit the limit of a long.
Imagine continuously counting seconds starting at 0. It would take you about 18 hours to hit the limit of an int while it would take you 136 years to hit the limit of a long.
This implies that you increment the counter once a second. The Arduino increments the counter a bit more often than that.
so an int is -32,768 to 32,767 and a long is -2,147,483,648 to 2,147,483,647. All I really care about is the positive side because I want to know how long until it wraps to the negative side. When it does wrap it will take 2 sec for a complete led on/off blink . So I am not worried about missing it once it wraps to the neagtive side. It will blink for a long time. The uno that I have runs at 16mhz so that is 1610^6=16,000,000 cycles per sec. I do not know how many cyles it takes to execute the add instruction for the counter=counter+1 but I will assume a 3 cycle non pipe lined. So 16mhz/3 =5.33310^6 addition per sec once the if statement evaluates to false. 5,333,333>32,767 so with an int we would wrap around in less than a second. Now with a long 2147483647/5333333=~402 seconds.
So I know that I made some generalizations and that there is more to it than this but in aprox 6 to 7 min it should loop and then start blinking again but it does not. Does anyone have any insights into what is going on.
move the count = count + 1; into the if and see what happens.
int count;
void setup() {
// initialize the digital pin as an output.
// Pin 13 has an LED connected on most Arduino boards:
pinMode(13, OUTPUT);
count=0;
}
void loop() {
if(count<3)
{
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(1000); // wait for a second
count=count+1;
}
}
Imagine continuously counting seconds starting at 0. It would take you about 18 hours to hit the limit of an int while it would take you 136 years to hit the limit of a long.
This implies that you increment the counter once a second. The Arduino increments the counter a bit more often than that.
byte count;
void setup() {
// initialize the digital pin as an output.
// Pin 13 has an LED connected on most Arduino boards:
pinMode(13, OUTPUT);
count=0;
while (count<3)
{
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(1000); // wait for a second
count++;
}
}
void loop() {
}
Once teh counter overflows and starts at -32768 it then counts up every 2 seconds, so 65536 seconds to hit 0 + 6 more seconds to count to 3, =65542 seconds, or 1093 minutes, or 18.2 hours of blinking once it starts blinking again. To go from 3 to 32767 wouldn't take very long...
Fixed the code I put above. In short there's no reason why the counter should ever reach 4. But then there's no reason to put any of that code inside loop().