Proyecto Arduino LCD DIY: Ensamblaje con resistencias, pulsador y display 16x2
Componentes y materiales
| Resistencia 10k ohm | × | 2 | Una para contraste LCD, otra para el botón. Importante: Use la resistencia en configuración pull-down, no pull-up como muestra el manual. |
| Resistencia 1k ohm | × | 1 | Para el contraste de la pantalla LCD. |
| Pulsador SparkFun 12mm | × | 1 | |
| Pantalla LCD estándar Adafruit 16x2 Blanco sobre Azul | × | 1 | |
| Arduino UNO | × | 1 | |
| Cables jumper (genéricos) | × | 1 |
Sobre este proyecto
Antecedentes
Formaba parte de un proyecto mayor pero hubo un retraso. Decidí hacer algo con mi viejo kit de Arduino. Nunca había usado la pantalla LCD. Así que soldé los pines en la pantalla (aprendí a soldar por primera vez).
Inicialmente copié el código de un manual en línea y lo subí. Solo mostraba texto moviéndose derecha e izquierda. Fue cuando conocí la librería LiquidCrystal. Escribí un código que hacía rebotar el número "0" por la pantalla, fue muy divertido. Entonces pensé en hacer algo más complejo, un juego. Busqué juegos para LCD en Arduino y solo encontré 3, 2 de los cuales funcionaron para mí. El código de esos juegos era demasiado complejo para entenderlo, así que decidí crear uno fácil.
Configuración
Conecte los pines del LCD al Arduino con cables como se muestra en el esquemático.
Usé un potenciómetro de 10k para ajustar el contraste y lo ajusté al nivel deseado. Medí la resistencia entre pines con un multímetro y usé resistencias apropiadas (1k y 10k ohmios en serie) para el pin VO del LCD.
Coloque un pulsador en la protoboard y conecte el cable de entrada al pin 8 del Arduino. Suba el código a su Arduino y listo.
Nota: Use la resistencia del botón en modo pull-down, como se muestra en el esquemático.
Jugando el juego
En este juego, eres un jugador de fútbol con el balón a tus pies. Tendrás defensores acercándose, y simplemente debes esquivarlos.
Después de la intro, pulsa el botón cuando se te pida. Cuando el defensor se acerque lo suficiente, pulsa el botón para saltar. El siguiente defensor se acercará a mayor velocidad, y esto continúa por 10 defensores.
PD: Inicialmente usé "0" como jugador y "1" como obstáculo. Como el Mundial 2018 está en curso y soy fan de Messi, decidí cambiar el tema.
Creé los glifos para el jugador y defensor usando un generador en línea: https://omerk.github.io/lcdchargen/
Código
lcd_1.ino (Arduino)
/* ¡Esquiva a los defensores!! Creado por: Shreyas R P
* Fecha: 21-06-2018 | Email: shreyasrp888@gmail.com
* Juego simple para LCD 16x2 con un botón.
* Licencia: GNU GPL v3 */
#include <LiquidCrystal.h>
const int btn = 8; // pin de entrada del botón
// Textos a mostrar
char* introText[] = {"Esquiva a los defs!!", "Creado el:", "Pulsa el boton..."};
// Declaración de variables
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: caracteres personalizados (8 bytes cada uno)
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); // RS, E, D4, D5, D6, D7
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) { // espera a que se pulse el botón
lcd.setCursor(0, 0);
lcd.print(introText[2]);
delay(100);
}
if (button() == 1) game = 1;
}
void reset() {
// Alterna animación de correr usando obstaclePos
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 del defensor
obstaclePos = 15; // posición inicial (LCD 16x2, índice 0-15)
while (game == 1) {
reset();
if (button() == 1) { // botón pulsado = salto
lcd.clear();
lcd.setCursor(0, 0);
lcd.write(2); // jugador saltando
obstacle(obstaclePos); // muestra defensor
delay(400); // pausa para ver la acción
lcd.clear();
lcd.setCursor(0, 1);
lcd.write(1); // jugador en suelo
obstacle(obstaclePos);
} else {
if (obstaclePos != 0) { // defensor no ha llegado
reset();
obstacle(obstaclePos);
} else if (obstaclePos == 0) { // defensor alcanza al jugador en suelo
game = 0;
break;
}
}
obstaclePos--; // defensor se acerca
if (obstaclePos < 0) { // esquivado con éxito
obsDelay = obsDelay - 20; // aumenta velocidad
obstaclePos = 15; // reinicia posición
score++; // incrementa puntuación
}
if (obsDelay == 0) // 10 defensores esquivados (200/20=10)
game = 0;
delay(obsDelay);
}
}
// Lectura de botón con anti-rebote
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;
}
// Dibuja el defensor según su posición
void obstacle(int i) {
if (obstaclePos % 2 == 0 && obstaclePos > 2) { // lejos: corriendo
lcd.setCursor(i, 1);
lcd.write(3);
} else if (obstaclePos % 2 != 0 && obstaclePos > 2) {
lcd.setCursor(i, 1);
lcd.write(4);
} else { // cerca: deslizándose
lcd.setCursor(i, 1);
lcd.write(5);
}
}
void endGame() {
if (score == 10) {
lcd.clear();
lcd.print("¡Felicidades!");
lcd.setCursor(0, 1);
lcd.print("Los venciste a todos");
delay(3000);
} else if (score < 3) {
lcd.clear();
lcd.print("Eres malo");
lcd.setCursor(0, 1);
lcd.print("Puntuacion: ");
lcd.print(score);
delay(3000);
} else if (score < 6) {
lcd.clear();
lcd.print("¡No esta mal!");
lcd.setCursor(0, 1);
lcd.print("Puntuacion: ");
lcd.print(score);
delay(3000);
} else {
lcd.clear();
lcd.print("¡Genial!");
lcd.setCursor(0, 1);
lcd.print("Puntuacion: ");
lcd.print(score);
delay(3000);
}
}
Esquemático

Proceso de manufactura
- Pasos Comprobados para Reparación Rápida y Asequible de Pantallas Táctiles Industriales
- Por qué el prototipado rápido es esencial para el desarrollo exitoso de productos
- Dominando el diseño de productos: estrategias probadas para superar desafíos comunes
- Pantalla de Cristal Líquido (LCD): Tecnología, Fabricación y Perspectivas Futuras
- Monitorización profesional de temperatura con Raspberry Pi y DS18B20
- Primal Display: construye monitor temperatura LCD con Raspberry Pi
- Drone Pi: Quadcopter Multiwii y Raspberry Pi de doble modo para control por smartphone y mando a distancia
- Arquímedes: El Búho Robot Sensor de Emociones con IA
- Mejores sopladores de hojas 2024: Encuentre el modelo ideal para su jardín
- El Tubo Tetrodo: Diseño, Función e Impacto en el Rendimiento del Amplificador
- Abastecimiento Estratégico de Datos: La Clave para Cadenas de Suministro Resilientes