I am trying to make my own delay function. Briefly mydelay
function is calling toggled
function every secs
seconds. The code is not well written, i know (this is the first version). But i am just trying to get it work properly. Then i will refactor it. But i have some unexpected bugs. First time the loop in x
function is working properly. It is printing "I am in while" for 1 second and then it prints "Im ending mydelay" which is the behaviour i want. But after finishing the loop in x
. The second time when it loops. It enters the mydelay
function (that is ok). But then it is not printing "I am in while" at all. It just prints "Im ending mydelay" which is not good.
Here is the code:
#include <Arduino.h>
int led = 7;
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop() {
x();
Serial.println("Im ending main loop");
}
void x() {
for (int i = 0; i <= 10; i++) {
mydelay(led, 0, 1);
mydelay(led, 1, 1);
}
}
void mydelay(int pin, int hol, int secs) {
int starttime = millis();
while ((millis() - starttime) <= (secs * 1000)) Serial.println("I am in while");
toggled(pin, hol);
Serial.println("Im ending mydelay");
}
void toggled(int pin, int hol) {
digitalWrite(led, hol);
}
2 Answers 2
As mentioned in the comments, your main problem is you declare starttime
as an int
. This is a signed value with a range of -32,768 to 32,767. You will quickly overflow - in about 32 seconds.
The solution is to use an unsigned long
which has a range of 0 to 4,294,967,295.
-
Yeah,actually i asked the exactly the same question on stackoverflow.And got my answer.But anyways i appreciate the answer.Silidrone– Silidrone2016年11月11日 12:20:35 +00:00Commented Nov 11, 2016 at 12:20
-
Btw,Isnt range of int on arduino 65536-1 ?Silidrone– Silidrone2016年11月11日 12:21:12 +00:00Commented Nov 11, 2016 at 12:21
-
@MuhamedCicak That would be for
unsigned int
. Without specifyingunsigned
you get a signed int.001– 0012016年11月11日 14:40:33 +00:00Commented Nov 11, 2016 at 14:40 -
True... I forgot that,i am pretty new to C so yea.I am reading this K&R Book.I dont know if you know it.Silidrone– Silidrone2016年11月11日 17:49:18 +00:00Commented Nov 11, 2016 at 17:49
You can try something along these lines:
void verboseDelay(unsigned long ms)
{
unsigned long now = millis();
Serial.print(F("delaying"));
unsigned long start = now, lastPrintTime = now;
do {
now = millis();
if (now - lastPrintTime >= 20) {
Serial.write('.');
lastPrintTime += 20;
}
} while (now - start < ms);
Serial.println();
}
The trick is to used unsigned long
for all the time-related variables,
and also to avoid printing too fast.
starttime
should beunsigned long
. 2) it is a bad idea toSerial.println()
inside a tight loop: you will fill the output buffer and be slowed down by the prints.