Projeto DIY Arduino LCD: Monte com Resistores, Botão e Display 16x2
Componentes e Materiais
- Resistor 10k ohm – 2 unidades (um para contraste do LCD, outro para o botão. Importante: Use o resistor em configuração pull-down, não pull-up como mostrado no manual.)
- Resistor 1k ohm – 1 unidade (para contraste do LCD)
- Chave Pushbutton 12mm SparkFun – 1 unidade
- LCD Padrão Adafruit 16x2 Branco sobre Azul – 1 unidade
- Arduino UNO – 1 unidade
- Jumpers (genéricos) – 1 unidade
Sobre o Projeto
Histórico
Fazia parte de um projeto maior, mas houve atraso. Decidi fazer algo com meu antigo kit Arduino. Nunca tinha usado a tela LCD. Soldei os pinos na tela (aprendi a soldar pela primeira vez).
Inicialmente copiei código de um manual online e carreguei. Só exibia texto movendo para direita e esquerda. Foi quando conheci a biblioteca LiquidCrystal. Escrevi um código que fazia o número "0" quicar pela tela, foi divertido. Então pensei em fazer algo mais complexo, um jogo. Pesquisei jogos para LCD no Arduino e encontrei apenas 3 jogos, 2 funcionaram para mim. O código era complexo demais para entender, então decidi criar um jogo fácil.
Configuração
Conecte os pinos do LCD ao Arduino com fios conforme o esquemático abaixo.
Usei um potenciômetro de 10k para ajustar o contraste e ajustei para o contraste desejado. Medi a resistência entre os pinos com multímetro e usei resistores apropriados (1k e 10k ohms em série) para o pino VO do LCD.
Coloque um push button na protoboard e conecte o fio de entrada ao pino 8 do Arduino. Carregue o código no seu Arduino e pronto.
Nota: Use o resistor do botão em modo pull-down, como mostrado no esquemático.
Jogando o Jogo
Neste jogo, você é um jogador de futebol com a bola nos pés. Defensores se aproximam e você deve simplesmente desviar deles.
Após a introdução, pressione o botão quando solicitado. Quando o defensor chegar perto o suficiente, pressione o botão para pular. O próximo defensor virá com velocidade maior, e isso continua por 10 defensores.
PS: Inicialmente usei "0" como jogador e "1" como obstáculo. Como a Copa do Mundo FIFA 2018 está acontecendo e sou fã do Messi, mudei o tema.
Criei os glifos para jogador e defensor usando um gerador online: https://omerk.github.io/lcdchargen/
Código
lcd_1.ino Arduino
/* Dodge the defs!! Criado por: Shreyas R P Criado em: 21-06-2018 E-mail: shreyasrp888@gmail.com
Um jogo simples para LCD 16x2 com um botão. Se fizer melhorias, adicione seus créditos abaixo.
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 .
--------------------------------------------------------------------------------------------- */
#include <LiquidCrystal.h>
const int btn = 8; // pino de entrada do botão
// textos para exibir
char* introText[] = {"Dodge the defs!!", "Created on:", "Hit the button..."};
// declarações de variáveis
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;
// GRÁFICOS
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) {
lcd.clear();
lcd.setCursor(0, 1);
lcd.write(byte(0));
} else {
lcd.clear();
lcd.setCursor(0, 1);
lcd.write(1);
}
}
void ballActive() {
obsDelay = 200; // delay inicial do defensor
obstaclePos = 15; // LCD 16x2, índice começa em 0
while (game == 1) {
reset();
if (button() == 1) { // se botão pressionado
lcd.clear();
lcd.setCursor(0, 0);
lcd.write(2); // jogador pulando
obstacle(obstaclePos); // imprime defensor
delay(400); // para não desaparecer rápido
lcd.clear();
lcd.setCursor(0, 1);
lcd.write(1); // jogador no chão
obstacle(obstaclePos);
} else {
if (obstaclePos != 0) {
reset();
obstacle(obstaclePos);
} else if (obstaclePos == 0) {
game = 0;
break;
}
}
obstaclePos--; // aproxima defensor
if (obstaclePos < 0) { // se desviou com sucesso
obsDelay = obsDelay - 20; // diminui delay (aumenta velocidade)
obstaclePos = 15; // reposiciona defensor
score++; // aumenta pontuação
}
if (obsDelay == 0) game = 0; // se 10 defensores desviados (200/20=10), fim de jogo
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 {
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);
}
}
Esquemático

Processo de manufatura
- Por Que a Prototipagem Rápida é Essencial para o Desenvolvimento de Produtos Bem-Sucedido
- Dominando Design de Produto: Estratégias Comprovadas para Superar Desafios Comuns
- O Tubo Tetrodo: Projeto, Função e Impacto no Desempenho do Amplificador
- Monitoramento Profissional de Temperatura com Raspberry Pi e DS18B20
- Primal Display: Construa Monitor de Temperatura LCD com Raspberry Pi
- Drone Pi: Quadricóptero Multiwii & Raspberry Pi de Modo Duplo para Controle por Smartphone e Remoto
- Arquimedes: O Robô Coruja Sensor de Emoções com IA
- Fontes Estratégicas de Dados: A Chave para Cadeias de Suprimentos Resilientes
- Passos Comprovados para Reparo Rápido e Acessível de Telas Touch Industriais
- Melhores Sopradores de Folhas 2024: Encontre o Modelo Ideal para Seu Jardim