/*
Se incluyó el movimiento combinado del texto al presionar dos botones
*/
#include <SPI.h>
const uint8_t CS_PIN = 11;
const uint8_t MOSI_PIN = 10;
const uint8_t MISO_PIN = 13; //Solo es necesario para la configuración SPI, la pantalla no devuelve datos
const uint8_t SCK_PIN = 12;
const uint8_t pinBotonDerecha = 35;
const uint8_t pinBotonIzquierda = 45;
const uint8_t pinBotonArriba = 40;
const uint8_t pinBotonAbajo = 19;
//Definición de registros de la matriz led
const uint8_t MAX7219_REG_NOOP = 0x00;
const uint8_t MAX7219_REG_DIGIT0 = 0x01;
const uint8_t MAX7219_REG_DIGIT1 = 0x02;
const uint8_t MAX7219_REG_DIGIT2 = 0x03;
const uint8_t MAX7219_REG_DIGIT3 = 0x04;
const uint8_t MAX7219_REG_DIGIT4 = 0x05;
const uint8_t MAX7219_REG_DIGIT5 = 0x06;
const uint8_t MAX7219_REG_DIGIT6 = 0x07;
const uint8_t MAX7219_REG_DIGIT7 = 0x08;
const uint8_t MAX7219_REG_DECODE_MODE = 0x09;
const uint8_t MAX7219_REG_INTENSITY = 0x0A;
const uint8_t MAX7219_REG_SCAN_LIMIT = 0x0B;
const uint8_t MAX7219_REG_SHUTDOWN = 0x0C;
const uint8_t MAX7219_REG_DISPLAY_TEST = 0x0F;
const uint8_t ArregloFilasNumero1[7] = {0x04, 0x06, 0x05, 0x04, 0x04, 0x04, 0x04};
const uint8_t ArregloFilasNumero2[7] = {0x06, 0x09, 0x08, 0x04, 0x02, 0x01, 0x0F};
const uint8_t ArregloFilasNumero3[7] = {0x07, 0x08, 0x08, 0x06, 0x08, 0x08, 0x07};
const uint8_t ArregloFilasNumero4[7] = {0x09, 0x09, 0x09, 0x0F, 0x08, 0x08, 0x08};
const uint8_t ArregloFilasNumero5[7] = {0x0F, 0x01, 0x01, 0x07, 0x08, 0x08, 0x07};
const uint8_t ArregloFilasNumero6[7] = {0x06, 0x09, 0x01, 0x07, 0x09, 0x09, 0x06};
const uint8_t ArregloFilasNumero7[7] = {0x0F, 0x08, 0x04, 0x04, 0x04, 0x02, 0x01};
const uint8_t ArregloFilasNumero8[7] = {0x06, 0x09, 0x09, 0x06, 0x09, 0x09, 0x06};
const uint8_t ArregloFilasNumero9[7] = {0x06, 0x09, 0x09, 0x0E, 0x08, 0x08, 0x08};
const uint8_t ArregloFilasNumero0[7] = {0x06, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06};
const uint8_t NumeroDeMatrices = 5;
uint8_t Fila;
uint8_t FilaAnterior;
uint8_t FilaPosterior;
uint8_t Matriz;
uint8_t MatrizAnterior;
uint8_t MatrizPosterior;
uint8_t EstadoActualMatrices[7][NumeroDeMatrices];
uint8_t EstadoAnteriorMatrices[7][NumeroDeMatrices];
uint8_t MatricesEstadoInicial[7][NumeroDeMatrices];
bool BotonPresionado;
void setup() {
Serial.begin(115200);
pinMode(pinBotonDerecha,INPUT_PULLUP);
pinMode(pinBotonIzquierda,INPUT_PULLUP);
pinMode(pinBotonArriba,INPUT_PULLUP);
pinMode(pinBotonAbajo,INPUT_PULLUP);
SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, CS_PIN);
pinMode(CS_PIN, OUTPUT);
digitalWrite(CS_PIN, HIGH);
ConfigurarConMax7219(MAX7219_REG_SCAN_LIMIT, 0x07); //Cuántas filas se utilizan
ConfigurarConMax7219(MAX7219_REG_DECODE_MODE, 0x01); //Módo de representación de los leds, solo binario o decodificador de BCD primero
ConfigurarConMax7219(MAX7219_REG_SHUTDOWN, 0x01); //Se prende la pantalla
ConfigurarConMax7219(MAX7219_REG_INTENSITY, 0x0F); //Brillo de los leds
for(Fila = 0; Fila < 7; Fila++){
MatricesEstadoInicial[Fila][0] = ArregloFilasNumero1[Fila];
MatricesEstadoInicial[Fila][1] = ArregloFilasNumero2[Fila];
MatricesEstadoInicial[Fila][2] = ArregloFilasNumero3[Fila];
MatricesEstadoInicial[Fila][3] = ArregloFilasNumero4[Fila];
MatricesEstadoInicial[Fila][4] = ArregloFilasNumero5[Fila];
}
ActualizarValoresAnterioresMatrices(MatricesEstadoInicial);
ImprimirNumerosEnMatrizLed(MatricesEstadoInicial);
}
void ConfigurarConMax7219(uint8_t Registro,uint8_t Dato){
digitalWrite(CS_PIN, LOW); //Inicio de la comunicación
//Con SPI.transfer, se envía y recibe datos a la vez. El valor () es el que se envía del maestro al esclavo. Los roles se definen con la inicialización en setup
SPI.transfer(Registro); //Primero se indica la dirección del registro
SPI.transfer(Dato); //Se inidca el dato a mandar al registro
digitalWrite(CS_PIN,HIGH); //Fin de la comunicación
}
void loop() {
//Se desplazan los valores
BotonPresionado = digitalRead(pinBotonDerecha) == LOW || digitalRead(pinBotonIzquierda) == LOW || digitalRead(pinBotonArriba) == LOW || digitalRead(pinBotonAbajo) == LOW;
if(BotonPresionado){
if(digitalRead(pinBotonDerecha) == LOW){
DesplazarPantalla('D');
}
if(digitalRead(pinBotonIzquierda) == LOW){
DesplazarPantalla('I');
}
if(digitalRead(pinBotonArriba) == LOW){
DesplazarPantalla('U');
}
if(digitalRead(pinBotonAbajo) == LOW){
DesplazarPantalla('A');
}
}
if(BotonPresionado){
BotonPresionado = false;
ImprimirNumerosEnMatrizLed(EstadoActualMatrices);
}
delay(100);
}
void ImprimirNumerosEnMatrizLed(uint8_t EstadoActualMatrices[7][NumeroDeMatrices]){
uint8_t EstadoActualFila[NumeroDeMatrices];
for(Fila = 0; Fila < 7; Fila++){
for(Matriz = 0; Matriz < NumeroDeMatrices; Matriz++){ //Se obtiene el estado actual de la fila
EstadoActualFila[Matriz] = EstadoActualMatrices[Fila][Matriz];
}
ComunicarConMax7219(Fila+1,EstadoActualFila);
}
}
void DesplazarPantalla(char Comando){
switch (Comando){
case 'I':
for(Fila = 0; Fila < 7; Fila++){
for(Matriz = 0; Matriz < NumeroDeMatrices; Matriz++){
if(Matriz+1 > 4){
MatrizAnterior = 0;
}else{
MatrizAnterior = Matriz + 1;
}
EstadoActualMatrices[Fila][Matriz] = EstadoAnteriorMatrices[Fila][Matriz] >> 1 | EstadoAnteriorMatrices[Fila][MatrizAnterior] << 7;
}
}
break;
case 'D':
for(Fila = 0; Fila < 7; Fila++){
for(Matriz = 0; Matriz < NumeroDeMatrices; Matriz++){
if(Matriz - 1 < 0 ){
MatrizPosterior = 4;
}else{
MatrizPosterior = Matriz - 1;
}
EstadoActualMatrices[Fila][Matriz] = EstadoAnteriorMatrices[Fila][Matriz] << 1 | EstadoAnteriorMatrices[Fila][MatrizPosterior] >> 7;
}
}
break;
case 'U':
for(Matriz = 0; Matriz < NumeroDeMatrices; Matriz++){
for(Fila = 0; Fila < 7; Fila++){
if(Fila + 1 > 6){
FilaAnterior = 0;
}else{
FilaAnterior = Fila + 1;
}
EstadoActualMatrices[Fila][Matriz] = EstadoAnteriorMatrices[FilaAnterior][Matriz];
}
}
break;
case 'A':
for(Matriz = 0; Matriz < NumeroDeMatrices; Matriz++){
for(Fila = 0; Fila < 7; Fila++){
if(Fila - 1 < 0){
FilaPosterior = 6;
}else{
FilaPosterior = Fila - 1;
}
EstadoActualMatrices[Fila][Matriz] = EstadoAnteriorMatrices[FilaPosterior][Matriz];
}
}
break;
default:
break;
}
ActualizarValoresAnterioresMatrices(EstadoActualMatrices);
}
void ComunicarConMax7219(uint8_t Registro,uint8_t EstadoFila[]){
digitalWrite(CS_PIN,LOW);
for(int i = 0; i < NumeroDeMatrices; i++){
SPI.transfer(Registro); //Los registros van del 1 al 7
SPI.transfer(EstadoFila[i]); //Se manda el estado actual de la fila de la matriz i+1
}
digitalWrite(CS_PIN,HIGH); //Se termina la comunicación con la fila
}
void ActualizarValoresAnterioresMatrices(uint8_t ValorMatrices[][NumeroDeMatrices]){
for(Fila = 0; Fila < 7; Fila++){
for(Matriz = 0; Matriz < NumeroDeMatrices; Matriz++){
EstadoAnteriorMatrices[Fila][Matriz] = ValorMatrices[Fila][Matriz];
}
}
}
//Comunicación SPI con la pantalla
//Al momento de pasar un arreglo o matriz a una función, se pasa en realidad un puntero a la dirección del primer dato.
//En el caso de una arreglo, no hace falta indicar la longitud solo []. Es equivalente pasar *arreglo o arreglo[].
//En ele caso de una matriz, no hace falta indicar las filas, solo las columnas [][NumeroColumnas]