Arduino Mega 2560

Simulador Práctica 3

Control de 9 LEDs con Teclado 4x4, Pantalla GLCD ST7920 (128x64) y Sensor DHT22.

💡

Barra de 9 LEDs en Protoboard (Pines 13 al 5)

Modo 0: Reposo inicial 200 ms / paso
Pin 13 Rojo
Pin 12 Rojo
Pin 11 Verde
Pin 10 Verde
Pin 9 Amarillo
Pin 8 Verde
Pin 7 Rojo
Pin 6 Amarillo
Pin 5 Verde

📺 Pantalla GLCD (ST7920)

SPI: 53, 51, 50
TEMPERATURA 25 °C
HUMEDAD 50 %
secuencia 0
Modo activo en micro: secuenciaActiva = 0

⌨️ Teclado Matricial 4x4

Pines: 23-29, 31-37
Teclas activas: 1, 2, 3, 4

🔘 4 Pulsadores Físicos

Pines 28, 26, 24, 22
🌡️ Sensor DHT22 (Pin 41)
Temperatura: 25 °C
Humedad: 50 %
C++ / Arduino

Código Fuente: Práctica 3

Control de 9 LEDs con Teclado Matricial 4x4, GLCD ST7920 y Sensor DHT22

💡 9 LEDs: Pines 13 al 5
⌨️ Teclado 4x4: 23-29 / 31-37
📺 GLCD ST7920: 53 (E), 51, 50
🌡️ Sensor DHT22: Pin 41 (Data)
practica3_teclado_glcd.ino / control_motor_mega.ino 100% C++ para Arduino Mega 2560
#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);
}