- Portada
- Ensablaje mecánico
-
Programación básica
-
Introducción al Montaje Electrónico
-
Resistencias y Ejemplos de cálculo
-
El pulsador
-
La protoboard y los LEDs
-
Entradas y salidas digitales. Lectura de un pulsador y encendido de un led.
-
Entradas Analógicas. Lectura de un potenciómetro.
-
El Servomotor
-
Salidas PWM. Control posición de un servo
-
Cuestionario Programación básica10 xp
-
-
Programación extendida
-
Actividad. Estados de caja. Apertura y cierre
-
Actividad. Dial analógico. Introducción de dígitos. Pantalla LCD
-
Introducción a Funciones
-
Las funciones
-
Actividad. Funcionalidad elemental caja fuerte.
-
El Zumbador
-
Actividad. Sistema de alarma con zumbador
-
Actividad avanzada. Cambio de contraseña. Memoria EEPROM
-
Actividad avanzada. Display: Íconos y animaciones
-
Cuestionario Programación extendida10 xp
-
- Para terminar
Actividad avanzada. Display: Íconos y animaciones
TEMÁTICAS DE NUESTROS CURSOS
Programación

Explicación actividad a programar
Esta ultima actividad nos servirá para ilustrar la programación que se puede realizar con la pantalla LCD. No añadiremos ninguna funcionalidad nueva, y tampoco requeriremos de un montaje electrónico adicional. Tan solo nos centraremos en mejorar la interfaz de la pantalla, añadiendo iconos personalizados.
La pantalla LCD 1602 permite la creación de hasta 8 caracteres personalizados. Puedes definir estos caracteres utilizando matrices de 5x8 píxeles. En este código, se definen cuatro caracteres personalizados: un icono de candado cerrado, un icono de candado abierto, un icono de "enter" y un icono de borrar.
Código completo
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Pines
const int potPin = A0;
const int enterButtonPin = 2;
const int clearButtonPin = 3;
const int ledRedPin = 9;
const int ledGreenPin = 10;
const int ledBluePin = 11;
const int servoPin = 6;
const int buzzerPin = 7;
Servo myServo;
// Variables de estado
bool isBoxOpen = false;
int enteredDigit = 0;
int enteredCode[4];
int currentDigitIndex = 0;
const int defaultCode[4] = {6, 6, 6, 6};
int correctCode[4];
int attemptsLeft = 10;
int incorrectAttempts = 0;
bool waitingForCodeChange = false;
bool enterButtonReleased = false;
// Definición de caracteres personalizados
byte lockIcon[8] = {
0b01110,
0b10001,
0b10001,
0b11111,
0b11011,
0b11011,
0b11111,
0b00000
};
byte unlockIcon[8] = {
0b01110,
0b10001,
0b10001,
0b00111,
0b00111,
0b10111,
0b11111,
0b00000
};
byte enterIcon[8] = {
0b00100,
0b01110,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};
byte clearIcon[8] = {
0b11111,
0b10001,
0b10101,
0b10001,
0b10101,
0b10001,
0b11111,
0b00000
};
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.clear();
// Crear caracteres personalizados
lcd.createChar(0, lockIcon);
lcd.createChar(1, unlockIcon);
lcd.createChar(2, enterIcon);
lcd.createChar(3, clearIcon);
pinMode(potPin, INPUT);
pinMode(enterButtonPin, INPUT_PULLUP);
pinMode(clearButtonPin, INPUT_PULLUP);
pinMode(ledRedPin, OUTPUT);
pinMode(ledGreenPin, OUTPUT);
pinMode(ledBluePin, OUTPUT);
myServo.attach(servoPin);
digitalWrite(ledRedPin, HIGH);
digitalWrite(ledGreenPin, LOW);
digitalWrite(ledBluePin, LOW);
myServo.write(0);
lcd.setCursor(0, 0);
lcd.print("Dial:");
lcd.setCursor(0, 1);
lcd.print("Code:");
readCodeFromEEPROM();
// Si EEPROM estaba vacía, usar código por defecto
for (int i = 0; i < 4; i++) {
if (correctCode[i] < 0 || correctCode[i] > 9) {
correctCode[i] = defaultCode[i];
}
}
}
void loop() {
/* SI QUEREMOS VERIFICAR EL CÓDIGO CARGADO EN LA EEPROM
Serial.print("Código cargado: ");
for (int i = 0; i < 4; i++) {
Serial.print(correctCode[i]);
Serial.print(" ");
}
Serial.println();
*/
if (!isBoxOpen){
lcd.setCursor(12, 0);
lcd.write(0); // lock icon
delay(300);
}
else{
lcd.setCursor(13, 0);
lcd.write(1); // unlock icon
delay(300);
}
int potValue = analogRead(potPin);
enteredDigit = map(potValue, 0, 1023, 0, 9);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Dial:");
lcd.setCursor(5, 0);
lcd.print(enteredDigit);
lcd.setCursor(0, 1);
lcd.print("Code:");
updateLCD();
bool enterButtonState = digitalRead(enterButtonPin) == LOW;
bool clearButtonState = digitalRead(clearButtonPin) == LOW;
if (clearButtonState && !waitingForCodeChange) {
lcd.setCursor(14, 0);
lcd.write(3); // Clear icon
resetCode();
updateLCD();
delay(1000);
}
if (enterButtonState && currentDigitIndex < 4 && !waitingForCodeChange) {
enteredCode[currentDigitIndex] = enteredDigit;
currentDigitIndex++;
lcd.setCursor(15, 0);
lcd.write(2); // Enter icon
updateLCD();
delay(300);
}
if (currentDigitIndex == 4 && !waitingForCodeChange) {
if (checkCode()) {
openBox();
resetAttempts();
waitingForCodeChange = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Change Code?");
lcd.setCursor(0, 1);
lcd.print("Enter=Yes Clr=No");
} else {
incorrectAttempts++;
attemptsLeft--;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cod. incorrecto");
delay(1000);
lcd.setCursor(0, 1);
lcd.print("Intentos: ");
lcd.print(attemptsLeft);
delay(1000);
resetCode();
updateLCD();
if (incorrectAttempts >= 10) {
activateAlarm();
}
}
}
if (enterButtonState && clearButtonState && !waitingForCodeChange) {
closeBox();
delay(300);
}
if (waitingForCodeChange) {
if (!enterButtonState) {
enterButtonReleased = true; //compruebo si el usuario quiere cambiar la contraseña
}
if (enterButtonState && enterButtonReleased) {
enterButtonReleased = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("New Code:");
resetCode();
updateLCD();
delay(300);
while (currentDigitIndex < 4) {
potValue = analogRead(potPin);
enteredDigit = map(potValue, 0, 1023, 0, 9);
lcd.setCursor(10, 0);
lcd.print(enteredDigit);
if (digitalRead(enterButtonPin) == LOW) {
enteredCode[currentDigitIndex] = enteredDigit;
currentDigitIndex++;
updateLCD();
delay(300);
}
}
for (int i = 0; i < 4; i++) {
EEPROM.write(i, enteredCode[i]);
correctCode[i] = enteredCode[i];
}
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Code Updated");
delay(1000);
waitingForCodeChange = false;
resetCode();
}
if (clearButtonState) {
waitingForCodeChange = false;
resetCode();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Dial:");
lcd.setCursor(0, 1);
lcd.print("Code:");
}
}
delay(200);
}
void resetCode() {
currentDigitIndex = 0;
for (int i = 0; i < 4; i++) {
enteredCode[i] = 0;
}
}
void updateLCD() {
lcd.setCursor(5, 1);
for (int i = 0; i < 4; i++) {
if (i < currentDigitIndex) {
lcd.print(enteredCode[i]);
} else {
lcd.print("_");
}
}
}
bool checkCode() {
for (int i = 0; i < 4; i++) {
if (enteredCode[i] != correctCode[i]) {
return false;
}
}
return true;
}
void openBox() {
isBoxOpen = true;
digitalWrite(ledRedPin, LOW);
digitalWrite(ledGreenPin, HIGH);
digitalWrite(ledBluePin, LOW);
myServo.write(90);
}
void closeBox() {
isBoxOpen = false;
digitalWrite(ledRedPin, HIGH);
digitalWrite(ledGreenPin, LOW);
digitalWrite(ledBluePin, LOW);
myServo.write(0);
}
void activateAlarm() {
for (int i = 0; i < 10; i++) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ALARMA ACTIVA");
tone(buzzerPin, 1000);
delay(500);
noTone(buzzerPin);
delay(500);
}
incorrectAttempts = 0;
attemptsLeft = 10;
}
void resetAttempts() {
incorrectAttempts = 0;
attemptsLeft = 10;
}
void readCodeFromEEPROM() {
for (int i = 0; i < 4; i++) {
correctCode[i] = EEPROM.read(i);
}
}
| Vistas | |
|---|---|
| 3 | Número de vistas |
| 3 | Vistas de miembros |
| 0 | Vistas públicas |
| Acciones | |
|---|---|
| 0 | Gustos |
| 0 | No me gusta |
| 0 | Comentarios |
Compartir por correo
Por favor iniciar sesión para compartir esto webpage por correo.