Ура, Troyka Slot Shield позволяет подключить Troyka OLED к цифровым выводам (6 и 7, согласно распиновке), а, значит, наконец-то я смог реализовать вызов прерываний. Но, как оказалось, все не так просто, как пишут в документации на форуме Arduino. Спойлер: если в функции-обработчике прерываний вызвать любую другую функцию, задействующую системные прерывания (в том числе, кстати, и замер миллисекунд, millis(), как рекомендуется в документации Arduino) — то результат будет примерно вот таким:
А вот как на самом деле это должно было работать:
Под катом — подробное объяснение.
Итак, как это работает.
Сначала загружаем библиотеку дисплея, инициализуирем её и декларируем все пины:
#include <TroykaOLED.h>
// создаём объект для работы с дисплеем
// и передаём I²C адрес дисплея
TroykaOLED myOLED(0x3C);
//Зададим пины кнопок
const byte LEFT_BUTTON = 7;
const byte RIGHT_BUTTON = 6;
//Initializing the button states as 1 (HIGH)
volatile byte left_state = HIGH;
volatile byte right_state = HIGH;
Обратите внимание на декларацию volatile — именно она поясняет компилятору, что данный параметр будет изменяться во время обработки прерываний.
Далее, необходимо определить функции обработки прерываний. У нас их две, для левой и правой кнопки, и в обоих мы будем читать значение соответствующей переменной:
void rightButtonISR(){
right_state = digitalRead(RIGHT_BUTTON);
}
void leftButtonISR(){
left_state = digitalRead(LEFT_BUTTON);
}
Внутри setup() стартуем последовательный интерфейс вызовом функции Serial.begin() и добавляем код, подключающий определенные нами функции обработки прерываний к соответствующим пинам с помощью функции attachInterrupt():
void setup() {
Serial.begin(9600);
pinMode(RIGHT_BUTTON, INPUT);
attachInterrupt(RIGHT_BUTTON, rightButtonISR, FALLING);
pinMode(LEFT_BUTTON, INPUT);
attachInterrupt(LEFT_BUTTON, leftButtonISR, FALLING);
}
Параметр FALLING определяет срабатывание прерываний при снижении напряжения, снимаемого с кнопки. В зависимости от ваших задач вы можете использовать альтернативные значения этого параметра: LOW (прерывание вызывается при достижении низкого уровня напряжения), CHANGE (прерывание вызывается при любом изменении напряжения), RISING (прерывание вызывается при росте напряжения на входе, к которому присоединена функция прерывания). Внутри основной функции loop() мы уже будем работать с состояниями для левой и правой кнопки, переданными нам из обработчиков прерываний (где мы вызывали процедуру digitalRead()):
void loop() {
if (right_state != HIGH)
{
//тут должен быть ваш код, что-то делающий, когда нажата правая кнопка
right_state = HIGH;
//возвращаем состояние кнопки в исходное значение
}
if (left_state != HIGH)
{
//код, что-то делающий после нажатия левой кнопки
left_state = HIGH;
//возвращаем состояние кнопки в исходное значение
}
}
Ну вот и все! Удачных вам поделок.
Полный код скетча из видео доступен тут.
З.Ы. Как оказалось, разработчики Curie не стали утруждать себя написанием библиотеки HID.h для работы с устройствами ввода, поэтому следующий пост будет уже на другой платформе.