#include <Arduino.h>
#include "soc/gpio_struct.h"
#include "soc/gpio_reg.h"
// Definiciones de imágenes
#define IMG_CARITA 10
#define IMG_QUIETO 11
#define IMG_MANO_ARRIBA 12
#define IMG_MANO_ABAJO 13
#define IMG_PALMA 14
#define IMG_APAGADO 15
class myDisplay {
private:
int img; // Imagen actual
int filaActual;
// Tiempo de espera entre cada fila del barrido
static const int tiempoRetardo = 5;
// Pines de la matriz
const uint8_t pines_filas[8] = {13, 14, 16, 17, 18, 19, 21, 22};
const uint8_t pines_columnas[8] = {23, 25, 26, 27, 32, 33, 4, 5};
// Una fila activa en 0 y las demás en 1
const uint8_t seleccion_filas[8] = {
0b11111110,
0b11111101,
0b11111011,
0b11110111,
0b11101111,
0b11011111,
0b10111111,
0b01111111
};
// Imágenes en hexadecimal
const uint8_t img_carita[8] = {
0x3C, 0x42, 0xA5, 0x81, 0xA5, 0x99, 0x42, 0x3C
};
const uint8_t img_quieto[8] = {
0x3c, 0x42, 0xa1, 0x91, 0x89, 0x85, 0x42, 0x3c
};
const uint8_t img_mano_arriba[8] = {
0x18,0x3c,0x7e,0xdb,0x99,0x18,0x18,0x18
};
const uint8_t img_mano_abajo[8] = {
0x18,0x18,0x18,0x99,0xdb,0x7e,0x3c,0x18
};
const uint8_t img_palma[8] = {
0x00, 0x24, 0x5a, 0x5a, 0x5a, 0x5a, 0x24, 0x00
};
const uint8_t img_apagado[8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Máscaras para apagar rápido grupos de pines
uint32_t mascara_filas_bajas;
uint32_t mascara_columnas_bajas;
uint32_t mascara_columnas_altas;
void configurarPinSalida(uint8_t pin) {
if (pin < 32) {
GPIO.enable_w1ts = (1UL << pin);
} else {
GPIO.enable1_w1ts.val = (1UL << (pin - 32));
}
}
/// reescribir en el puerto en esos puertos
void escribirPin(uint8_t pin, bool valor) {
if (pin < 32) {
if (valor) {
GPIO.out_w1ts = (1UL << pin);
} else {
GPIO.out_w1tc = (1UL << pin);
}
} else {
if (valor) {
GPIO.out1_w1ts.val = (1UL << (pin - 32));
} else {
GPIO.out1_w1tc.val = (1UL << (pin - 32));
}
}
}
void apagarColumnas() {
GPIO.out_w1tc = mascara_columnas_bajas;
GPIO.out1_w1tc.val = mascara_columnas_altas;
}
void apagarFilas() {
GPIO.out_w1ts = mascara_filas_bajas;
}
void escribirFila(uint8_t patronFila) {
for (int i = 0; i < 8; i++) {
uint8_t bitFila = (patronFila >> (7 - i)) & 0x01;
escribirPin(pines_filas[i], bitFila);
}
}
void escribirColumnas(uint8_t patronColumnas) {
for (int i = 0; i < 8; i++) {
uint8_t bitColumna = (patronColumnas >> (7 - i)) & 0x01;
escribirPin(pines_columnas[i], bitColumna);
}
}
const uint8_t* obtenerImagenActual() {
switch (img) {
case IMG_CARITA: return img_carita;
case IMG_QUIETO: return img_quieto;
case IMG_MANO_ARRIBA: return img_mano_arriba;
case IMG_MANO_ABAJO: return img_mano_abajo;
case IMG_PALMA: return img_palma;
case IMG_APAGADO: return img_apagado;
default: return img_apagado;
}
}
public:
// Constructor
myDisplay() {
img = IMG_APAGADO;
filaActual = 0;
mascara_filas_bajas = 0;
mascara_columnas_bajas = 0;
mascara_columnas_altas = 0;
}
// Inicializa el controlador
void begin() {
for (int i = 0; i < 8; i++) {
configurarPinSalida(pines_filas[i]);
configurarPinSalida(pines_columnas[i]);
}
for (int i = 0; i < 8; i++) {
if (pines_filas[i] < 32) {
mascara_filas_bajas |= (1UL << pines_filas[i]);
}
if (pines_columnas[i] < 32) {
mascara_columnas_bajas |= (1UL << pines_columnas[i]);
} else {
mascara_columnas_altas |= (1UL << (pines_columnas[i] - 32));
}
}
apagarFilas();
apagarColumnas();
}
// Fija la imagen que será visualizada
void show(int imagen) {
img = imagen;
}
// Realiza un ciclo de refresco del display
void refresh() {
const uint8_t* imagenActual = obtenerImagenActual();
apagarFilas();
apagarColumnas();
escribirFila(seleccion_filas[filaActual]);
// Se usa 7-filaActual porque en tu montaje la imagen salía invertida verticalmente
escribirColumnas(imagenActual[7 - filaActual]);
delay(tiempoRetardo);
apagarColumnas();
filaActual++;
if (filaActual >= 8) {
filaActual = 0;
}
}
};
myDisplay disp;
unsigned long tiempoInicio;
void setup() {
disp.begin();
disp.show(IMG_CARITA);
tiempoInicio = millis();
}
void loop() {
// Mostrar QUIETO por 10 segundos
disp.show(IMG_QUIETO);
while(millis() < tiempoInicio + 1000) {
disp.refresh();
}
tiempoInicio = millis();
// Mostrar MANO_ARRIBA por 10 segundos
disp.show(IMG_MANO_ARRIBA);
while(millis() < tiempoInicio + 1000) {
disp.refresh();
}
tiempoInicio = millis();
// Mostrar MANO_ABAJO por 10 segundos
disp.show(IMG_MANO_ABAJO);
while(millis() < tiempoInicio + 1000) {
disp.refresh();
}
tiempoInicio = millis();
// Mostrar PALMA por 10 segundos
disp.show(IMG_PALMA);
while(millis() < tiempoInicio + 1000) {
disp.refresh();
}
tiempoInicio = millis();
// Mostrar APAGADO por 10 segundos
disp.show(IMG_APAGADO);
while(millis() < tiempoInicio + 1000) {
disp.refresh();
}
tiempoInicio = millis();
// Mostrar CARITA por 10 segundos
disp.show(IMG_CARITA);
while(millis() < tiempoInicio + 1000) {
disp.refresh();
}
tiempoInicio = millis();
}