DIY-проект Arduino LCD: сборка с резисторами, кнопкой и дисплеем 16x2
Компоненты и материалы
| Резистор 10 кОм | × | 2 | Один для контраста LCD-экрана, другой для кнопки. Важно: используйте резистор в конфигурации pull-down, а не pull-up, как показано в руководстве. |
| Резистор 1 кОм | × | 1 | Для контраста LCD-экрана. |
| Тактовая кнопка SparkFun 12 мм | × | 1 | |
| Стандартный LCD Adafruit 16x2 (белый на синем) | × | 1 | |
| Arduino UNO | × | 1 | |
| Провода-перемычки (универсальные) | × | 1 |
О проекте
Предыстория
Я участвовал в более крупном проекте, но была задержка. Поэтому решил заняться своим старым набором Arduino. Раньше не использовал LCD-экран. Так что я припаял пины к экрану (научился паять в первый раз).
Изначально я скопировал код из онлайн-руководства и загрузил его. Он только выводил текст, движущийся вправо и влево. Тогда я впервые познакомился с библиотекой LiquidCrystal. Написал код, который заставлял цифру «0» прыгать по экрану — это было весело. Тогда я подумал сделать что-то более сложное — игру. Погуглил игры на LCD для Arduino и нашел всего 3 игры, 2 из которых заработали у меня. Код этих игр был слишком сложен для понимания, поэтому решил создать простую игру.
Настройка
Подключите пины LCD к Arduino проводами, как показано на схеме ниже.
Я использовал потенциометр 10 кОм для регулировки контраста и настроил его по своему усмотрению. Измерил сопротивление между пинами мультиметром и использовал соответствующие резисторы (1 кОм и 10 кОм последовательно) для пина VO LCD.
Установите тактовую кнопку на макетной плате и подключите входной провод к пину 8 Arduino. Загрузите код в Arduino и вы готовы к работе.
Примечание: Используйте резистор кнопки в режиме pull-down, как показано на схеме.
Игровой процесс
В этой игре вы — футболист с мячом у ног. На вас будут нападать защитники, и вы должны просто уворачиваться от них.
После заставки нажмите кнопку, когда будет предложено. Когда защитник приблизится достаточно близко, нажмите кнопку, чтобы прыгнуть. Следующий защитник приблизится с большей скоростью, и так продолжается для 10 защитников.
P.S.: Изначально я использовал «0» как игрока и «1» как препятствие. Поскольку шел Чемпионат мира по футболу 2018 года и я фанат Месси, решил сменить тему.
Спрайты игрока и защитника созданы с помощью онлайн-генератора: https://omerk.github.io/lcdchargen/
Код
lcd_1.ino
/* Dodge the defs!! (Уворачивайся от защитников!!)
Created by: Shreyas R P
Created on: 21-06-2018
E-mail ID: shreyasrp888@gmail.com
Простая игра для 16x2 LCD с кнопкой.
Если вы вносите улучшения или изменения в игру, добавьте свои кредиты ниже:
Enjoy :)
Copyright (C) 2018 Shreyas R P
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
--------------------------------------------------------------------------------------------- */
#include <LiquidCrystal.h>
const int btn = 8; // пин входа кнопки
// тексты для отображения
char* introText[]={"Dodge the defs!!","Created on:", "Hit the button..."};
// объявления переменных
int game=0;
int buttonPress = 0;
int buttonState=0;
int obstaclePos;
int obsDelay;
int score=0;
unsigned long lastDebounceTime = 0; // последнее время переключения выходного пина
unsigned long debounceDelay = 50;
int lastButtonState=LOW;
// ГРАФИКА (пользовательские символы)
byte runnin1[8] = {
0b01100,
0b01100,
0b00000,
0b11100,
0b01110,
0b01100,
0b11110,
0b00011
};
byte runnin2[8]={
0b00110,
0b00110,
0b00000,
0b00111,
0b01110,
0b00110,
0b01110,
0b00101
};
byte jump[8]={
0b00100,
0b01100,
0b11100,
0b01110,
0b01100,
0b11111,
0b00000,
0b00001
};
byte def1[8] = {
0b00100,
0b00110,
0b00111,
0b01110,
0b00110,
0b01111,
0b01000,
0b00000
};
byte def2[8]={
0b00100,
0b00110,
0b00111,
0b01110,
0b00110,
0b00110,
0b00110,
0b00010
};
byte slide[8]={
0b00000,
0b00000,
0b00011,
0b00011,
0b00000,
0b01111,
0b11111,
0b00000
};
LiquidCrystal lcd(4,6,10,11,12,13);
void setup() {
Serial.begin(9600);
pinMode(btn,INPUT);
lcd.begin(16,2);
lcd.createChar(0,runnin1);
lcd.createChar(1,runnin2);
lcd.createChar(2,jump);
lcd.createChar(3,def1);
lcd.createChar(4,def2);
lcd.createChar(5,slide);
buttonState=digitalRead(btn);
}
void loop() {
intro();
while(game==1) ballActive();
endGame();
}
void intro() {
score=0;
lcd.clear();
lcd.print(introText[0]);
lcd.setCursor(7,1);
lcd.print("By SRP888");
delay(2000);
lcd.clear();
lcd.print(introText[1]);
lcd.setCursor(0,1);
lcd.print("21-06-2018");
delay(2000);
lcd.clear();
while(button()!=1) // ждем нажатия кнопки, отображая текст
{
lcd.setCursor(0,0);
lcd.print(introText[2]);
delay(100);
}
if(button()==1) game=1;
}
void reset() {
if(obstaclePos%2==0) // смена позы игрока для анимации бега, используя obstaclePos
{
lcd.clear();
lcd.setCursor(0,1);
lcd.write(byte(0));
}
else {
lcd.clear();
lcd.setCursor(0,1);
lcd.write(1);
}
}
void ballActive() {
obsDelay=200; // начальная задержка для защитника
obstaclePos=15; // так как 16x2 LCD, индекс начинается с 0
while(game==1) {
reset();
if(button()==1) // если кнопка нажата
{
lcd.clear();
lcd.setCursor(0,0);
lcd.write(2); // выводим игрока прыгающим
obstacle(obstaclePos); // выводим защитника
delay(400); // задержка, чтобы анимация не пропала слишком быстро
lcd.clear();
lcd.setCursor(0,1);
lcd.write(1); // игрок снова на земле
obstacle(obstaclePos); // защитник
}
else {
if(obstaclePos!=0) // если защитник не дошел до игрока, продолжаем
{
reset();
obstacle(obstaclePos);
}
else if(obstaclePos==0) // если защитник в позиции 0, т.е. дошел до игрока на земле — конец игры
{
game=0;
break;
}
}
obstaclePos--; // приближаем защитника к игроку
if(obstaclePos<0) // если игрок успешно увернулся
{
obsDelay=obsDelay-20; // уменьшаем задержку (увеличиваем скорость)
obstaclePos=15; // возвращаем защитника в начальную позицию
score++; // увеличиваем счет на 1
}
if(obsDelay==0) // если увернулись от 10 игроков (200/20=10), конец игры
game=0;
delay(obsDelay);
}
}
int button() {
int reading = digitalRead(btn);
// Если переключатель изменился из-за шума или нажатия:
if (reading != lastButtonState) {
// сброс таймера антидребезга
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
buttonState = reading;
if (buttonState == HIGH) {
lastButtonState = reading;
return 1;
}
}
lastButtonState = reading;
return 0;
}
void obstacle(int i) {
if(obstaclePos%2==0 && obstaclePos>2) // если защитник далеко, показываем его бегущим
{
lcd.setCursor(i,1);
lcd.write(3);
}
else if(obstaclePos%2!=0 && obstaclePos>2) {
lcd.setCursor(i,1);
lcd.write(4);
}
else // если он в 2 шагах от игрока, показываем скольжение
{
lcd.setCursor(i,1);
lcd.write(5);
}
}
void endGame() {
if(score==10) {
lcd.clear();
lcd.print("Congratulations!");
lcd.setCursor(0,1);
lcd.print("You beat 'em all");
delay(3000);
}
else if(score<3) {
lcd.clear();
lcd.print("You suck");
lcd.setCursor(0,1);
lcd.print("Score: ");
lcd.print(score);
delay(3000);
}
else if(score<6) {
lcd.clear();
lcd.print("Not bad!");
lcd.setCursor(0,1);
lcd.print("Score: ");
lcd.print(score);
delay(3000);
}
else {
lcd.clear();
lcd.print("Great!");
lcd.setCursor(0,1);
lcd.print("Score: ");
lcd.print(score);
delay(3000);
}
}
Схемы

Производственный процесс
- Почему быстрый прототипинг необходим для успешной разработки продукта
- Мастерство продуктового дизайна: проверенные стратегии преодоления частых вызовов
- Тетродная лампа: конструкция, функция и влияние на усилительные характеристики
- Профессиональный мониторинг температуры на Raspberry Pi с датчиком DS18B20
- Primal Display: создайте монитор температуры на Raspberry Pi с LCD
- Drone Pi: двухрежимный квадрокоптер Multiwii + Raspberry Pi для управления со смартфона и пульта
- Archimedes: Робот-совица с ИИ для распознавания эмоций
- Стратежическое источникование данных: ключ к устойчивым цепочкам поставок
- Проверенные шаги для быстрого, доступного ремонта промышленных сенсорных экранов
- Лучшие духовые дутуты 2024: как выбрать идеальную модель для вашего участка