Альтернатива задержке, чтобы ее можно было прервать
У меня есть задача, которая включает в себя 30-секундную задержку в пустом цикле. Во время этой задержки я хочу иметь возможность нажать клавишу на клавиатуре и получить сообщение, отображаемое на последовательном мониторе в качестве аварийной остановки. Поскольку задержки блокируют код до тех пор, пока они не будут закончены, я думал, что смогу разбить их на более мелкие секции, чтобы все еще можно было нажать клавишу аварийной остановки между ними, но, конечно, это не сработает. Я прочитал, как использовать функцию milis (), но из того, что я могу собрать, кажется, что она не будет работать для моей системы, так как мне нужен пользовательский ввод для нее, поэтому время от запуска Arduino до нажатия кнопки аварийной остановки каждый раз разное. Есть ли способ, который не слишком сложен и позволил бы мне нажать кнопку в течение этих 30 секунд?
Задержка находится в if (клавиша == '2'), и последняя часть скетча-это аварийная остановка.
const int greenLED = 13; //Объявляет greenLED подключенным к D13
const int redLED = 12; //Объявляет redLED подключенным к D12
//
const int ButtonT1 = 11; //Объявить пин для ButtonT1 как D11
int ButtonT1State = 0; //Переменная для чтения состояния
const int ButtonT2 = 10; //Объявить пин для ButtonT2 как D10
int ButtonT2State = 0; //Переменная для чтения состояния ButtonT2
//
int count_value1 = 0; //Переменная для хранения значения счетчика для турникета 1
int count_value2 = 0; //Переменная для хранения значения счетчика для турникета 2
//
const byte ROWS = 4; //Four row matrix
const byte COLS = 4; //Four columns matrix
char keys [ROWS] [COLS] = { //Defines symbols on buttons of keypad
{'1','2','3','A'}, //Defines ROW 1
{'4','5','6','B'}, //Defines ROW 2
{'7','8','9','C'}, //Defines ROW 3
{'*','0','#','D'}}; //Defines ROW 4
byte rowPins[ROWS] = {9, 8, 7, 6}; //Pin numbres of row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //Pin numbers of column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
//
void setup() { //Begin void setup, code runs once
Serial.begin(9600); //Begin serial transmission
Wire.begin(); //Begin I2C wire communication protocol
lcd.begin(16,2); //Begin LCD with 16 columns and 2 rows
//
pinMode(greenLED, OUTPUT); //Set greenLED as an OUTPUT
pinMode(redLED, OUTPUT); //Set redLED as an OUTPUT
pinMode(ButtonT1, INPUT); //Set ButtonT1 as an INPUT
pinMode(ButtonT2, INPUT); //Set ButtonT2 as an INPUT
}
//
void loop() { //Begin void loop
char key = keypad.getKey(); //Get a character key from the keypad
//
//counter 1
ButtonT1State = digitalRead(ButtonT1); //Read the state of ButtonT1 -
if (ButtonT1State == HIGH){ //Begin IF ButtonT1State is HIGH
count_value1++; //IF buttonT1 pressed, increase count value
Serial.println(count_value1); //Print count_value1 on serial monitor
delay(200); //Delay for 200ms, 0.2s
digitalWrite(greenLED,HIGH); //Set greenLED to HIGH,ON
digitalWrite(redLED,LOW); //Set redLED to LOW, OFF
//
if (key == '1'){ //Wait until key '1' is pressed
} //End IF key == '1'
ButtonT2State = digitalRead(ButtonT2); //Read ButtonT2 state
if (ButtonT2State == HIGH){ //Check if ButtonT2State is == HIGH
count_value2++; //IF buttonT1 pressed, increase count value
Serial.println(count_value2); //Print count_value2 on serial monitor
delay(500); //Delay for 500ms, 0.5s
//
if(key == '2'){ //Wait untill key '2' is pressed - confirm ride is ready
Serial.println("Ride starting - 30s"); //Print message in brackets on serial monitor
//30s delay, broken into smaller delays
delay(10000);
Serial.println("20s left");
delay(10000);
Serial.println("10s left");
delay(10000);
Serial.println("Ride finished"); //Print message in brackets on serial monitor
delay(100); //Delay for 1000ms, 1s
} //End if key == '2'
//
if (key == '4'){ //Wait until key '4' is pressed - emergency stop
Serial.println("Emergency stop"); //Print message in brackets on serial monitor
digitalWrite(redLED,HIGH); //Set redLED to HIGH,ON
digitalWrite(greenLED,LOW); //Set greenLED to LOW,OFF
lcd.clear(); //Clear i2c LCD
lcd.setCursor(0,0); //Set cursor to column 0, row 0
lcd.print("Emergency stop"); //Print message in brackets on i2c LCD
count_value2 = 0; //Set count_value2 to 0
delay(1000); //Delay for 1000ms, 1s
} //End IF key == '4'
}
@Izabela, 👍1
Обсуждение1 ответ
Сделайте конечный автомат.
Возьмите лист бумаги и нарисуйте порядок работы, и каждый раз, когда вы ждете, вы указываете, что будет делать каждая кнопка.
Так, например, каждый раз, когда нажимается кнопка 1, вы увеличиваете счетчик и меняете дисплей.
Ожидая тайм - аута, вы проверяете if(startTimestamp- millis() > timeout)>
для следующего шага.
Затем дайте каждому ожидающему состоянию номер и поставьте большой переключатель на глобальный в начале цикла()
и обновляйте глобальный каждый раз, когда состояние должно измениться.
- Контакт клавиатуры как прерывание (проводка или программирование)
- Использование millis() и micros() внутри процедуры прерывания
- Подсчет импульсов с прерыванием
- Устранение дребезга кнопки с помощью прерывания
- Программа arduino выдаёт ошибку expected //primary-expression before ')' token error: //expected ';' before '}' token E
- Почему необходимо использовать ключевое слово volatile для глобальных переменных при обработке прерываний в ардуино?
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Использование поворотных энкодеров с прерываниями смены контактов
Три слова: "Конечный автомат". У вас нет *никаких* задержек. Вместо этого используйте " millis ()", чтобы решить, когда выполнять различные действия., @Majenko
@Majenko Как мне использовать millis (), чтобы создать задержку в 30 секунд, не делая этого в intevals? Я хочу, чтобы задержка началась после нажатия клавиши на клавиатуре. Могу ли я установить значение 0, когда я нажимаю клавишу, а затем делаю интервал в 30 секунд?, @Izabela
Запишите время нажатия кнопки. Затем посмотрите на разницу между текущим временем и тем временем, чтобы узнать, сколько прошло времени. Как если бы вы варили яйцо. Вы не сидите, уставившись на часы, вы смотрите на них один раз, а затем регулярно смотрите на них, занимаясь другими делами, пока не пройдет 5 минут., @Majenko