Суть вопроса представлено в видео по ссылке. Исходный код Код (C++): #define BLYNK_PRINT Serial #include <WiFi.h> #include <WiFiClient.h> #include <BlynkSimpleEsp32.h> char auth[] = "xxx";//токен блинка char ssid[] = "xxx";//SSID файфая char pass[] = "xxx";//wifi пароль #define but 2 //пин кнопки #define relay 13 //пин реле unsigned long timing; int ButtonFlag; //флаг int button; //значение кнопки int buttonState; //значение кнопки блинка int del = 100; //задержка, необхожима для стабильной обработки нажатия кнопок void setup() { Serial.begin(9600); pinMode(but, INPUT); pinMode(relay, OUTPUT); Blynk.begin(auth, ssid, pass); delay(1000); } void loop() { if (millis() - timing > 1000){ Blynk.run();//запуск блинка } button = digitalRead(but);//считывание значений кнопки if( (ButtonFlag==0) && (button==1) ){ //если кнопка нажата, подымаем флаг ButtonFlag = 1; //подымаем флаг buttonState=1; //изменяем значение переменной кнопки блинка, т.к она еще не считывалась delay(del); //задержка Serial.println("1"); }else if( (ButtonFlag==1) && (button ==1) ){//если кнопка нажата 2 раз опускаем флаг ButtonFlag=0; //опускаем флаг buttonState=0; //изменяем значение переменной кнопки блинка, т.к она еще не считывалась delay(del); //задержка } if(ButtonFlag==1){//если флаг поднят,то включаем реле и включаем кнопку на юлинке digitalWrite(relay, HIGH);//включаем реле Blynk.virtualWrite(V1, HIGH); //включаем кнопку на блинке }else{//если опущен, то выключаем реле и кнопку на блинке digitalWrite(relay, LOW); //выключаем реле Blynk.virtualWrite(V1, LOW); //выключаем кнопку на блинке } if( (buttonState==0) && (ButtonFlag==1) ){//если выключается кнопка на блинке, то опускаем флаг ButtonFlag=0; //опускаем флаг } if( buttonState == 1 ){//если нажата кнопка на блинке, то подымаем флаг ButtonFlag=1;//подымаем флаг } } BLYNK_WRITE(V1) {//считывание значения кнопки блинка buttonState = param.asInt(); } Необходимо скорректировать код, исключить моргание управляемого светодиода. Пока кнопка не будет отжата, программа ни чего не исполняла и ждала отжатия
Самое простое и радикальное... ну и рабочее это delay перетащить после включения/выключения реле(светодиода), а не в цикле анализа состояния кнопки. можно ещё и анализировать состояние этого самого реле. Да и анализ кнопки в конце не надо. Вы же реализовали flip-flop... хотели по крайней мере. Ну так зачем реализацию убиваете? Анализируйте в одном месте!
Спасибо поржал. Начал ржать ещё с предыдущего поста с просьбой об установке компилятора esp32 в среду ардуино. Продолжай, годный контент.
DenKiva - начнем с того, что выложенный код вообще не компилируется - в нем есть функция setup() из 5 строк, функция loop() из 2х строк, а что идет дальше - фиг знает, какие-то обрывки кода, лежащие вне функций. Очевидно. что на видео снята работа не этого кода - соответсвенно и править нужно не ту, извините фигню, что выложена, а тот код, что снят в видео.
Честно говоря вообще не понимаю зачем там столько флагов и задержек, если нужно совершать действия только по отпусканию кнопки, то: Код (C++): if ( digitalRead( but )==1 ) { //Если кнопка нажата (высокий уровень) while ( digitalRead( but ) == 1 ) do NOP; //Цикл ожидания отпускания кнопки .... ... - выполняем свои действия после отпускания кнопки } Ну и я бы ещё в начале воткнул защиту от дребезга, с небольшим делеем, на 5мс. P.S. Но если вы хотите что бы пока кнопка нажата МК выполнял ещё какие то действия, то конечно этот способ не подходит.
Если вы про это, то ваш код немного ....неверный: условие if((ButtonFlag==1)&&(digitalread(кнопка)==0)) у не будет выполнятся бОльшую часть времени, а следовательно постоянно будет вызываться: Правильней сделать так: Код (C++): if ( ( ButtonFlag==0 )&&(digitalread(кнопка)==1)){ //Флаг = 0, на кнопке высокий уровень, значит её нажали ButtonFlag=1; ... выполняем свои действия , они выполнятся один раз, т.к. флаг останется в "1" }; Далее в основном цикле надо сбросить флаг как только отпустили кнопку if ( ( ButtonFlag==1 )&&(digitalread(кнопка)==0)){ //Если флаг поднят, а кнопка отжата (низкий уровень) ButtonFlag=0; //Сбрасываем флаг } Теперь вы можете давить на кнопку сколько угодно долго, инструкция выполнится только 1 раз, а следующее нажатие будет зафиксировано только после отпускания кнопки.