Привет! Наверное, вы помните, как в уроках про мультинажание на кнопку нам нужно было решить проблему подсчета количества нажатий в одной серии. Тогда мы использовали функцию delay() и задерживали выполнение программы. Но что, если делать такую паузу нельзя, а необходимо получать данные с датчиков постоянно. Но при этом управлять программой с помощью кнопок или других датчиков. Для этого в Ардуино существуют прерывания.
Содержание
В одном из последних обзоров датчиков, мы рассматривали датчик препятствий KY-033. Посмотрите тот обзор если вы пропустили или уже забыли, потому что в этом уроке мы будем его использовать.
Итак, прерывания. Они позволяют выполнять программу асинхронно. При наступлении определенного события — нажатия на кнопку, сигнала от датчика, они дают возможность остановить ход текущей программы, выполнить код прерывания, а затем вернуться к прерванной задаче.
Для того, чтобы выполнить этот урок нам понадобиться.
- Ардуино UNO
- Макетная плата
- Перемычки
- Датчик KY-033
- 3 светодиода разного цвета
- 3 резистора 220 Ом
- Кабель USB
Прерывания
Аппаратные прерывания — это альтернатива постоянного сканирования состояния контактов в цикле loop(). Они не лучше и не хуже, вы всегда можете выбрать тот способ, который будет лучше работать в вашем проекте.
С аппаратной точки зрения, опрос контактов в цикле и прерывание абсолютно одинаковы. Однако, существуют моменты, когда использовать прерывания будет невозможно.
Например, устранение дребезга. Внутри прерывания не может быть использована функция delay(), а это значит, что программы подтверждающие состояние датчика должны быть спроектированы по-другому.
Программа
Проблему дребезга кнопки можно решить аппаратно. Мы сделаем это в другом уроке, а пока займемся работой с прерываниями.
В этом проекте мы хотим использовать бесконечный цикл в главном цикле loop() и использовать прерывание для запуска дополнительной подпрограммы, которая вмешается в работу цикла.
Кроме того, используем датчик препятствий из последнего обзора, он будет выполнять функцию бесконтактной кнопки.
Соберем на макетной плате схему. Используем уже знакомую схему подключения датчика препятствий, но добавим в нее три светодиода.
В цикле loop() будем бесконечно изменять яркость одного светодиода с помощью шим. А при срабатывании прерывания от датчика будем заменять один светодиод на другой, при этом яркость изменяться не будет.
volatile
В первую очередь нам нужно будет объявить переменную, которая отвечает за контакт активного светодиода. Она будет изменяться в процессе программы, а значит ее следует объявить как volatile.
volatile int selectedLED = 9;
attachInterrupt
Далее создадим 0 прерывание. 0 прерывание связано с пином 2 на плате Ардуино Uno, поэтому датчик препятствий подключен именно ко 2 контакту.
void setup(){
attachInterrupt(0, swap, RISING);
}
Теперь напишем функцию swap(), чтобы вызвать ее по прерыванию. Она будет переключать активный светодиод.
void swap(){
analogWrite(selectedLED, 0);
if (selectedLED == GREEN)
selectedLED = RED;
else if (selectedLED == RED)
selectedLED = YELLOW;
else if (selectedLED == YELLOW)
selectedLED = GREEN;
}
И в конце осталось только написать бесконечный цикл в основном цикле программы. Он будет изменять яркость светодиодов.
void loop(){
for (int i = 0; i<256; i++){
analogWrite(selectedLED, i);
delay(10);
}
for (int i = 255; i>= 0; i--){
analogWrite(selectedLED, i);
delay(10);
}
}
Полный текст программы
const int RED=9;
const int YELLOW=10;
const int GREEN=11;
volatile int selectedLED = RED;
void setup(){
pinMode (RED, OUTPUT);
pinMode (GREEN, OUTPUT);
pinMode (YELLOW, OUTPUT);
attachInterrupt(0, swap, RISING);
}
void swap(){
analogWrite(selectedLED, 0);
if (selectedLED == GREEN)
selectedLED = RED;
else if (selectedLED == RED)
selectedLED = YELLOW;
else if (selectedLED == YELLOW)
selectedLED = GREEN;
}
void loop(){
for (int i = 0; i<256; i++){
analogWrite(selectedLED, i);
delay(10);
}
for (int i = 255; i>= 0; i--){
analogWrite(selectedLED, i);
delay(10);
}
}
Заключение
Мы рассмотрели прерывания в Ардуино. Это одна из сложных тем в изучении Ардуино, но она поможет нам создавать сложные устройства с несколькими датчиками и большие программы отвечающие за несколько устройств сразу.