Найти тему
informatics_for_everyone

Аппаратные прерывания в Arduino

В Arduino имеется 4 вида аппаратных прерываний. Отличаются они сигналом на контакте прерывания.

  • Контакт прерывания притянут к земле. Ардуино будет выполнять обработчик прерывания пока на пине прерывания будет сигнал LOW.
  • Изменение сигнала на контакте прерывания. Ардуино будет выполнять обработчик прерывания каждый раз когда на пине прерывания будет изменяться сигнал.
  • Изменение сигнала на контакте прерывания от LOW к HIGH. Обработчик прерывания исполняется только при изменении низкого сигнала на высокий.
  • Изменение сигнала на контакте прерывания от HIGH к LOW. Обработчик прерывания исполняется только при изменении высокого сигнала на низкий.

В Arduino Uno есть два пина, поддерживающие прерывания. Это цифровые пины 2 (int 0) и 3 (int 1). Один из них мы и будем использовать в нашей схеме.

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

-2

/ Назначение прерывания
int buttonInt = 0;
// Переменные с пинами светодиодов
int yellowLed = 11;
int redLed = 10;
int greenLed = 9;
int nullLed = 6;
volatile int selectedLed = greenLed;
// Инфракрасный дальномер
int distPin = 0;
void setup() { // Устанавливаем режимы пинов
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(nullLed, OUTPUT);

// Устанавливаем прерывание
attachInterrupt(buttonInt, swap, RISING);
}

// Обработчик прерывания
void swap() { if(selectedLed == greenLed)
selectedLed = redLed;
else if(selectedLed == redLed)
selectedLed = yellowLed;
else if(selectedLed == yellowLed)
selectedLed = nullLed;
else selectedLed = greenLed;
}
void loop() { // Получаем данные с дальномера
int dist = analogRead(distPin);
int brightness = map(dist, 0, 1023, 0, 255);

// Управляем яркостью
analogWrite(selectedLed, brightness);
}

Необходимо использовать ключевое слово «volatile» перед объявлением переменной значение которой будет изменяться в обработчике прерывания. Так же я добавил переменную «nullLed» для того что бы программа на определенном шаге не меняла цвет ни одного из подключенных светодиодов. Строка «attachInterrupt(buttonInt, swap, RISING);» назначает обработчиком прерывания функцию swap. Подробнее об этой функции вы можете почитать здесь.