Содержание

Эксперимент 20. Перетягивание каната

← Светильник, управляемый по USB | Оглавление | Конец первой серии экспериментов!

В этом эксперименте мы создаем еще одну игру, на этот раз нужно быстрее соперника нажать кнопку 20 раз.

В старой версии блокнота хакера по ошибке были указаны резисторы на 100 кОм, которых нет в наборе. На самом деле в уроке смело можно и нужно использовать резисторы на 10 кОм из комплекта.

Список деталей для эксперимента

Для дополнительного задания

Принципиальная схема

Схема на макетке

Обратите внимание

Скетч

p200_button_wrestling.ino
#define BUZZER_PIN     0
#define FIRST_BAR_PIN  4
#define BAR_COUNT      10
#define MAX_SCORE      20
// глобальные переменные, используемые в прерываниях (см. далее)
// должны быть отмечены как нестабильные (англ. volatile)
volatile int score = 0;
 
void setup()
{
  for (int i = 0; i < BAR_COUNT; ++i)
    pinMode(i + FIRST_BAR_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  // Прерывание (англ. interrupt) приостанавливает основную
  // программу, выполняет заданную функцию, а затем возобновляет
  // основную программу. Нам нужно прерывание на нажатие кнопки,
  // т.е. при смене сигнала с высокого на низкий, т.е. на
  // нисходящем (англ. falling) фронте
  attachInterrupt(INT1, pushP1, FALLING); // INT1 — это 3-й пин
  attachInterrupt(INT0, pushP2, FALLING); // INT0 — это 2-й пин
}
 
void pushP1() { ++score; } // функция-прерывание 1-го игрока
void pushP2() { --score; } // функция-прерывание 2-го игрока
void loop()
{
  tone(BUZZER_PIN, 2000, 1000); // даём сигнал к старту.
  // пока никто из игроков не выиграл, обновляем «канат»
  while (abs(score) < MAX_SCORE) {
    int bound = map(score, -MAX_SCORE, MAX_SCORE, 0, BAR_COUNT);
    int left = min(bound, BAR_COUNT / 2 - 1);
    int right = max(bound, BAR_COUNT / 2);
    for (int i = 0; i < BAR_COUNT; ++i)
      digitalWrite(i + FIRST_BAR_PIN, i >= left && i <= right);
  }
  tone(BUZZER_PIN, 4000, 1000); // даём сигнал победы
  while (true) {} // «подвешиваем» плату до перезагрузки
}

Пояснения к коду

Вопросы для проверки себя

  1. Каким образом мы подавляем дребезг аппаратно?
  2. Для чего используются прерывания?
  3. Каким образом можно включить обработку внешних прерываний?
  4. О каких нюансах работы с уже известными нам вещами следует помнить при работе с прерываниями?
  5. Как выбрать максимальное из двух значений? Минимальное?
  6. Как получить абсолютное значение переменной? Чего следует избегать при использовании этой функции?
  7. Когда оператор логическое «или» возвращает «ложь»?

Задания для самостоятельного решения

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

← Светильник, управляемый по USB | Оглавление | Конец первой серии экспериментов!