ESP8266, похоже, убивает цикл while
Когда я тестировал программу, я обнаружил странное поведение esp8266
Похоже, что цикл while выходит из цикла, даже если нет возможности выйти из кода
Я не знаю, связаны ли они, но вот код (программа представляет собой два разных визуальных шаблона светодиодов, переключаемых кнопкой)
#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); //при изменении цикла while это должно удалить помехи
digitalWrite(led4, LOW);
previousTime = millis();
while (!change){ //визуальный шаблон светодиодов по умолчанию
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){ //после этого все светодиоды должны быть ВЫСОКИМ
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){ //после этого все светодиоды должны быть НИЗКИМИ
digitalWrite(led1, LOW);
previousTime = millis();
}
if (!digitalRead(button) && millis()-pressedButton>200){ //проверяем, была ли нажата кнопка, чтобы прервать цикл while
pressedButton = millis();
break;
}
}
while (change){ //альтернативный вариант визуального оформления светодиодов
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){ //проверяем, была ли нажата кнопка, чтобы прервать цикл while
// нажатая кнопка = millis();
// перерыв;
//}
}
change = !change; //после перерыва в одном из циклов while программа перейдет к другому циклу while
}
Что-то не так с кодом? Вот ссылка на видео поведения для более подробной информации. https://drive.google.com/file/d/1822MHNGQn- A2-HGHhRXz_8xydz-wM4Ha/view?usp=sharing
@tatu101, 👍2
Обсуждение1 ответ
Лучший ответ:
Вы не можете поймать ESP в цикле while таким образом. Есть вещи, которые ему нужно вернуться в основной режим и выполнить между циклами. Вместо этого пусть функция цикла будет вашим циклом. Сделайте операторы while, если операторы и где у вас есть перерыв, вы меняете переменную изменения. Поместите код вверху в оператор if, который проверяет, изменились ли изменения.
#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); //при изменении цикла while это должно удалить помехи
digitalWrite(led4, LOW);
previousTime = millis();
oldChange = change;
}
if (!change) { //визуальный шаблон светодиодов по умолчанию
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) { //после этого все светодиоды должны быть ВЫСОКИМ
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) { //после этого все светодиоды должны быть НИЗКИМИ
digitalWrite(led1, LOW);
previousTime = millis();
}
if (!digitalRead(button) && millis() - pressedButton > 200) { //проверяем, была ли нажата кнопка, чтобы прервать цикл while
pressedButton = millis();
change = true;
}
}
if (change) { //альтернатива визуального оформления светодиодов
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
}
Спасибо! Это устранило нежелательный разрыв второго паттерна. Но в чем причина того, что цикл while не работает внутри другого цикла?, @tatu101
Функция цикла неоднократно вызывается из main(). В main() есть и другие вещи, которые должны происходить между вызовами цикла. Вы не можете перехватить выполнение внутри цикла. Вам нужно время от времени прерывать цикл или вызывать метод yield или Delay(0). В вашем случае вам не нужен цикл while, поскольку цикл уже является циклом., @Delta_G
- Светодиод не гаснет полностью с помощью функции digitalWrite(led, LOW);
- Как определить размер Flash?
- В ESP-12E NodeMCU, какой выход PIN A0?
- Код Arduino для управления 4 светодиодами с 4 кнопок
- Преобразование byte* в int в Arduino
- Каково использование зарезервированных контактов и контактов SDD2, SDD3 NodeMCU?
- NodeMCU (Arduino IDE) «DynamicJsonBuffer» не был объявлен в этой области
- NodeMCU поддерживает внедрение ключей?
Вы не можете поймать ESP в цикле while таким образом. Есть вещи, которые ему нужно вернуться в основной режим и выполнить между циклами. Вместо этого пусть функция цикла будет вашим циклом. Сделайте операторы while, если операторы и где у вас есть перерыв, вы меняете переменную изменения. Поместите код вверху в оператор if, который проверяет, изменились ли изменения., @Delta_G
@Delta_G Пожалуйста, ответьте, а не комментируйте., @Nick Gammon
Что касается вашей проблемы со светодиодом: даже если это произойдет с вашим текущим скетчом, задайте по этому поводу отдельный вопрос. Когда вы это сделаете, пожалуйста, добавьте схему вашей цепи., @the busybee
@NickGammon. Сделанный., @Delta_G
@the busybee, ладно, я не знал, что проблемы не связаны между собой. Как это? https://arduinoprosto.ru/q/93807/led-doesnt-completely-turn-off-with-digitalwriteled-low, @tatu101
Точно. И у вас уже есть ответ., @the busybee