Как отключить несколько внешних кнопок прерывания?

У меня есть Arduino, спящий большую часть времени, чтобы сэкономить энергию, и есть две кнопки, прикрепленные к разным контактам прерывания, которые выполняют разные функции. Эти функции отличаются друг от друга, но обе должны запускать длинный блокирующий код. Я не хочу, чтобы кнопка подпрыгивала (или даже намеренно нажималась несколько раз во время кода блокировки), чтобы поставить в очередь несколько запусков функции прерывания. Я также не хочу, чтобы период сна был коротким, потому что я стараюсь держать if выключенным как можно больше, чтобы сэкономить энергию. Я не хочу ждать 8 секунд после нажатия кнопки, прежде чем произойдет действие кнопки. Таким образом, я бы подумал, что флаги или опрос контактов из основного цикла-это не способ справиться с этим из-за неэффективности питания и длительной задержки между нажатием кнопки и действием. Должен ли я отсоединить каждый ISR от своего собственного вывода прерывания до тех пор, пока его действие не будет завершено, а затем снова присоединить?

const int buttonA = 6;     
const int buttonB =  10;      

void setup() {
  pinMode(buttonA, INPUT_PULLUP);
  pinMode(buttonA, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonA), actionA, FALLING);
  attachInterrupt(digitalPinToInterrupt(buttonB), actionB, FALLING);
}

void loop() {
  sleep_function();  //занимает 8 секунд
}

void actionA(){
  //какой-то блокирующий код, который занимает 2 секунды, но который я хочу запустить сразу после нажатия кнопки
}

void actionB(){
  //какой-то блокирующий код, который занимает 10 секунд, но который я хочу запустить сразу после нажатия кнопки
}

, 👍-1

Обсуждение

код блокировки-это все равно, что иметь одного водителя с одним транспортным средством и без мобильного телефона забирать посылки, @jsotola

При использовании прерывания я лично предпочитаю использовать аппаратную деблокировку с RC - схемой и триггером Шмитта. См. Раздел "RC Debouncer" книги Джека Ганссла [Руководство по дебоунсу](http://www.ganssle.com/debouncing-pt2.htm)., @hcheung

не выполняйте действие при нажатии кнопки ... вставьте слой разделения между нажатием кнопки и желаемым действием ... нажатие кнопки должно установить флаг, не более того ... желаемое действие должно происходить только тогда, когда установлен флаг ... таким образом, несколько нажатий кнопок игнорируются, если флаг уже установлен, @jsotola


1 ответ


Лучший ответ:

3

Просто установите флаг в прерывании и запустите свой код в цикле

const int buttonA = 6;     
const int buttonB =  10;
volatile byte flagA = 0;
volatile byte flagB = 0;      

void setup() {
  pinMode(buttonA, INPUT_PULLUP);
  pinMode(buttonA, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonA), actionA, FALLING);
  attachInterrupt(digitalPinToInterrupt(buttonB), actionB, FALLING);
}

void loop() {
  if(flagA){
    //какой-то блокирующий код, который занимает 2 секунды, но который я хочу запустить сразу после нажатия кнопки
    flagA = 0;
  }
  if(flagB){
    //какой-то блокирующий код, который занимает 10 секунд, но который я хочу запустить сразу после нажатия кнопки
    flagB = 0;
  }
  sleep_function();  //занимает 8 секунд
}

void actionA(){
   flagA = 1;
}

void actionB(){
   flagB = 1;
}
,

будет ли прерывание всегда заканчивать сон или оно просто возобновит его?, @rfii

Прерывание прерывает сон, и если вы хотите спать, вы должны снова погрузить его в сон. https://www.gammon.com.au/power, @Dave X