Control de 9 LEDs con Teclado 4x4, Pantalla GLCD ST7920 (128x64) y Sensor DHT22.
Control de 9 LEDs con Teclado Matricial 4x4, GLCD ST7920 y Sensor DHT22
Pines 13 al 5
23-29 / 31-37
53 (E), 51, 50
Pin 41 (Data)
#include <Arduino.h>
#include <Keypad.h>
#include <DHT.h>
#include <U8g2lib.h>
// 1. Pines de los 9 LEDs (de izquierda a derecha en la protoboard)
const int pinesLeds[] = {13, 12, 11, 10, 9, 8, 7, 6, 5};
const int numLeds = sizeof(pinesLeds) / sizeof(pinesLeds[0]);
// 2. Pines de los 4 pulsadores físicos (Pull-Down)
const int PIN_BTN1 = 28;
const int PIN_BTN2 = 26;
const int PIN_BTN3 = 24;
const int PIN_BTN4 = 22;
// 3. Sensor DHT22
#define DHTPIN 41
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// 4. Teclado Matricial 4x4
const byte FILAS = 4;
const byte COLUMNAS = 4;
char teclas[FILAS][COLUMNAS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte pinesFilas[FILAS] = {23, 25, 27, 29};
byte pinesColumnas[COLUMNAS] = {31, 33, 35, 37};
Keypad teclado = Keypad(makeKeymap(teclas), pinesFilas, pinesColumnas, FILAS, COLUMNAS);
// 5. Pantalla GLCD 128x64 ST7920 en Modo Serie SPI
// E = Clock (53), R/W = Data/SID (51), RS = CS (50)
U8G2_ST7920_128X64_1_SW_SPI u8g2(U8G2_R0, 53, 51, 50, U8X8_PIN_NONE);
// Variables de estado
int secuenciaActiva = 0;
int pasoSecuencia = 0;
unsigned long ultimoPasoLed = 0;
const unsigned long INTERVALO_LED = 200;
float temperatura = 25.0;
float humedad = 50.0;
unsigned long ultimoMuestreoDHT = 0;
const unsigned long INTERVALO_DHT = 2000;
bool actualizarGLCD = true;
bool estadoPrevBtn1 = LOW, estadoPrevBtn2 = LOW, estadoPrevBtn3 = LOW, estadoPrevBtn4 = LOW;
// Prototipos
void cambiarModo(int nuevoModo);
void leerEntradas();
void leerSensorDHT();
void actualizarAnimacionLeds();
void refrescarPantallaGLCD();
void encenderTodos();
void apagarTodos();
void setup() {
Serial.begin(9600);
for (int i = 0; i < numLeds; i++) {
pinMode(pinesLeds[i], OUTPUT);
digitalWrite(pinesLeds[i], LOW);
}
pinMode(PIN_BTN1, INPUT);
pinMode(PIN_BTN2, INPUT);
pinMode(PIN_BTN3, INPUT);
pinMode(PIN_BTN4, INPUT);
dht.begin();
u8g2.begin();
apagarTodos();
refrescarPantallaGLCD();
}
void loop() {
leerEntradas();
leerSensorDHT();
actualizarAnimacionLeds();
if (actualizarGLCD) {
refrescarPantallaGLCD();
actualizarGLCD = false;
}
}
void leerEntradas() {
char tecla = teclado.getKey();
if (tecla != NO_KEY) {
if (tecla == '1') cambiarModo(1);
else if (tecla == '2') cambiarModo(2);
else if (tecla == '3') cambiarModo(3);
else if (tecla == '4') cambiarModo(4);
}
bool b1 = digitalRead(PIN_BTN1);
bool b2 = digitalRead(PIN_BTN2);
bool b3 = digitalRead(PIN_BTN3);
bool b4 = digitalRead(PIN_BTN4);
if (b1 == HIGH && estadoPrevBtn1 == LOW) cambiarModo(1);
else if (b2 == HIGH && estadoPrevBtn2 == LOW) cambiarModo(2);
else if (b3 == HIGH && estadoPrevBtn3 == LOW) cambiarModo(3);
else if (b4 == HIGH && estadoPrevBtn4 == LOW) cambiarModo(4);
estadoPrevBtn1 = b1; estadoPrevBtn2 = b2; estadoPrevBtn3 = b3; estadoPrevBtn4 = b4;
}
void cambiarModo(int nuevoModo) {
secuenciaActiva = nuevoModo;
pasoSecuencia = 0;
ultimoPasoLed = millis();
actualizarGLCD = true;
if (secuenciaActiva == 1) encenderTodos();
else if (secuenciaActiva == 2) apagarTodos();
else if (secuenciaActiva == 3 || secuenciaActiva == 4) apagarTodos();
}
void leerSensorDHT() {
if (millis() - ultimoMuestreoDHT >= INTERVALO_DHT) {
ultimoMuestreoDHT = millis();
float t = dht.readTemperature();
float h = dht.readHumidity();
if (!isnan(t) && !isnan(h)) {
if ((int)round(t) != (int)round(temperatura) || (int)round(h) != (int)round(humedad)) {
temperatura = t;
humedad = h;
actualizarGLCD = true;
}
}
}
}
void actualizarAnimacionLeds() {
if (secuenciaActiva == 3) {
// Secuencia 3: Acumulativa
if (millis() - ultimoPasoLed >= INTERVALO_LED) {
ultimoPasoLed = millis();
if (pasoSecuencia < numLeds) {
digitalWrite(pinesLeds[pasoSecuencia], HIGH);
pasoSecuencia++;
} else if (pasoSecuencia == numLeds) {
pasoSecuencia++;
} else {
apagarTodos();
pasoSecuencia = 0;
}
}
} else if (secuenciaActiva == 4) {
// Secuencia 4: Barrido
if (millis() - ultimoPasoLed >= INTERVALO_LED) {
ultimoPasoLed = millis();
apagarTodos();
digitalWrite(pinesLeds[pasoSecuencia], HIGH);
pasoSecuencia++;
if (pasoSecuencia >= numLeds) pasoSecuencia = 0;
}
}
}
void refrescarPantallaGLCD() {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_ncenB10_tr);
u8g2.setCursor(4, 18);
u8g2.print(F("TEMPERATURA "));
if (isnan(temperatura)) u8g2.print(F("--"));
else u8g2.print((int)round(temperatura));
u8g2.print(F(" \xb0\x43"));
u8g2.setCursor(4, 38);
u8g2.print(F("HUMEDAD "));
if (isnan(humedad)) u8g2.print(F("--"));
else u8g2.print((int)round(humedad));
u8g2.print(F(" %"));
u8g2.setCursor(24, 58);
u8g2.print(F("secuencia "));
u8g2.print(secuenciaActiva);
} while (u8g2.nextPage());
}
void encenderTodos() {
for (int i = 0; i < numLeds; i++) digitalWrite(pinesLeds[i], HIGH);
}
void apagarTodos() {
for (int i = 0; i < numLeds; i++) digitalWrite(pinesLeds[i], LOW);
}