Освой Arduino играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Если вы смотрели фильм "Трасса 60", то видели, как действует шар судьбы. Нужно задать вопрос, потрясти шар и получить ответ. Такой шар также можно купить в магазинах. Мы сделаем электронную версию.
На момент создания проекта у меня на макетной плате была схема от Игры на реакцию. Для начала я решил в качестве отладочного материала использовать готовую схему в упрощённом виде. Нам понадобится кнопка и светодиод. Резисторы и провода являются вспомогательными деталями.
Кнопка будет подключена к питанию через нагрузочный резистор (pull-up) номиналом 10 кОм. Резистор одним выводом подключается к порту 3, другим - к источнику питания.
Светодиод подключаем к порту 13 через резистор номиналом 330 Ом или близким к нему.
Общий алгоритм кода:
int reply;
int waitTime; // пауза разной величины перед включением светодиода
const int ledPin = 13;
const int buttonPin = 3; // кнопка
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
Serial.println("Шар судьбы");
}
void loop() {
Serial.println("Когда загорится светодиод, задай вопрос и нажми кнопку");
waitTime = random(2000, 4000); // пауза в виде случайной величины от 2000 до 4000 мс
delay(waitTime); // делаем паузу
digitalWrite(ledPin, HIGH); // включаем светодиод
while (digitalRead(buttonPin) == HIGH) { } // пустой цикл, выполняется пока не нажата кнопка
digitalWrite(ledPin, LOW); // выключаем светодиод
reply = random(8);
switch (reply) {
case 0:
Serial.println("Yes");
break;
case 1:
Serial.println("Probably");
break;
case 2:
Serial.println("Definitely");
break;
case 3:
Serial.println("Don't be silly");
break;
case 4:
Serial.println("Of course");
break;
case 5:
Serial.println("Ask again");
break;
case 6:
Serial.println("Doubtful");
break;
case 7:
Serial.println("No");
break;
}
delay(1000); // небольшая пауза перед новым ответом
}
После загрузки скетча следует открыть монитор порта. В нём выводится инструкция, подготавливающая игрока к началу испытаний. Затем включается светодиод. Задавайте вопрос и нажимайте кнопку. Результат записывается и выводится на экран. Затем всё повторяется снова. И так до бесконечности.
Цикл while блокирует исполнение кода, пока не будет нажата кнопка. Когда кнопка будет нажата, то условие цикла выполнится и скетч выполнит код, который идёт за циклом.
Убедившись, что задумка работает, можно переходить к следующему этапу - подключать дисплей (ЖК-экран) и любой подходящий датчик (датчик наклона, акселерометр и т.п.).
В сети полно примеров на эту тему. Некоторые даже покупают шар судьбы, распиливают его на две половинки, вытаскивают внутреннюю начинку из ёмкости с жидкостью и заменяют на электронный аналог.
Похожий скетч в чуть упрощённом варианте. Подключение экрана смотреть на странице Библиотека LiquidCrystal. Кнопка подключена к выводу 7 в режиме INPUT_PULLUP. Ответы немного поменял, не забывайте, что у экрана меньше места для текста.
// Подключаем стандартную библиотеку LiquidCrystal
#include <LiquidCrystal.h>
// Инициализируем объект-экран, передаём использованные
// для подключения контакты на Arduino в порядке:
// RS, E, D4, D5, D6, D7
LiquidCrystal lcd(4, 5, 10, 11, 12, 13);
const int switchPin = 7;
int switchState = 0;
int prevSwitchState = 0;
int reply;
void setup()
{
pinMode(switchPin, INPUT_PULLUP);
lcd.begin(16, 2);
lcd.print("Ask the ");
lcd.setCursor(0, 1);
lcd.print("Magic 8 Ball!");
}
void loop()
{
switchState = digitalRead(switchPin);
if (switchState != prevSwitchState) {
if (switchState == LOW) {
reply = random(8); //pick a number from 0 to 7
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("The ball says: ");
lcd.setCursor(0, 1 );
switch (reply) {
case 0: lcd.print("Yes");
break;
case 1: lcd.print("Most likely");
break;
case 2: lcd.print("Definitely");
break;
case 3: lcd.print("Outlook good");
break;
case 4: lcd.print("Try again");
break;
case 5: lcd.print("Ask again");
break;
case 6: lcd.print("Doubtful");
break;
case 7: lcd.print("My replay is no");
break;
} //end of switch
} //end of nested if()
} //end of outer if()
//update the tilt switch status
prevSwitchState = switchState;
}