0
votes

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
I think that the problem might be with millis, that will keep returning milliseconds since the arduino begins the program, I think eventually millis-starttime will be larger than secs * 1000 - Josh

2 Answers

2
votes

Change int starttime = millis(); to unsigned long starttime = millis();. This might be the problem because if you are using an int, your program will go crazy after 32 seconds. That is a problem because an int can only hold a number going from -32,768 to 32,767 .

Also, you might as well try this:

while ((millis() - starttime) <= (secs * 1000))
{
  Serial.println("I am in while");
}
1
votes

maybe you can try to reset the millis using something like this, I don't have an arduino so it's not tested but hopefully it can help.

extern volatile unsigned long timer0_millis;
unsigned long reset = 0;

#include <Arduino.h>
int led = 7;
void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);
}

void loop(){
  x();
  Serial.println("Im ending main loop");

  setMillis(reset);
}

void setMillis(unsigned long new_millis){
  uint8_t oldSREG = SREG;
  cli();
  timer0_millis = new_millis;
  SREG = oldSREG;
}

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);
}