Друзья, добрый день!) История такая: пишу цикл проверки состояния кнопок. Условие: есть 2 тактовые кнопки, которые должны работать по ИДЕЕ в взаимоисключающем состоянии, другими словами если на кнопке 1 - HIGH, то на кнопке 2 обязательно - LOW, и если HIGH у кнопки, то должно выводиться в сериал определенное сообщение. Так вот, возможна такая ситуация (не спрашивайте, как, почему, зачем, откуда корни), что эти кнопки, будут не в взаимоисключающем состоянии, обе либо в HIGH либо в LOW, что является состоянием ошибки, и на это событие (когда обе в одинаковом состоянии), тоже нужно реагировать определенным сообщением. Я написал определенный код, который делает прерывание событий + обработка дребезга, сравнивает состояние друг с другом и все хорошо, если нажимаешь кнопки по очереди, но есть одно маленькое НО: в моем проекте состоянием ошибки, является ТО состояние, когда кнопки находятся в одинаковом состоянии некоторое время (скажем 1 секунду), а рабочий режим кнопок их поочередное нажатие, другими словами, когда я нажал кнопку 1 и РЕЗКО ее отпускаю и нажимаю кнопку 2, в момент переключения, когда я отпустил кнопку 1, программа сравнивает свое состояние со 2 кнопкой на, которой LOW, и думает, что это состояние ошибки (мой кривокод), вот, а это не состояние ошибки, а рабочий момет переключения, как мне это пофиксить, надеюсь у меня получилось объяснить, код прикладываю) Код (C++): //1 const int switchPin1 = 2; boolean switchPin1_memory = 0; boolean switchPin1_now_memory = 0; unsigned long switchPin1_lastPress; boolean error1 = true; //2 const int switchPin2 = 3; boolean switchPin2_memory = 0; boolean switchPin2_now_memory = 0; unsigned long switchPin2_lastPress; boolean error2 = false; void setup() { pinMode (switchPin1, INPUT); pinMode (switchPin2, INPUT); Serial.begin(9600); while(!Serial); } void loop() { //порт 1 switchPin1_now_memory = digitalRead(switchPin1); if (switchPin1_now_memory == 1 && switchPin1_memory == 0 && millis() - switchPin1_lastPress > 100) { switchPin1_memory = true; switchPin1_lastPress = millis(); if (switchPin2_memory == switchPin1_memory) { error1 = !error1; Serial.println("Ошибка1"); error1 = !error1; } if (error1 != error2) { error1 = !error1; Serial.println("Кнопка 1 нажата"); } } if (switchPin1_now_memory == 0 && switchPin1_memory == 1) { switchPin1_memory = false; if (switchPin2_memory == switchPin1_memory) { error1 = !error1; } if (error1 != error2) { Serial.println("Ошибка11"); } } // Второй порт switchPin2_now_memory = digitalRead(switchPin2); if (switchPin2_now_memory == 1 && switchPin2_memory == 0 && millis() - switchPin2_lastPress > 100){ switchPin2_memory = true; switchPin2_lastPress = millis(); if (switchPin2_memory == switchPin1_memory) { error2 = !error2; Serial.println("Ошибка2"); error2 = !error2; } if (error1 != error2) { error2 = !error2; Serial.println("кнопка 2 нажата"); } } if (switchPin2_now_memory == 0 && switchPin2_memory == 1){ switchPin2_memory = false; if (switchPin2_memory == switchPin1_memory) { error2 = !error2; } if (error1 != error2) { Serial.println("Ошибка2"); } } }
Для того, чтобы научиться правильно писать код - существует один из приёмов: вы в комментариях, строка за строкой - описываете то, как должен работать код. Потом - наполняете файл кодом, вставляя его между комментариями. В вашем случае, с алгоритмической точки зрения, должен быть флаг "состояние кнопок одинаковое и не менялось N времени". Скажем, это может быть переменная типа unsigned long, куда записывается время, получаемое с millis(). Далее, для каждой кнопки - у вас есть такое понятие, как событие: т.е. соответствие каким-то условиям, по наступлению которых можно понять - кликнута ли кнопка, нажата ли кнопка, нажата и удерживается - это всё как пример. По итогу получаем что: у вас всё равно есть регулярный опрос состояния пинов кнопок. В этом опросе вы делаете следующее: если состояние кнопок РАЗНОЕ - то сбрасываете флаг одинаковости состояния кнопок в millis(). Если оно одинаковое, то проверяете - как давно был сброс флага одинаковости состояния кнопок. Если дольше, чем N времени - это ошибка, о которой надо сигнализировать. Таким образом, мы алгоритмически разделили несколько частей кода, сделав их отдельными единицами, оперировать которыми в коде - гораздо легче, чем мешать весь код в большую простыню Надеюсь, помог.
Ну так я об этом и писал, собственно. Пока в комментариях расписываешь - по сути, составляешь алгоритм, пусть даже в первом грубом приближении.
Алгоритм должен выглядеть так https://yandex.ru/images/search?text=блоки алгоритма&stype=image&lr=2&source=wiz Мы же принципиальные схемы рисуем согласно ГОСТ, а не описываем SPICE текстом.
Да, спасибо) Я думал в эту сторону, просто не знаю, как грамотней завернуть мб в строчку Код (C++): switchPin2_memory == switchPin1_memory где я проверяю на "одинаковость" состояния, вставить еще одно временное условие? Вы имели это ввиду?
Смотрите, как это может примерно выглядеть в псевдокоде: Код (C++): state buttonState1 = button1.getState(); state buttonState2 = button2.getState(); if(buttonState1 != buttonState2) { // состояние кнопок - разное, нормальный режим работы stateCheckTimer = millis(); // сбросили таймер stateTimerOn = false; } else { // состояние кнопок - одинаковое, надо проверить, какое время оно удерживается if(!stateTimerOn) { stateTimerOn = true; stateCheckTimer = millis(); } else { if(millis() - stateCheckTimer > INTERVAL) { alert("АВАРИЯ!"); } } }