Приостановка выполнения программы с помощью кнопки
У меня есть программа, которая бесконечно мигает тремя светодиодами подряд. Как запрограммировать кнопку для приостановки программы в середине кода?
Кроме того, можно ли изменить код так, чтобы повторное нажатие кнопки приводило к ускорению мигания светодиода?
Каждый раз, когда я пытаюсь нажать кнопку, чтобы приостановить программу, она останавливается только после того, как программа возвращается к началу.
Вот мой код на данный момент (извините, он не очень чистый):
int ledpins[] = {4, 5, 6};
int buttonpin = 3;
int buttonstate = 0;
void setup() {
Serial.begin(9600);
for (int pin = 6; pin > 3; pin--) {
pinMode(ledpins[pin], OUTPUT);
}
pinMode(buttonpin, INPUT);
}
void loop() {
buttonstate = digitalRead(buttonpin);
if (buttonstate == HIGH) {
digitalWrite(ledpins, HIGH);
}
if (buttonstate == LOW) {
for (int pin = 4; pin < 7; pin++) {
digitalWrite(pin, HIGH);
delay(200);
digitalWrite(pin, LOW);
}
for (int pin = 6; pin > 3; pin--) {
digitalWrite(pin, HIGH);
delay(200);
digitalWrite(pin, LOW);
}
}
}
@andrew chen, 👍0
Обсуждение3 ответа
Думаю, можно использовать прерывание для кнопки. В обработчике можно задать переменную состояния, например, buttonPressed.
В обработчике это может выглядеть так:
....
if(buttonPressed != true){
buttonPressed = true; //Это только в первый раз
}
else if(buttonPressed){
buttonPressed = false; //Удалить первый флаг
speedTime = xxx; //Это только для второго нажатия
}
....
В цикле это может выглядеть так (вы можете установить его в начале или в конце кода):
....
while(buttonPressed){
// Ничего не делать (приостановить программу)
}
....
Перед настройкой запишите это и замените 200 в цикле на speedTime:
....
int speedTime = 200;
....
Чтобы приостановить выполнение кода, вам нужно дождаться момента, когда вы достигнете точки while(buttonPressed). Например, вверху или внизу. Повторное нажатие до достижения этой точки изменит только время.
Если вы не хотите ждать какое-то время для паузы, то замените эту функцию delay(200) на что-то лучшее.
Поскольку вам всё равно приходится ждать начала цикла, чтобы проверить эту переменную, как именно это меняет ситуацию? Вы по-прежнему находитесь в той же ситуации: вам приходится ждать, чтобы отреагировать на нажатие кнопки, и к тому же у вас есть дополнительные накладные расходы на прерывание., @Delta_G
Я бы просто использовал прерывание от контакта, и при нажатии кнопки процедура прерывания устанавливает флаг (т.е. flag=1). Затем в вашем цикле просто добавьте оператор, который вызывает функцию, которая представляет собой цикл while, ожидающий, пока переменная flag снова не станет равной 0. Функция прерывания просто переключает переменную flag каждый раз при нажатии кнопки. Таким образом, при первом нажатии кнопки программа зацикливается, а при втором — выполнение программы возвращается к циклу loop().
Проблема в этом коде заключается в том, что циклы for блокируются с задержкой в 1,2 секунды, и только по её завершении код возвращается к проверке кнопки. Вместо этого следует использовать саму функцию цикла для управления циклом и метод синхронизации Blink Without Delay. Таким образом, выполнение функции цикла никогда не блокируется, и она может выполняться тысячи раз в секунду, не пропуская ни одного нажатия кнопок. Кроме того, таким образом вы сможете приостановить программу в любой момент, а не только каждые 1,2 секунды.
- Данные DHT11 из Arduino UNO в Firebase через ESP8266
- Объяснение кода MPU6050
- Как я могу прервать задержку() при нажатии кнопки?
- Проблема с открытием нескольких текстовых файлов одновременно/по порядку с использованием <SD.h>
- Запуск/Остановка/Сброс мелодии с помощью кнопок
- hx711 и датчик нагрузки показывают 0 для калибровки
- Как остановить серводвигатель в текущем положении при использовании последовательного порта? Я хочу, чтобы он оставался в одном положении при получении «0».
- Как установить управляющий регистр в модуле RTC DS3231 для Arduino UNO R3?
Взгляните на фильм «Моргай без промедления»., @tttapa
пожалуйста, переформатируйте свой код так, чтобы он имел правильный отступ и правильное расположение пробелов, @jsotola
1) В
setup()вы обращаетесь кledpins[6], что выходит за пределы диапазона. 2) Вloop()digitalWrite(ledpins, HIGH)не имеет смысла, так какledpinsне является целым числом., @Edgar Bonet