2

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

asked Jul 11, 2023 at 20:57
6
  • 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. Commented Jul 11, 2023 at 21:59
  • @Delta_G Please make an answer and not a comment. Commented 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. Commented Jul 12, 2023 at 7:13
  • 1
    @NickGammon. Done. Commented 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/… Commented Jul 13, 2023 at 23:13

1 Answer 1

2

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 
}
answered Jul 12, 2023 at 16:34
2
  • 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? Commented 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. Commented Jul 14, 2023 at 3:28

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.