Arduino — различия между версиями

Материал из CADR
Перейти к: навигация, поиск
(Подключение оборудования: Поправил ссылку)
(Прерывания: Дополнил)
Строка 1: Строка 1:
 
= Прерывания =
 
= Прерывания =
Допустим, мы сделали "бегущий огонь" и теперь хотим прикрутить кнопку для управления режимом светодиодов.  Самым прямолинейным решением, на первый взгляд, является считвание значение кнопки в начале <code>loop</code>.  Собираем схему, добавляем считывание значения с цифрового порта и логику переключения режимов.  Всё бы хорошо, но наше кратковременное нажатие на кнопку обычно приводит к многократному считыванию значения; как следствие, логика не работает, как должна.
+
Допустим, мы сделали "бегущий огонь" и теперь хотим прикрутить кнопку для управления режимом светодиодов:
  
Плюс, добавляя кнопку в наш проект, мы добавляем в наш проект неопределённость -- нажатие на кнопку может возникнуть в любой момент, и (если всё делать по-нормальному) мы должны обрабатывать это событие в тот момент, как оно возникла.  В таких случаях говорят, что событие возникает асинхронно (по отношению к нашей программе.)
+
<pre>
 +
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);
 +
}
 +
</pre>
 +
 
 +
Самым прямолинейным решением, на первый взгляд, является считывание значение кнопки в начале <code>loop</code>.  К примеру:
 +
 
 +
<pre>
 +
const int BUTTON  = 31;
 +
 
 +
// ... пропущена часть кода из предыдущей программы ...
 +
 
 +
boolean isEnabled = false;
 +
 
 +
void loop() {
 +
  if (digitalRead(BUTTON)) {
 +
    isEnabled = ! isEnabled;
 +
  }
 +
 
 +
  if (isEnabled) {
 +
    isEnabled = true;
 +
    for (int pin = LED_MIN; pin <= LED_MAX; pin++)
 +
      blink(pin);
 +
  }
 +
}
 +
</pre>
 +
 
 +
Собираем схему, добавляем считывание значения с цифрового порта и логику переключения режимов.  Всё бы хорошо, но наше кратковременное нажатие на кнопку обычно приводит к многократному считыванию значения: за время, пока нажата кнопка, <code>loop</code> успевает отработать несколько раз; как следствие, логика не работает, как должна.
 +
 
 +
Плюс, добавляя кнопку в наш проект, мы добавляем в наш проект неопределённость -- нажатие на кнопку может возникнуть в любой момент; в таких случаях говорят, что событие возникает асинхронно (по отношению к нашей программе.)  Если нажатие на кнопку возникло в тот момент, когда Arduino "не смотрела" на значение на порту и занималась другим делами, то событие пройдёт незамеченным.  Если же всё делать по-нормальному, то мы должны обрабатывать это событие в тот момент, как оно возникла.   
  
 
Для правильного решения данной задачи необходимо использовать прерывания.
 
Для правильного решения данной задачи необходимо использовать прерывания.
  
 
== Реакция на внешние события ==
 
== Реакция на внешние события ==
Для обработки внешнего асинхнонного события нам потребуются как минимум две вещи:
+
Для обработки внешнего асинхронного события нам потребуются как минимум две вещи:
 
* Написать обработчик события
 
* Написать обработчик события
 
* Связать обработчик с внешним событием
 
* Связать обработчик с внешним событием

Версия 18:56, 11 апреля 2016

Прерывания

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

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) {
    isEnabled = true;
    for (int pin = LED_MIN; pin <= LED_MAX; pin++)
      blink(pin);
  }
}

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

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

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

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

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

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

TODO

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

TODO

См. также

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