When i was testing out a program I found a strange behavior of esp8266
It seems to get out of a while loop even when there's no option of getting out on code
I don't know if these are related but here's the code (the program is just two different visual patterns of leds toggled by a button)
#define led1 D0
#define led2 D1
#define led3 D2
#define led4 D3
#define button D7
unsigned long pressedButton;
bool change = 0;
unsigned long previousTime;
unsigned int difference;
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(button, INPUT_PULLUP);
}
void loop(){
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW); //when the while loop change, this should delete interference
digitalWrite(led4, LOW);
previousTime = millis();
while (!change){ //default visual pattern of leds
difference = millis()-previousTime;
if (!digitalRead(led1) && difference>=200){
digitalWrite(led1, HIGH);
}
if (!digitalRead(led2) && difference>=400){
digitalWrite(led2, HIGH);
}
if (!digitalRead(led3) && difference>=600){
digitalWrite(led3, HIGH);
}
if (!digitalRead(led4) && difference>=800){ //after here, all the leds should be HIGH
digitalWrite(led4, HIGH);
}
if (digitalRead(led4) && difference>=1000){
digitalWrite(led4, LOW);
}
if (digitalRead(led3) && difference>=1200){
digitalWrite(led3, LOW);
}
if (digitalRead(led2) && difference>=1400){
digitalWrite(led2, LOW);
}
if (digitalRead(led1) && difference>=1600){ //after here, all the leds should be LOW
digitalWrite(led1, LOW);
previousTime = millis();
}
if (!digitalRead(button) && millis()-pressedButton>200){ //check if button was pressed to break while loop
pressedButton = millis();
break;
}
}
while (change){ //alternative of visual pattern of leds
difference = millis()-previousTime;
if (!digitalRead(led1) && difference>=200){
digitalWrite(led1, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
}
if (digitalRead(led1) && difference>=400){
digitalWrite(led1, LOW);
digitalWrite(led4, LOW);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
previousTime = millis();
}
//if (!digitalRead(button) && millis()-pressedButton>=200){ //check if button was pressed to break while loop
// pressedButton = millis();
// break;
//}
}
change = !change; //after a break in one of the while loops, this will make the program go to the other while loop
}
Is there something wrong with the code? Here is a link of a video of the behavior for more details https://drive.google.com/file/d/1822MHNGQn-A2-HGHhRXz_8xydz-wM4Ha/view?usp=sharing
-
You can't trap an ESP in a while loop like that. There are things it needs to get back to main and do between loops. Instead, let the loop function be your loop. Make the while statements if statements and where you have break, that's where you change the change variable. Put the code at the top in an if statement that checks to see if change has changed.Delta_G– Delta_G2023年07月11日 21:59:41 +00:00Commented Jul 11, 2023 at 21:59
-
@Delta_G Please make an answer and not a comment.Nick Gammon– Nick Gammon ♦2023年07月12日 05:04:05 +00:00Commented Jul 12, 2023 at 5:04
-
Concerning your LED issue: Even if it happens with your current sketch, please post a separate question for it. When you do, please add a schematic of your circuit.the busybee– the busybee2023年07月12日 07:13:25 +00:00Commented Jul 12, 2023 at 7:13
-
1@NickGammon. Done.Delta_G– Delta_G2023年07月12日 16:54:21 +00:00Commented Jul 12, 2023 at 16:54
-
@the busybee all right I didn't know the problems were not related. Like that? arduino.stackexchange.com/questions/93807/…tatu101– tatu1012023年07月13日 23:13:08 +00:00Commented Jul 13, 2023 at 23:13
1 Answer 1
You can't trap an ESP in a while loop like that. There are things it needs to get back to main and do between loops. Instead, let the loop function be your loop. Make the while statements if statements and where you have break, that's where you change the change variable. Put the code at the top in an if statement that checks to see if change has changed.
#define led1 D0
#define led2 D1
#define led3 D2
#define led4 D3
#define button D7
unsigned long pressedButton;
bool change = 0;
bool oldChange = 1;
unsigned long previousTime;
unsigned int difference;
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(button, INPUT_PULLUP);
}
void loop() {
if (change != oldChange) {
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW); //when the while loop change, this should delete interference
digitalWrite(led4, LOW);
previousTime = millis();
oldChange = change;
}
if (!change) { //default visual pattern of leds
difference = millis() - previousTime;
if (!digitalRead(led1) && difference >= 200) {
digitalWrite(led1, HIGH);
}
if (!digitalRead(led2) && difference >= 400) {
digitalWrite(led2, HIGH);
}
if (!digitalRead(led3) && difference >= 600) {
digitalWrite(led3, HIGH);
}
if (!digitalRead(led4) && difference >= 800) { //after here, all the leds should be HIGH
digitalWrite(led4, HIGH);
}
if (digitalRead(led4) && difference >= 1000) {
digitalWrite(led4, LOW);
}
if (digitalRead(led3) && difference >= 1200) {
digitalWrite(led3, LOW);
}
if (digitalRead(led2) && difference >= 1400) {
digitalWrite(led2, LOW);
}
if (digitalRead(led1) && difference >= 1600) { //after here, all the leds should be LOW
digitalWrite(led1, LOW);
previousTime = millis();
}
if (!digitalRead(button) && millis() - pressedButton > 200) { //check if button was pressed to break while loop
pressedButton = millis();
change = true;
}
}
if (change) { //alternative of visual pattern of leds
difference = millis() - previousTime;
if (!digitalRead(led1) && difference >= 200) {
digitalWrite(led1, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
}
if (digitalRead(led1) && difference >= 400) {
digitalWrite(led1, LOW);
digitalWrite(led4, LOW);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
previousTime = millis();
}
}
change = false
}
-
Thank you! That resolved the unwanted break on the second pattern. But what is the reason for the while loop not working inside another loop?tatu101– tatu1012023年07月13日 18:47:06 +00:00Commented Jul 13, 2023 at 18:47
-
The loop function is called repeatedly from main(). There are other things in main() that have to happen in between calls to loop. You can't trap execution inside loop. You have to let loop exit once in a while or call yield or delay(0). In your case, you didn't need a while loop since loop is already a loop.Delta_G– Delta_G2023年07月14日 03:28:36 +00:00Commented Jul 14, 2023 at 3:28
Explore related questions
See similar questions with these tags.