Reputation: 39
I am writing a delay function for Arduino to be used in a project. The reason is that TIMER0 (the default timer used for Arduino delay) is occupied with PWM control. The test code for the delay function is as follows:
int count;
unsigned long int sec;
void delay_ms (uint16_t millisecond) {
sec = ((16000000/12)/1000)*millisecond;
for (count = 0; count < sec; count ++);
}
void setup (){
Serial.begin(9600);
}
void loop (){
Serial.println('a');
delay_ms(1000);
Serial.println('b');
delay_ms(1000);
}
This setup simply prints a and b with a 1-second delay between each. It's working properly but before that there were other setups I used that did not work. The changes are:
Based on the knowledge provided by Arduino Reference on Unsigned Long and Int, I'd thought that they are essentially the same in this case. Therefore, I'd like to get some clarification in terms of how the data is processed by the loop as well as the delay function.
Upvotes: 0
Views: 281
Reputation: 409166
You tagged the question with arduino-uno
, and the link you provide for int
explicitly say that int
on an Uno is 16 bits, with a range of -32768 to 32767:
On the Arduino Uno (and other ATmega based boards) an int stores a 16-bit (2-byte) value. This yields a range of -32,768 to 32,767 (minimum value of -2^15 and a maximum value of (2^15) - 1).
Now ((16000000/12)/1000)*1000
(for a delay of 1000
) is 1333333
, which is way over the limit of an int
(even an unsigned int
). That means your int
variable count
will overflow in the loop and you will have undefined behavior.
What happens practically when count
overflow is that it becomes negative (since the Uno is using two's complement for negative numbers). Then you count up to zero and the possitive number until it overflows again, leading to count < sec
to always be true and give you an infinite loop.
The solution is, of course, to use types which can handle such large numbers as yours without problems. Like e.g. unsigned long
.
Oh, and stop using global variables. Both count
and sec
should be local inside your delay function. And stop making your own delay functions, AFAIK the Arduino framework should have delay functions you can use. Lastly, Arduino is programmed in C++, not C, although without the full and proper standard library (it uses its own framework instead).
Upvotes: 3