Как выйти из цикла while с помощью клавиатуры?
Кажется, я не могу выйти из цикла while с помощью кнопки на клавиатуре. Я пробовал решение из этой темы: https://forum.arduino.cc/index.php?topic= 79932.0
Вот мой код:
void alarm(){
char customKey = customKeypad.getKey();
while (customKey == NO_KEY){
customKey = customKeypad.getKey();
lcd.noDisplay();
delay(750);// изменить для более быстрой вспышки
lcd.display();
delay(750);// изменить для более быстрой вспышки
}
lcd_home_screen();
}
Я попробовал и ==, и != некоторое время (customKey == NO_KEY)
Дополнительная информация: Я вызываю эту функцию будильника из другой функции внутри моего цикла. Вот полный код:
void loop() {
// клавиатура
char customKey = customKeypad.getKey();
if (customKey == 'A'){
main_program(5);
}
}
int main_program(int duration){
timer(duration);
alarm();
}
2 ответа
Лучший ответ:
Поскольку вы используете delay()
в цикле while
, вы должны убедиться, что нажимаете клавишу именно в тот момент, когда она считывается.
Вы не должны использовать delay()
.
Вместо этого взгляните на пример BlinkWithoutDelay в среде IDE. А также рассмотрите возможность реализации Конечного автомата, чтобы знать, моргаете ли вы и в каком состоянии находитесь. мигает в настоящее время.
Чтобы уточнить ответ Маженко, вы можете создать несколько типов перечисления для состояний, например
enum EAlarmState
{
On,
Off
};
EAlarmState _alarmState = EAlarmState::Off;
enum EBlinkState
{
BlinkOn,
BlinkOff,
};
EBlinkState _blinkState = EBlinkState::BlinkOff;
unsigned int long _lastBlinkTime = 0;
Состояние _blinkState
и _lastBlinkTime
не будет проверяться, если _alarmState
выключено.
Теперь вы можете использовать что-то вроде этого для проверки состояний и клавиатуры (псевдокод):
void loop()
{
checkKeypad();
switch (_alarmState)
{
case EAlarmStateOn:
if (millis() - _lastBlinkTime) >= 750)
{
`Blink off code`
switch(_blinkState)
{
case EBlinkStateOn:
_lastBlinkTime = millis();
'Blink off code'
_blinkState = EBlinkState::Off;
break;
`same for case EBlinkStateOff'
break;
default: // Error
break;
}
}
А также создать проверку и изменение состояния самого будильника.
Похоже, кода много (и так и будет), поэтому разделите его на подфункции. Но самое главное то, что код достаточно легко читается (и, следовательно, поддерживается).
Я попытался скопировать/вставить ваш код, но, поскольку я не понимаю, что происходит, я не смог заставить его работать. Я вставил верхнюю часть вашего кода перед функцией Setup(), а нижнюю часть в цикле while внутри моей функции alarm(). Теперь я сталкиваюсь со следующей ошибкой msg "ожидаемый инициализатор до '_blinkState', @Vincent Labrecque
Я забыл точку с запятой после второго перечисления. компилятора под рукой нет, @Michel Keijzers
Вы также должны избавиться от оператора while. Не блокируйте свой код на долгое или неопределенное время., @Michel Keijzers
- Проблема при кодировании обнаружения клавиш клавиатуры 4x4 (без библиотеки)
- Клавиатура 4x3 не обеспечивает никакого вывода, а вывод, который она обеспечивает, неверен
- Печать string and integer LCD
- Почему мои часы реального времени показывают неверное время с моего ПК?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Отправьте несколько значений int из Python в Arduino, используя pySerial
- Глобальные переменные занимают много места в динамической памяти.
- (Код ультразвукового датчика: такого файла или каталога нет)
Ваше решение BlinkWithoutDelay имеет большой смысл и более доступно для моего уровня знаний, спасибо. Моя блокировка сейчас заключается в том, что я не могу использовать функции lcd.Display и noDisplay. В примере с BlinkWithoutDelay код проверяет низкий или высокий уровень выходного сигнала, но в моем случае я должен проверить, включен ли мой ЖК-дисплей на Display или noDisplay. Как я могу это проверить? Я опубликую новый код, если то, что я только что написал, непонятно., @Vincent Labrecque
Неважно, я заставил это работать с фиктивной булевой переменной. BlinkWithoutDelay — это то, что нужно. Спасибо!, @Vincent Labrecque