Arduino

Материал из CADR
Версия от 18:57, 11 апреля 2016; Avp (обсуждение | вклад) (Прерывания: Исправил ошибку в примере программы)
Перейти к: навигация, поиск

Прерывания

Допустим, мы сделали "бегущий огонь" и теперь хотим прикрутить кнопку для управления режимом светодиодов:

const int LED_MIN = 22;
const int LED_MAX = 30;
const int DELAY   = 100;

void setup() {
  for (int pin = LED_MIN; pin <= LED_MAX; ++pin)
    pinMode(pin, OUTPUT);
}

void blink(int pin) {
  digitalWrite(pin, HIGH);
  delay(DELAY);
  digitalWrite(pin, LOW);
  delay(DELAY);
}

void loop() {
  for (int pin = LED_MIN; pin <= LED_MAX; ++pin)
    blink(pin);
}

Самым прямолинейным решением, на первый взгляд, является считывание значение кнопки в начале loop. К примеру:

const int BUTTON  = 31;

// ... пропущена часть кода из предыдущей программы ...

boolean isEnabled = false;

void loop() {
  if (digitalRead(BUTTON))
    isEnabled = ! isEnabled;

  if (isEnabled) {
    for (int pin = LED_MIN; pin <= LED_MAX; pin++)
      blink(pin);
  }
}

Собираем схему, добавляем считывание значения с цифрового порта и логику переключения режимов. Всё бы хорошо, но наше кратковременное нажатие на кнопку обычно приводит к многократному считыванию значения: за время, пока нажата кнопка, loop успевает отработать несколько раз; как следствие, логика не работает, как должна.

Плюс, добавляя кнопку в наш проект, мы добавляем в наш проект неопределённость -- нажатие на кнопку может возникнуть в любой момент; в таких случаях говорят, что событие возникает асинхронно (по отношению к нашей программе.) Если нажатие на кнопку возникло в тот момент, когда Arduino "не смотрела" на значение на порту и занималась другим делами, то событие пройдёт незамеченным. Если же всё делать по-нормальному, то мы должны обрабатывать это событие в тот момент, как оно возникла.

Для правильного решения данной задачи необходимо использовать прерывания.

Реакция на внешние события

Для обработки внешнего асинхронного события нам потребуются как минимум две вещи:

  • Написать обработчик события
  • Связать обработчик с внешним событием

TODO

Прерывания по таймеру

TODO

См. также

Подключение оборудования