Есть ли лучший способ объединить оператор if с ISR?
В моем скетче при срабатывании прерывания переменная состояния переключается с высокого на низкий уровень и наоборот. В зависимости от состояния переменной у меня есть оператор if в основном цикле, который вызовет функцию alarm_On, если состояние высокое, а часть else условного оператора вызовет функцию alarm_Off, если прерывание сработает во второй раз. Таким образом, я хочу, чтобы это условие if запускалось только при срабатывании прерывания. Во всех других случаях я хочу запустить другой код, но если он касается тех же компонентов, например, светодиодов, другой код не выполняется. Если это не общий компонент, то он работает нормально. Как решить эту проблему с "общим компонентом"?
// Аналоговые устройства ввода
# define humiditySensor A5
// Тревожный вход
# define alarmButton 2 // Кнопка
// Устройства вывода
# define redLed 10
# define yellowLed 11
# define greenLed 12
# define waterPump 9 // светодиод на реле
# define spk 5
// Переменные
volatile byte alarm = LOW;
void setup() {
pinMode (alarmButton, INPUT);
pinMode (redLed, OUTPUT);
pinMode (yellowLed, OUTPUT);
pinMode (greenLed, OUTPUT);
pinMode (waterPump, OUTPUT);
attachInterrupt(digitalPinToInterrupt(alarmButton), ISR_Alarm, RISING);
Serial.begin(9600);
}
void loop() {
if (alarm == 1) {
alarm_On();
} else if (alarm == 0) {
alarm_Off();
}
int humVal = analogRead(humiditySensor);
Serial.println(humVal);
if (humVal >= 500) {
digitalWrite(redLed, HIGH);
} else {
digitalWrite(redLed, LOW);
}
} // пустой цикл
void ISR_Alarm () {
alarm = !alarm; // переключение функции будильника при нажатии более одного раза
}
void alarm_On() {
tone (spk, 100);
digitalWrite(waterPump, HIGH);
static byte ledState = LOW;
static unsigned long oldTime = 0;
if (millis() - oldTime >= 250) { // цикл для мигания светодиодов в аварийной ситуации
oldTime = millis();
if (ledState == LOW) {
digitalWrite(redLed, HIGH);
digitalWrite(yellowLed, HIGH);
digitalWrite(greenLed, HIGH);
ledState = HIGH;
} else {
digitalWrite(redLed, LOW);
digitalWrite(yellowLed, LOW);
digitalWrite(greenLed, LOW);
ledState = LOW;
}
}
} // конец сигнала тревоги в функции
void alarm_Off () {
noTone (spk);
digitalWrite(redLed, LOW);
digitalWrite(yellowLed, LOW);
digitalWrite(greenLed, LOW);
digitalWrite(waterPump, LOW);
} // конец функции отключения будильника
void high_Humidity() {
digitalWrite(waterPump, HIGH);
}
void low_Humidity() {
digitalWrite(waterPump, LOW);
}
@Zaffresky, 👍0
Обсуждение1 ответ
Лучший ответ:
Ваш код не заблокирован, но каждый цикл вызывается ON или OFF, поэтому ваши изменения в «общих» компонентах перезаписываются довольно быстро.
Не отслеживать состояние внутри IRQ. Вы можете сделать что-то вроде:
volatile byte alarm = 1;
byte alarm_state = 1;
void ISR_Alarm () {
alarm = 1;
}
void loop() {
if (alarm){
alarm = 0;
if (alarm_state) {
alarm_state = 0;
alarm_Off();
} else {
alarm_state = 1;
alarm_On();
}
}
// другой код
}
Я использовал «блокировку» в другом контексте, но код действительно не блокируется. Было легче понять с вашим примером кода. Спасибо, @Zaffresky
- Прерывание ардуино при смене контакта
- Как прервать функцию цикла и перезапустить ее?
- Изменчивая переменная не обновляется с таймера ISR
- ISR для очень быстрых процессов, обнаружен странный код. Влияет ли ISR на поведение таймера?
- Arduino использует задержку в I2C ReceiveEvent
- Умеренно точный осциллограф на Arduino Uno R3
- Прерывания в Critical Statements
- Почему сопротивление между выводом ввода-вывода и землей падает, когда Arduino не питается
первый оператор if-else неправильно сформулирован, @jsotola
насколько я могу судить, ваш код не блокируется .... вы сможете без проблем добавлять дополнительные функции в
loop()
, @jsotolaкод alarm_On() не нуждается в кодовом блоке
if (ledState)
...... используйтеledState = ((ledState == LOW) ? HIGH : LOW);
следует с помощьюdigitalWrite(redLed, ledState);
и т. д., @jsotolaОн блокирует код, если я хочу что-то сделать с компонентами/датчиками, упомянутыми в функциях arlam_on и alarm_Off. Единственный случай, когда это не мешает, - это когда код не включает эти компоненты., @Zaffresky
@jsotola вы также упоминаете, что первое выражение if-else сформулировано неправильно. Подскажите, пожалуйста, как правильно сформулировать?, @Zaffresky
операторы else не должны иметь с ними условия., @Delta_G
@Zaffresky, погуглите
c++ if-else
, @jsotolaЭто даже компилируется?
} еще (тревога == 0) {
, @Thomas Weller@ThomasWeller, нет, код не компилируется ... компилятор возвращает «ожидаемый»; перед ошибкой '{' token` .... OP небрежно представил нерабочий код, @jsotola
Извините, что плохо, но я убрал ошибки и повторно вставил код., @Zaffresky