Альтернатива задержке, чтобы ее можно было прервать

interrupt keypad

У меня есть задача, которая включает в себя 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' 
}

, 👍1

Обсуждение

Три слова: "Конечный автомат". У вас нет *никаких* задержек. Вместо этого используйте " millis ()", чтобы решить, когда выполнять различные действия., @Majenko

@Majenko Как мне использовать millis (), чтобы создать задержку в 30 секунд, не делая этого в intevals? Я хочу, чтобы задержка началась после нажатия клавиши на клавиатуре. Могу ли я установить значение 0, когда я нажимаю клавишу, а затем делаю интервал в 30 секунд?, @Izabela

Запишите время нажатия кнопки. Затем посмотрите на разницу между текущим временем и тем временем, чтобы узнать, сколько прошло времени. Как если бы вы варили яйцо. Вы не сидите, уставившись на часы, вы смотрите на них один раз, а затем регулярно смотрите на них, занимаясь другими делами, пока не пройдет 5 минут., @Majenko


1 ответ


1

Сделайте конечный автомат.

Возьмите лист бумаги и нарисуйте порядок работы, и каждый раз, когда вы ждете, вы указываете, что будет делать каждая кнопка.

Так, например, каждый раз, когда нажимается кнопка 1, вы увеличиваете счетчик и меняете дисплей.

Ожидая тайм - аута, вы проверяете if(startTimestamp- millis() > timeout)> для следующего шага.

Затем дайте каждому ожидающему состоянию номер и поставьте большой переключатель на глобальный в начале цикла() и обновляйте глобальный каждый раз, когда состояние должно измениться.

,