Всем доброго времени суток. Перерыл весь интернет, не могу найти нужный алгоритм подсчета времени нажатия на кнопку. По простому нажатию кнопки нужно включать 3 светодиода в режиме Р, а если зажать кнопку на 3 и более секунд - перейти в меню выбора этого режима и последовательными нажатиями на ту же кнопку переключать его. Если состояние кнопки в режиме меню LOW втечении 3 сек - выход из меню. Собственно мой код, помогите со входом в меню пожалуйста? Как сделать условие, "если кнопка зажата 3 сек? #include <Bounce.h> #define KEY 2 //дефайним значения пинов с кнопкой и со светодиодом #define LED_1 8 //дефайним значения пинов с кнопкой и со светодиодом #define LED_2 7 //дефайним значения пинов с кнопкой и со светодиодом #define LED_3 6 //дефайним значения пинов с кнопкой и со светодиодом Bounce bouncer = Bounce(KEY,10); //создаем объект класса Bounce. Указываем пин, к которому подключена кнопка, и время дребезга в мс. int state = LOW; //задаем начальное состояние всех светодиодов "выключен" int mode = 1; //задаем начальный режим работы светодиодов void setup() { pinMode(KEY,INPUT); //определяем режимы работы пинов pinMode(LED_1,OUTPUT); //определяем режимы работы пинов pinMode(LED_2,OUTPUT); //определяем режимы работы пинов pinMode(LED_3,OUTPUT); //определяем режимы работы пинов } void loop() { if ( bouncer.update() ) { //если сменилось состояние кнопки if ( bouncer.read() == HIGH) { //если считано значение 1 if ( state == LOW ) { //если свет был выключен state = HIGH; // будем его включать } else { // если свет был включен state = LOW; // будем выключать } } } if (state == HIGH) { // если свет включен switch (mode){ case 1: // Если значение mode равно 1 digitalWrite (LED_1, HIGH); // Включаем светодиод digitalWrite (LED_2, HIGH); // Включаем светодиод digitalWrite (LED_3, HIGH); // Включаем светодиод break; // Выходим из свитч case 2: // Если значение mode равно 2 digitalWrite (LED_1, HIGH); // Включаем светодиод digitalWrite (LED_2, HIGH); // Выключаем светодиод digitalWrite (LED_3, LOW); // Выключаем светодиод break; // Выходим из свитч case 3: // Если значение mode равно 3 digitalWrite (LED_1, HIGH); // Включаем светодиод digitalWrite (LED_2, LOW); // Выключаем светодиод digitalWrite (LED_3, LOW); // Выключаем светодиод break; // Выходим из свитч case 4: // Если значение mode равно 4 digitalWrite (LED_1, LOW); // Выключаем светодиод digitalWrite (LED_2, HIGH); // Включаем светодиод digitalWrite (LED_3, LOW); // Выключаем светодиод break; // Выходим из свитч case 5: // Если значение mode равно 5 digitalWrite (LED_1, LOW); // Выключаем светодиод digitalWrite (LED_2, LOW); // Выключаем светодиод digitalWrite (LED_3, HIGH); // Включаем светодиод break; // Выходим из свитч case 6: // Если значение mode равно 6 digitalWrite (LED_1, LOW); // Выключаем светодиод digitalWrite (LED_2, HIGH); // Включаем светодиод digitalWrite (LED_3, HIGH); // Включаем светодиод break; case 7: // Если значение mode равно 7 digitalWrite (LED_1, HIGH); // Включаем светодиод digitalWrite (LED_2, LOW); // Выключаем светодиод digitalWrite (LED_3, HIGH); // Включаем светодиод break; } }else { // если свет выключен digitalWrite (LED_1, LOW); // Выключаем светодиод digitalWrite (LED_2, LOW); // Выключаем светодиод digitalWrite (LED_3, LOW); // Выключаем светодиод } }
Запоминайте момент, в который произошло изменение состояния кнопки. Также храните момент предыдущего изменения состояния. Анализируйте разность времен смены состояний и в зависимости от результата переключайте режим либо выполняйте логику конкретного режима. В логике второго режима проверяйте разность текущего времени и времени входа в режим. Если больше трех секунд - переключайте режим обратно.
Спасибо, примерно так и сделал, теперь проблема, как ни странно, выключить свет по кратковременному нажатию. Программа сбивает счетчик и не может понять долго ли я держу кнопку или просто хочу выключить свет. Куда копать, чтобы избавиться от граблей? Мой обновленный скетч без функции выключения света: #include <Bounce.h> #define DEBUG #ifdef DEBUG #define DEBUG_PRINT(x) Serial.print(x) #define DEBUG_PRINTLN(x) Serial.println(x) #else #define DEBUG_PRINT(x) #define DEBUG_PRINTLN(x) #endif #define KEY 9 //дефайним значения пинов с кнопкой и со светодиодом #define LED_1 8 //дефайним значения пинов с кнопкой и со светодиодом #define LED_2 7 //дефайним значения пинов с кнопкой и со светодиодом #define LED_3 6 //дефайним значения пинов с кнопкой и со светодиодом Bounce bouncer = Bounce(KEY,40); //создаем объект класса Bounce. Указываем пин, к которому подключена кнопка, и время дребезга в мс. boolean state = 0; //задаем начальное состояние всех светодиодов "выключен" int mode = 1; // задаем начальный режим работы светодиодов int push = 0; // задаем время нажатия на кнопку в мс int unpush = 0; // время простоя кнопки boolean setupON = 0; // задаем начальное состояние переменной активации режима настройки unsigned long push_p = 0; // переменная хранящая промежуточное значение времени нажатия unsigned long unpush_p = 0; ////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////// void setup() { Serial.begin(9600); // включаем сериал порт на скорости 9600 pinMode(KEY,INPUT); //определяем режимы работы пинов pinMode(LED_1,OUTPUT); //определяем режимы работы пинов pinMode(LED_2,OUTPUT); //определяем режимы работы пинов pinMode(LED_3,OUTPUT); //определяем режимы работы пинов } ////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////// void loop() { #ifdef DEBUG #endif DEBUG_PRINTLN(state); bouncer.update(); //обновить состояние кнопки boolean switchstate = bouncer.read(); //создаем переменную и считываем в нее состояние кнопки if (switchstate == 1 && state == 0){ // Если кнопка нажата и свет выключен state = 1; // включаем свет } timepush(switchstate); // считаем нажатие на кнопку и если оно больше 3 секунд - переключаем режим настройки света if (setupON = 1) { // если режим настройки света активирован SetMode(switchstate); // переходим в режим настройки time_unpush(switchstate); // считаем время простоя кнопки и если оно больше 5 сек. выходим из режима настройки } if (state == 1){ // если свет включен LED_ON(); // зажигаем светодиоды в соответствии с режимом } } ////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////// void timepush(boolean switchstate) { // счетчик нажатия кнопки if (switchstate == 1 && state ==1){ //если кнопка нажата и свет включен if ((millis() - push_p) >= 1000) { // если разница общего времени работы и промежуточным числом больше или равно 1 сек. push++; // счетчик времени нажатия увеличиваем на 1 (сек) push_p = millis(); // обновляем значение временного числа } } else { push_p = 0; push = 0; } if (push >= 4){ // если счетчик отсчитал 3 секунды setupON = 1; // активируем режим настройки } } ////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////// void time_unpush (boolean switchstate){ // счетчик не нажатой кнопки if (switchstate == 0 && state ==1){ //если кнопка не нажата и свет включен if ((millis() - unpush_p) >= 1000) { // если разница общего времени работы и промежуточным числом больше или равно 1 сек. unpush++; // счетчик времени простоя увеличиваем на 1 (сек) unpush_p = millis(); // обновляем значение временного числа } } else { unpush_p = 0; unpush = 0; } if (unpush >= 6){ // если счетчик отсчитал 5 секунд setupON = 0; // выходим из режима настройки } } ////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetMode(boolean switchstate) { // Выбор режима света if (switchstate == 1) { // если кнопка нажата if (mode <= 6){ // если выбираемый режим меньше или равен 6 mode++; // режим увеличиваем на 1 } else { // иначе mode = 1; // выбираем первый режим } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////// void LED_ON(){ // функция переключения режимов switch (mode){ // Выбираем режим case 1: // Если значение mode равно 1 digitalWrite (LED_1, HIGH); // Включаем светодиод 1 digitalWrite (LED_2, HIGH); // Включаем светодиод 2 digitalWrite (LED_3, HIGH); // Включаем светодиод 3 break; // Выходим из свитч case 2: // Если значение mode равно 2 digitalWrite (LED_1, HIGH); // Включаем светодиод 1 digitalWrite (LED_2, HIGH); // Выключаем светодиод 2 digitalWrite (LED_3, LOW); // Выключаем светодиод 3 break; // Выходим из свитч case 3: // Если значение mode равно 3 digitalWrite (LED_1, HIGH); // Включаем светодиод 1 digitalWrite (LED_2, LOW); // Выключаем светодиод 2 digitalWrite (LED_3, LOW); // Выключаем светодиод 3 break; // Выходим из свитч case 4: // Если значение mode равно 4 digitalWrite (LED_1, LOW); // Выключаем светодиод 1 digitalWrite (LED_2, HIGH); // Включаем светодиод 2 digitalWrite (LED_3, LOW); // Выключаем светодиод 3 break; // Выходим из свитч case 5: // Если значение mode равно 5 digitalWrite (LED_1, LOW); // Выключаем светодиод 1 digitalWrite (LED_2, LOW); // Выключаем светодиод 2 digitalWrite (LED_3, HIGH); // Включаем светодиод 3 break; // Выходим из свитч case 6: // Если значение mode равно 6 digitalWrite (LED_1, LOW); // Выключаем светодиод 1 digitalWrite (LED_2, HIGH); // Включаем светодиод 2 digitalWrite (LED_3, HIGH); // Включаем светодиод 3 break; // Выходим из свитч case 7: // Если значение mode равно 7 digitalWrite (LED_1, HIGH); // Включаем светодиод 1 digitalWrite (LED_2, LOW); // Выключаем светодиод 2 digitalWrite (LED_3, HIGH); // Включаем светодиод 3 break; } }