when i call " strobeFunction(500, 500, 1024, 10);" The esp8266 crashes after 6 serial prints. every time. if i remove the function call the esp does not crash. any ideas why this is happening??
unsigned long now2 = 0;
int counter = 0;
unsigned long strobenow = 0;
unsigned long strobenow2 = 0;
bool strobeoff = true;
const int strobe = 4;
void strobeFunction(int delay1, int delay2, int brightness, int times) {
// server.send(200, "ok");
while (counter < times) {
if (millis() - strobenow >= delay1 && strobeoff) {
counter++;
// analogWrite(strobe, brightness); //turn it on
Serial.println("strobe on");
strobeoff = false;
Serial.println("strobe 1");
strobenow2 = millis();
Serial.println("strobe 2");
}
if (millis() - strobenow2 >= delay2 && !strobeoff ) {
Serial.println("strobe 3");
// analogWrite(strobe, 0); //turn it off
Serial.println("strobe ff");
strobenow = millis();
strobeoff = true;
}
}
}
void setup(void) {
pinMode(strobe, OUTPUT);
digitalWrite(strobe, LOW);
Serial.begin(115200);
strobeFunction(500, 600, 1024, 10);
}
void loop(void) {
}
if i only call it like this it does not crash,
strobeFunction(500, 500, 1024, 2);
i dont understand whats wrong
if i call strobeFunction(500, 500, 1024, 2); every 10 seconds like this,
if (millis() - now >= 10000) {
//sendStruct();
Serial.println("started");
counter = 0;
strobeFunction(500, 500, 1024, 2);
now = millis();
}
Hi,
I ran your code on a UNO, and added a serialprint to show the count and it functioned okay.
I put a serialprint in the void loop() to show it had ended.
unsigned long now2 = 0;
int counter = 0;
unsigned long strobenow = 0;
unsigned long strobenow2 = 0;
bool strobeoff = true;
const int strobe = 4;
void strobeFunction(int delay1, int delay2, int brightness, int times) {
// server.send(200, "ok");
while (counter < times) {
if (millis() - strobenow >= delay1 && strobeoff) {
counter++;
// analogWrite(strobe, brightness); //turn it on
Serial.println("strobe on");
strobeoff = false;
Serial.println("strobe 1");
strobenow2 = millis();
Serial.print("strobe 2 counter = ");
Serial.println(counter);
}
if (millis() - strobenow2 >= delay2 && !strobeoff) {
Serial.println("strobe 3");
// analogWrite(strobe, 0); //turn it off
Serial.print("strobe ff counter = ");
Serial.println(counter);
strobenow = millis();
strobeoff = true;
}
}
}
void setup(void) {
pinMode(strobe, OUTPUT);
digitalWrite(strobe, LOW);
Serial.begin(115200);
strobeFunction(500, 600, 1024, 10);
}
void loop(void) {
Serial.println("Finished");
while (1)
{
}
}
Hello,
I had something similar in the past where the solution was to not to call millis() too many times. But store the value of millis() in a temporary variable each cycle. Second thing you could do is be careful with too many Serial.println() as this might cause some buffer overruns or overload on code sections where interrupts are blocked. Other thing that can be usefull: add delay(10) to your code so the processor has some room to schedule saved interrupt tasks.
Another approach that is much clearer is the use of a timer object instead of the millis().
so if i had the same program with lots of those while loops, i could add dealy() or yield() in the main loop instead of all the while loops. i mean obviously this would probably not be ideal. but would work?
thanks for sharing the link. it is in my nature to over complicate things
The code i posted was just a test. the code im going to use will be like this with no while loop.
const int ledPin = A0;// the number of the LED pin
int ledState = LOW; // ledState used to set the LED
unsigned long previousMillis = 0; // will store last time LED was updated
unsigned long previousMillis2 = 0;
const long interval = 1000; // interval at which to blink (milliseconds)
bool strobeoff = true;
int counter = 0;
bool alarm = true;
void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
}
void handleStrobe(int delayOn, int delayOff, int brightness, int times) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= delayOn && strobeoff) {
previousMillis = currentMillis;
counter++;
strobeoff = false;
Serial.println("strobe on");
previousMillis2 = millis();
}
if (currentMillis - previousMillis2 >= delayOff && !strobeoff) {
previousMillis = currentMillis;
strobeoff = true;
Serial.println("strobe off");
previousMillis = millis();
}
if (counter >= times) {
alarm = false;
strobeoff = true;
Serial.println("strobe off counter");
counter = 0;
}
}
void loop() {
if (alarm) {
handleStrobe(500, 500, 1024, 10);
}
}
which is just blinkWithoutDelay + statechange
and the function arguments will be from a web server.
BUT the whole yield() problem with the wifi stack might explain a lot of problems i have with random crashes
I believe that the ESP stuff uses a watchdog timer that throws exception if it doesn't get "patted" often enough. I think main calls it.
So if you have something in your code that takes a long time, without letting the watchdog code have some CPU it will fail. Yield gets around that and I expect that the ESP implementation of delay does too.