Как я могу обнаружить нажатие трех переключателей с помощью процедуры обслуживания прерывания, подключенной только к одному выводу прерывания

Недавно я попытался использовать свою плату Arduino Uno (AtMega328) для обнаружения нажатия серии из трех переключателей с помощью процедуры обслуживания прерывания.

Если есть три переключателя для R, G и B. Всякий раз, когда хотя бы один из этих переключателей нажимается один раз, RGB-светодиод должен переключать свое состояние на красный, зеленый или синий.

Теперь это не проблема для двух переключателей R и G, так как плата Arduino Uno имеет два прерывания подходящие контакты (2 и 3).

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

Существует ли возможная схема, которая позволяет легко обнаруживать нажатие хотя бы одного из трех переключателей, чтобы я мог просто использовать один вывод с возможностью прерывания для обнаружения нажатия любого переключателя?

Код для двух светодиодов с использованием Arduino IDE был очень простым для всего двух переключателей:

const int buttonRed = 2;     // the number of the pushbutton pin
const int ledRed =  13;      // the number of the LED pin

const int buttonGreen= 3;
const int ledGreen=12;

// variables will change due to ISR
volatile int redState = 0;         
volatile int greenState=0;

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledRed, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonRed, INPUT);

  pinMode(ledGreen, OUTPUT);
  pinMode(buttonGreen, INPUT);

  // Attach an interrupt to the ISR vector
  attachInterrupt(digitalPinToInterrupt(buttonRed), redButton_ISR, CHANGE); 
  attachInterrupt(digitalPinToInterrupt(buttonGreen), greenButton_ISR, CHANGE); 
}

void loop() {
  // Nothing to do here
}

void greenButton_ISR() {
  greenState=digitalRead(buttonGreen);
  digitalWrite(ledGreen, greenState);
}

void redButton_ISR() {
  redState = digitalRead(buttonRed);
  digitalWrite(ledRed, redState);
} 

person Aleph0    schedule 13.11.2019    source источник
comment
ATmega328 способна обрабатывать прерывания смены контакта на любом выводе ввода-вывода. См. главу 13. Внешние прерывания в таблице данных   -  person AterLux    schedule 14.11.2019


Ответы (1)


Как указано в комментариях, вы можете использовать прерывания смены контакта.

См. https://thewanderingengineer.com/2014/08/11/arduino-pin-change-interrupts/ или

https://arduino.stackexchange.com/questions/1784/how-many-interrupt-pins-can-an-uno-handle

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

Либо вы подключаете все три кнопки с тремя разными резисторами к аналоговому входу. Измеренное напряжение говорит вам, какая из кнопок нажата.

Если ваш код ничего не делает, кроме этого, на самом деле нет необходимости в прерываниях, поэтому вы можете просто часто опрашивать состояния кнопок в цикле.

person Piglet    schedule 14.11.2019