#13 Эксперимент-игра “Проверь свою реакцию”
В окружающих нас приборах и устройствах, элементы управления чаще всего представлены кнопками, потенциометрами и сенсорными панелями. Если же речь идёт об игровых приставках и автоматах, то одним из незаменимых элементов управления игровыми персонажами является джойстик.
Джойстики обычно имеют 2 степени свободы (т.е. их рукоятка может спокойно перемещаться вдоль 2-х координатных осей). Кроме этого, многие джойстики оборудованы ещё и кнопкой. Таким образом, джойстик становится удобным и многофункциональным устройством ввода. Устроен джойстик достаточно просто: он состоит из 2-х потенциометров, которые изменяют своё сопротивление в момент отклонения рукоятки джойстика от центрального положения. Один из них отвечает за горизонтальное отклонение рукоятки (ось X), другой – за её вертикальное отклонение (ось Y). Если мы будем снимать сигналы с этих потенциометров, то получим значения в диапазоне [0 … 1023]:
- Если мы отклоним рукоятку в крайнее левое положение, то X-потенциометр передаст значение [0];
- Если мы отклоним рукоятку в крайнее правое положение, то X-потенциометр передаст значение [1023];
- Если мы отклоним рукоятку в крайнее верхнее положение, то Y-потенциометр передаст значение [0];
- Если мы отклоним рукоятку в крайнее нижнее положение, то Y-потенциометр передаст значение [1023];
При этом, если джойстик оборудован кнопкой, то при нажатии на рукоятку, на соответствующем пине появится цифровой высокий (HIGH) или низкий (LOW) сигнал, в зависимости от того, какую схему подключения кнопки мы использовали.
На этом занятии мы подробно разберём тонкости работы с этим компонентом и даже соберём и запрограммируем свою собственную игру, играя в которую со своими друзьями, вы сможете посоревноваться в скорости реакции!
Перед выполнением эксперимента прочтите:
СБОРКА УСТРОЙСТВА НА МАКЕТНОЙ ПЛАТЕ
Нам понадобятся следующие компоненты:
- Arduino Uno;
- USB-кабель для подключения к компьютеру;
- Беспаечная макетная плата;
- 4 светодиода любого цвета;
- 1 пьезодинамик;
- 1 джойстик;
- 4 резистора, номиналом 220 Ом;
- 15 соединительных проводов разных цветов.
Соберите устройство по следующей схеме:
Схема устройства на макетной плате |
Принципиальная схема устройства |
Обратите внимание:
- джойстик имеет 5 пинов: (GND) – земля, (+5V) – питание, (VRx) – сигнальный пин потенциометра, регистрирующего отклонение рукоятки джойстика по оси X, (VRy) – потенциометр, регистрирующий отклонение по оси Y, (SW) – сигнальный пин кнопки джойстика;
- сигнальные пины потенциометров подключаем к входным аналоговым пинам A0 и A1;
- кнопку подключаем по схеме с подтягивающим резистором. Для этого необходимо замкнуть сигнальный пин на пин питания 5 В Arduino через резистор, сопротивлением 10 кОм. С этого-же пина будем снимать сигнал, принимая его на 2-м пине Arduino. Обратите внимание: когда кнопка не нажата, на сигнальном пине кнопки будет высокий (HIGH) сигнал, а при нажатии кнопки сигнал будет меняться на низкий (LOW);
- светодиоды подключаем по классической схеме к пинам 9, 10, 11, 12 Arduino, через токоограничивающие резисторы, номиналом 220 Ом;
- пьезодинамик подключён к 8-му пину Arduino.
При тестировании работы джойстика, держите его так, как показано на рисунках – чтобы пины джойстика оказались слева. Тогда при перемещении рукоятки вправо-влево, сигнал будет изменяться на выходе VRx, а если двигать рукоятку вверх-вниз, то на пине VRy.
ПРОГРАММИРОВАНИЕ
Для начала, давайте посмотрим какие значения мы будем получать с сигнальных пинов джойстика в ходе его работы. Для этого, мы создадим простой алгоритм, который будет посылать сигналы с 3-х пинов джойстика в последовательный порт компьютера.
Запустите Arduino и выберите [Инструменты] ⇒ [ArduBlock]. Наш тестовый алгоритм будет выглядеть следующим образом:
Загрузите программу в Arduino. После загрузки программы, откройте [Монитор последовательного порта]. Передвигая рычаг джойстика и нажимая на него, посмотрите: как будут изменяться значения сигналов пришедших с пинов джойстика:
Как видно из данных, полученных с пинов джойстика:
- когда джойстик находится в центральном положении, сигналы с пинов VRx и VRy принимают значения в диапазоне [507-511], сигнал с кнопки – значение [1];
- если джойстик сдвинуть в крайнее левое положение, то сигнал с пина VRx примет значение [0];
- если сдвинуть джойстик в крайнее правое положение, то сигнал с пина VRx примет значение [1021];
- если джойстик сдвинуть в крайнее верхнее положение, то сигнал с пина VRy примет значение [0];
- если сдвинуть джойстик в крайнее нижнее положение, то сигнал с пина VRy примет значение [1023];
- если нажать кнопку, то сигнал с кнопки джойстика изменится на [0].
Если вы будете плавно изменять положение рукоятки джойстика, то заметите, что сигналы с пинов VRx и VRy тоже изменяются плавно. При перемещении рукоятки от центрального до крайнего положения, сигнал будет изменяться от 511 до 1023 или от 511 до 0, т.е. будем плавно изменять свои значения примерно на 500 единиц. При нажатии кнопки, сигнал будет меняться с [1] на [0] и наоборот.
Давайте попробуем плавно зажечь светодиоды, расположенные справа и слева на макетной плате. При этом, светодиоды должны светить тем ярче, чем на большее расстояние сдвинута рукоятка относительно центрального положения. Алгоритм может выглядеть следующим образом:
Обратите внимание: мы использовали блок [constrain], чтобы ограничить диапазон значений, которые будут получать светодиоды, а для светодиода, подключённого к 9-му пину, мы поменяли местами начальные и конечные значения в блоке [map], так как при уменьшении значения сигнала с потенциометра джойстика, значения, посылаемые на светодиод должны увеличиваться.
Давайте протестируем возможности кнопки и заставим пьезодинамик издавать сигнал, пока кнопка нажата. Для этого используем блок [если/иначе]:
Загрузите программу в Arduino и проверьте её работу. Как видите, всё достаточно просто.
Теперь пришло время заняться нашей главной задачей. Давайте создадим алгоритм проверки скорости человеческой реакции. Для этого заставим светодиоды зажигаться в случайном порядке. Задачей испытуемого будет переместить рукоятку джойстика в сторону загоревшегося светодиода. При этом, алгоритм должен посчитать – какое время понадобилось человеку, чтобы сделать это. Полученный результат и будет временем реакции человека. Для того, чтобы получить более точные данные – будем давать каждому испытуемому 10 попыток для проверки его реакции. Это достаточно сложная задача, поэтому будем реализовывать алгоритм постепенно.
Начнём с основной части алгоритма:
Давайте разберёмся – что происходит при выполнении алгоритма:
- во-первых, мы объявили переменную [counter] – счётчик, который необходим для подсчёта количества попыток в нашей игре. У нас 10 попыток на одного испытуемого. Счётчик будет изменять свои значения в диапазоне [0 … 10]. В самом начале, мы должны присвоить счётчику любое значение не входящее в этот диапазон, чтобы игра не началась автоматически. Присвоим ему значение [11];
- далее, зажжём все светодиоды, это будет сигналом, что устройство готово к запуску;
- запуск игры должен происходить при нажатии на кнопку, т.е. мы должны проверить наличие низкого сигнала на кнопке и в случае его обнаружения выполнить алгоритм запуска;
- при запуске игры, мы гасим все светодиоды и с помощью блока [повтор] воспроизводим 3 раза короткий звук на частоте 440 Гц с задержкой в 0,5 секунды – это сигнал испытуемому, что игра вот-вот начнётся;
- после третьего сигнала, мы задаём переменную [Random], которая случайным образом генерирует число от 1 до 4. Для этого мы используем блок [случайный], который находится в разделе [Математические операторы]. В качестве параметров блока задаём значения в 1 и 5 – это границы диапазона, при этом нижняя граница включена в диапазон, а верхняя – нет, поэтому, мы должны задавать значение на единицу большее, нежели нам нужно (в нашем случае [5] вместо [4]);
- задаём переменную [start] и присваиваем ей значение [миллисекунды]. Блок [миллисекунды] можно найти в разделе [Управление]. Данный блок представляет собой переменную в которой хранится значение времени с момента запуска Arduino и его можно использовать как таймер. Задавая переменной [start] такое значение, мы задаём ей точку старта в миллисекундах, т.е. точку начала отсчёта для определения скорости реакции;
- далее, присваиваем переменной [counter] значение [0] для того, чтобы начать отсчёт наших десяти попыток;
- в последовательный порт выводим строку [————————————]. Она будет служить нам разделителем, чтобы не путаться в попытках разных испытуемых при просмотре результатов;
- далее идёт блок [выполнять пока] – основной блок нашего алгоритма, внутри него и будет происходить расчёт времени реакции. Блоки, которые находятся внутри это подпрограммы, которые мы опишем далее. Эти подпрограммы будут работать до тех пор, пока значение счётчика снова не станет равно [11] (вот почему в самом начале, мы присваивали счётчику это значение – чтобы основной блок не запустился раньше нажатия на кнопку);
- после выполнения основного блока, мы должны заново зажечь все светодиоды, что будет означать о готовности устройства протестировать следующего испытуемого на скорость реакции.
Теперь разберёмся с подпрограммами. У нас их 4. В каждой подпрограмме будет происходить проверка – какой из светодиодов зажёгся и в зависимости от этого, будет выполняться алгоритм, который будет считать миллисекунды до момента, пока испытуемый не передвинет рычажок джойстика в соответствующее положение. Далее, внутри подпрограммы будет производиться расчёт времени, которое понадобилось испытуемому для того, чтобы среагировать и переместить джойстик в нужное положение, а полученный результат будет выведен на экран. При этом, мы должны увеличивать значение счётчика [counter] на 1, чтобы перейти к следующей попытке. Алгоритм подпрограммы [left], для левого светодиода приведён ниже:
Опишем работу подпрограммы подробнее:
- если в переменной [Random] случайным образом “выпало” значение [1], то запускается алгоритм, который находится внутри подпрограммы [left];
- вначале, зажигается левый светодиод и программа “ожидает” момента, когда значение с пина VRx джойстика примет значение <50, т.е. джойстик переместиться в крайнее левое положение (значение взято с запасом, так как джойстик может не всегда выдавать “идеальный” нуль в момент достижения крайнего положения);
- как только нужный сигнал получен, в переменную [stop] записываются показания [миллисекунды] – время, прошедшее с начала работы программы до этого момента;
- светодиод гаснет и воспроизводится звук, длительностью в 200 мс, который оповещает о том, что испытуемый успешно “среагировал” и переместил джойстик в нужную позицию;
- переменная [Random] обновляется до нового случайного значения, а в последовательный порт выводится разность значений переменных [stop] и [start], т.е. время реакции испытуемого;
- далее обновляется значение переменной [start] и отсчёт времени начинается вновь;
- счётчик [Counter] увеличивает своё значение на единицу.
Подпрограммы [right], [up] и [down] представляют собой такие-же алгоритмы для правого, верхнего и нижнего светодиодов. Разница будет лишь в пинах светодиодов и ожидаемых значениях сигналов с пинов джойстика. Алгоритмы подпрограмм приведены ниже:
Загрузите программу в Arduino. После загрузки программы запустите [Монитор последовательного порта] – туда будут выводиться значения времени реакции. Протестируйте полученное устройство. Пример работы программы можете увидеть ниже (время реакции выводится в миллисекундах):
Теперь наша игра на проверку реакции готова! Можете посоревноваться со своими друзьями – у кого самая малое время реакции.
ЗАДАНИЯ ДЛЯ САМОСТОЯТЕЛЬНОГО ВЫПОЛНЕНИЯ
Задание 1*:
Измените алгоритм таким образом, чтобы по завершении тестирования одного пользователя, в последовательный порт выводился средний результат времени его реакции. Для того, чтобы найти среднее время реакции, нужно сложить значения времени всех 10-ти “раундов” и разделить полученное значения на 10. Результат работы такой программы представлен ниже:
Поздравляем, вы завершили курс и освоили “начальный уровень” программирования микроконтроллеров Arduino. Теперь вы можете переходить к разработке собственных проектов! Примеры проектов вы можете найти в конце данного курса.
Если вас увлекло занятие программирования Arduino и вы хотите дополнить и расширить свои познания в данной области, можете переходить к следующему “продвинутому уровню“. Там вы познакомитесь с ещё более интересными возможностями этого микроконтроллера и сможете реализовать более интересные и сложные проекты.
Для того, чтобы получить сертификат, подтверждающий успешное прохождение курса – выполняйте тесты в конце занятий. | Пройти проверочный тест |