Кнопка на три режима..
- Войдите на сайт для отправки комментариев
Ср, 11/11/2020 - 13:52
Пробую делать трех-режимный селектор на одной кнопке. При нажатии на кнопку происходит переключение на следующий режим и так по кругу ...1-2-3-1-2-3... Ниже код в котором переключение происходит в нужном порядке, но если перестаю нажимать на кнопку, то номер режима, к примеру первый - многократно печатается в сериал мониторе и ни как не могу придумать способ его остановить. Буду признателен за помощь.
const int btn = 2;
int selector = 0;
bool but_state;
void setup() {
Serial.begin(9600);
pinMode(btn, INPUT_PULLUP);
}
void loop() {
if (digitalRead(btn) == true && but_state == false )
{
but_state = true;
selector++;
if (selector > 3) {
selector = 0;
} else if (digitalRead(btn) == HIGH)
{
but_state = false;
}
switch (selector) {
case 0:
Serial.println("Case 0");
break;
case 1:
Serial.println("Case 1");
break;
case 2:
Serial.println("Case 2");
break;
}
}
}
У вас в коде какой-то бардак с логикой.
Можете обьяснить, зачем нужен else if() в строке 18 и вообще какова функция переменной but_state? Почему она обнуляется только если selector не равен нулю?
Вставил не ту версию кода. Та была до того как определился с окончательной версией.
Вот:
const int btn = 2; int selector = 0; bool but_state = 0; void setup() { Serial.begin(9600); pinMode(btn, INPUT_PULLUP); } void loop() { if (digitalRead(btn) == true && but_state == false ) { but_state = true; selector++; if (selector > 3) selector = 0; } else if (digitalRead(btn) == false) { but_state = false; } switch (selector) { case 0: Serial.println("Case 0"); break; case 1: Serial.println("Case 1"); break; case 2: Serial.println("Case 2"); break; } }Ну начнем с того, что у тебя не 3 режима а 4.
Условие для трёх должно быть :
if(selector>=3)
А можно без всяких if, просто:
selector++;
selector%=3;
Так в чем проблема-то?
Тс , ты определись, тебе "шашечки или ехать ? "
У тебя в теле switch стоит вывод в порт в каждом проходе.
Ты либо флагами все case обвешай(будет много мусора), либо отдельно выводи если значение изменилось.
static int _selector=selector; if(_selector!=selector){ _selector=selector; Serial.print("Case "); Serial.println(selector); }NVN Plus, зачем тут нужен but_state - так и осталось не понятным.
А чтобы значение selector не мусорило в Монитор - достаточно в коде из #2 перенести блок Switch() в 17 строку
NVN Plus, зачем тут нужен but_state - так и осталось не понятным.
А чтобы значение selector не мусорило в Монитор - достаточно в коде из #2 перенести блок Switch() в 17 строку
but_state - это я дребезг устранял, хвосты.. Switch() перенёс, не компилируется..(
Ну, я пока так не умею, учусь.. спасибо за примерчик.
Тс , ты определись, тебе "шашечки или ехать ? "
У тебя в теле switch стоит вывод в порт в каждом проходе.
Ты либо флагами все case обвешай(будет много мусора), либо отдельно выводи если значение изменилось.
static int _selector=selector; if(_selector!=selector){ _selector=selector; Serial.print("Case "); Serial.println(selector); }Это что, все запихать в case??? Разве так можно?
П.С. Мне лучше с комментариями, хочется все-таки понять как правильно..
Switch() перенёс, не компилируется..(
Весь блок switch со всеми case переносить нужно
const int btn = 2; int selector = 0; bool but_state = 0; void setup() { Serial.begin(9600); pinMode(btn, INPUT_PULLUP); } void loop() { if (digitalRead(btn) == true && but_state == false ) { but_state = true; selector++; if (selector > 3) selector = 0; switch (selector) { case 0: Serial.println("Case 0"); break; case 1: Serial.println("Case 1"); break; case 2: Serial.println("Case 2"); break; } } else if (digitalRead(btn) == false) { but_state = false; } }Это что, все запихать в case??? Разве так можно?
П.С. Мне лучше с комментариями, хочется все-таки понять как правильно..
Это не надо пихать в кейс.
Это нужно разместить после блока switch, убрав из всех case'ов вывод в порт.
Если нужно обязательно пихать в case, тогда примерно так:
Объявляем переменные
boolean serial_flag=1;
int _selector=selector;
В кейсах будет:
case 0:
if(serial.flag=1){Serial.println("Case 0");serial_flag=0;}
break;
За пределами switch:
if(_selector!=selector){
_selector=selector;
serial_flag=1;}
он ведь так и напишет. А нам опять разгребать
он ведь так и напишет. А нам опять разгребать
Ну пусть хоть малость подумает.
Очевидно же
он ведь так и напишет. А нам опять разгребать
Не, не напишу - кейсы лучше не загромождать - читал..)
В общем всем спасибо! Ваши подсказки помогли! Пока не все понял, но буду разбираться - пищи для размышлений предостаточно. Добавил антидребезг и все ваши поправки - код преобразился.) Доволен!
const int btn = 2; int selector = 0; bool but_state = false; unsigned long last_press; void setup() { Serial.begin(9600); pinMode(btn, INPUT_PULLUP); } void loop() { if ( (digitalRead(btn) == true && but_state == false ) && (millis() - last_press > 5) ) { but_state = true; last_press = millis(); selector++; selector %= 3; switch (selector) { case 0: Serial.print("Case "); Serial.println(selector); break; case 1: Serial.print("Case "); Serial.println(selector); break; case 2: Serial.print("Case "); Serial.println(selector); break; } static int _selector = selector; if (_selector != selector) { _selector = selector; } } else if ( (digitalRead(btn) == false && but_state == true ) && (millis() - last_press > 5) ) { but_state = false; last_press = millis(); } }А разве вместо case switch не проще
if (selector!=_selector) Serial.println("Case "+ selector); _selector = selector;А разве вместо case switch не проще
if (selector!=_selector) Serial.println("Case "+ selector); _selector = selector;Гыгыгы.