Buenas a todos, espero que estén bien.
Hace un tiempo, gracias a la ayuda de algunos miembros de la comunidad, despejé un montón de dudas y me permitió concretar un poco mas mi proyecto, el cual nuevamente se ve demorado por mi inexperiencia en este campo, obligándome a recurrir nuevamente a sus conocimientos.
El proyecto:
El proyecto se trata de un dispositivo para contar distintos tipos de valores (Vida, Veneno y daño de comandantes (3) ) en un juego de cartas, en este caso, MTG. Y cuyos valores incrementan o decrecen gracias a dos pulsadores por contador, lo cual hace un total de 10 pulsadores.
El problema:
Por cuestiones de tamaño, el diseño final del dispositivo me impide contar con 10 pulsadores físicos para la tarea, por lo cual me veo obligado a optar por un encoder, específicamente el KY-040 (adjunto imagen de referencia)
y solo dos pulsadores para incrementar o decrecer los valores seleccionados.
Mi solicitud:
No cuento con los conocimientos necesarios en este campo, solo soy un aficionado que quiere diseñar un objeto para enriquecer su juego de mesa, por eso humildemente les solicito ayuda con este problema.
Quisiera que me ayudaran a modificar mi código para:
- Que el dispositivo solo cuente con un Encoder KY-040 y dos pulsadores normalmente abiertos como métodos de entrada.
- Que el Encoder KY-040 funcione como selector (omitiendo su switch) y que los pulsadores puedan variar el valor sobre donde esta posicionado el encoder.
Dicho en palabras simples, quiero utilizar el encoder como una rueda de selección entre los 5 contadores y que con los pulsadores dichos contadores cambien de valor.
El código:
//Proyecto: "Contador para MTG - Commmander"
//Descripcion: Dispositivo que permite tener cinco contadores: 1 para la Vida, 1 para Veneno y 3 contadores para puntos de daños por parte de los comandantes enemigos, cuyos valores incrementan o decrecen segun el pulsador asociado.
//Los valores limite para ellos son: Vida = 20, Veneno = 10, COM (1/2/3) = 21. Los valores son impresos en un dispaly OLED SSD1306 de 0.91 pulgadas.
//Creador: KingAbaaddon
//**Librerias
//Pantalla
#include <Adafruit_SSD1306.h> // libreria para controlador SSD1306
//Pantalla
#define ANCHO 128 // reemplaza ocurrencia de ANCHO por 128
#define ALTO 64 // reemplaza ocurrencia de ALTO por 64
//Reset
#define OLED_RESET -1 // necesario por la libreria pero no usado. -1 porque tiene boton
Adafruit_SSD1306 oled(ANCHO, ALTO, &Wire, OLED_RESET); // crea objeto
//**Declaraciones
//Vida
int valor_actual = -1; // valor inicial -1 para inicializar antes de contar
int pulsador = 4; // pin en donde se conecta el pulsador
int despulsador = 3; // pin en donde se conecta el pulsador
bool estPulActual = 1; // variable donde se guarda el estado logico actual del pulsador
bool estPulAnterior = 1; // variable donde se guarda el estado logico anterior del pulsador
//Veneno
int valor_actual_veneno = -1; // valor inicial -1 para inicializar antes de contar
int pulsador_veneno = 6; // pin en donde se conecta el pulsador
int pulsador_veneno_negativo = 5; // pin en donde se conecta el pulsador
bool estVenActual = 1; // variable donde se guarda el estado logico actual del pulsador
bool estVenAnterior = 1; // variable donde se guarda el estado logico anterior del pulsador
//Comandantes
//COM1
int valor_actual_COM1 = -1; // valor inicial -1 para inicializar antes de contar
int pulsador_COM1 = 8; // pin en donde se conecta el pulsador
int pulsador_COM1n = 7; // pin en donde se conecta el pulsador
bool estCOM1Actual = 1; // variable donde se guarda el estado logico actual del pulsador
bool estCOM1Anterior = 1; // variable donde se guarda el estado logico anterior del pulsador
//COM2
int valor_actual_COM2 = -1; // valor inicial -1 para inicializar antes de contar
int pulsador_COM2 = 10; // pin en donde se conecta el pulsador
int pulsador_COM2n = 9; // pin en donde se conecta el pulsador
bool estCOM2Actual = 1; // variable donde se guarda el estado logico actual del pulsador
bool estCOM2Anterior = 1; // variable donde se guarda el estado logico anterior del pulsador
//COM3
int valor_actual_COM3 = -1; // valor inicial -1 para inicializar antes de contar
int pulsador_COM3 = 12; // pin en donde se conecta el pulsador
int pulsador_COM3n = 11; // pin en donde se conecta el pulsador
bool estCOM3Actual = 1; // variable donde se guarda el estado logico actual del pulsador
bool estCOM3Anterior = 1; // variable donde se guarda el estado logico anterior del pulsador
//**Logo
// 'LOGO', 128x48px
const unsigned char Mi_Logologo [] PROGMEM = {
0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x01, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x03, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x03, 0x82, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x03, 0x82, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x07, 0xc2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x0f, 0xe2, 0x02, 0x00, 0x04, 0x30, 0x7c, 0x01, 0xf9, 0xe2, 0x13, 0xc0, 0x60, 0x30, 0x20,
0x02, 0x0f, 0xe3, 0x06, 0x00, 0x1f, 0x7c, 0x7c, 0x19, 0xfd, 0xf7, 0x37, 0xc0, 0xf8, 0x60, 0x60,
0x02, 0x1f, 0xf1, 0xfc, 0x00, 0x19, 0x64, 0x70, 0x18, 0x30, 0xe7, 0x37, 0x00, 0x4c, 0x4e, 0x60,
0x02, 0x1f, 0xf0, 0xd8, 0x00, 0x30, 0x6c, 0x70, 0x1c, 0x30, 0xe3, 0x37, 0x00, 0x4c, 0xde, 0x60,
0x02, 0x0f, 0xe0, 0x88, 0x00, 0x30, 0x6c, 0x60, 0x1c, 0x30, 0xe3, 0x37, 0x00, 0x4c, 0xde, 0x60,
0x02, 0x07, 0xc1, 0x8c, 0x00, 0x20, 0x76, 0x60, 0x2c, 0x30, 0xe3, 0x67, 0x00, 0x6c, 0x42, 0x60,
0x02, 0x07, 0xc1, 0x8c, 0x00, 0x60, 0x04, 0x60, 0x24, 0x30, 0x61, 0x66, 0x00, 0x4c, 0x42, 0x60,
0x02, 0x03, 0x81, 0x8c, 0x00, 0x60, 0x3c, 0x78, 0x24, 0x30, 0x61, 0x63, 0x80, 0x78, 0x40, 0x60,
0x1f, 0xf9, 0x03, 0x06, 0x00, 0x60, 0x38, 0x3c, 0x24, 0x30, 0x61, 0x63, 0xc0, 0x70, 0x40, 0x60,
0x3f, 0xf8, 0x02, 0x02, 0x00, 0x60, 0x38, 0x38, 0x24, 0x30, 0x61, 0xe3, 0xc0, 0x60, 0x42, 0x60,
0x20, 0x08, 0x06, 0x01, 0x00, 0x60, 0x38, 0x30, 0x24, 0x30, 0x61, 0xe3, 0x00, 0x70, 0x5a, 0x60,
0x26, 0x4f, 0xff, 0x01, 0x00, 0x60, 0x38, 0x30, 0x7e, 0x30, 0x61, 0xe3, 0x00, 0x70, 0xd2, 0x60,
0x24, 0x4c, 0x03, 0x01, 0x80, 0x60, 0x3c, 0x30, 0x4e, 0x30, 0x60, 0xc3, 0x00, 0x78, 0xd2, 0x60,
0x20, 0x0c, 0x03, 0x01, 0x80, 0x30, 0x34, 0x30, 0xc6, 0x30, 0x60, 0xc3, 0x00, 0x58, 0xd2, 0x60,
0x20, 0x08, 0x01, 0x81, 0xc0, 0x30, 0x36, 0x30, 0xc6, 0x30, 0x60, 0xc3, 0x00, 0x5c, 0x42, 0x60,
0x26, 0x48, 0x81, 0xff, 0xc0, 0x1b, 0x36, 0x70, 0xc2, 0x30, 0x60, 0xc3, 0x00, 0x4c, 0x64, 0x70,
0x24, 0x48, 0x01, 0x80, 0xc0, 0x0f, 0x37, 0x7d, 0xc2, 0x30, 0xf0, 0x83, 0xe0, 0x66, 0x3c, 0x7e,
0x20, 0x08, 0x01, 0x82, 0xc0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x01, 0xc0, 0x00, 0x10, 0x3c,
0x30, 0x18, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3f, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 784)
const int Mi_LogoallArray_LEN = 1;
const unsigned char* Mi_LogoallArray[1] = {
Mi_Logologo
};
//**Setup
void setup() {
pinMode(pulsador, INPUT_PULLUP); //el pin pulsador es asignado como entrada
pinMode(despulsador, INPUT_PULLUP); //el pin pulsador es asignado como entrada
pinMode(pulsador_veneno, INPUT_PULLUP); //el pin pulsador es asignado como entrada
pinMode(pulsador_veneno_negativo, INPUT_PULLUP); //el pin pulsador es asignado como entrada
pinMode(pulsador_COM1, INPUT_PULLUP); //el pin pulsador es asignado como entrada
pinMode(pulsador_COM1n, INPUT_PULLUP); //el pin pulsador es asignado como entrada
pinMode(pulsador_COM2, INPUT_PULLUP); //el pin pulsador es asignado como entrada
pinMode(pulsador_COM2n, INPUT_PULLUP); //el pin pulsador es asignado como entrada
pinMode(pulsador_COM3, INPUT_PULLUP); //el pin pulsador es asignado como entrada
pinMode(pulsador_COM3n, INPUT_PULLUP); //el pin pulsador es asignado como entrada
delay(100); // se da una espera de 100ms para que el display inicie correctamente
Wire.begin(); // inicializa bus I2C
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // inicializa pantalla con direccion 0x3C
oled.clearDisplay(); // limpia pantalla
oled.drawBitmap(0, 17, Mi_Logologo, 128, 32, WHITE);
oled.display();
delay(2000); // se da una espera de 100ms para que el display inicie correctamente
oled.setRotation(0); // se escoje la orientacion del display puede ser 0, 1, 2 o 3
oled.setTextColor(WHITE); // se le dice a la pantalla que el texto que se va a desplegar es en color blanco
oled.dim(false); //dejamos el brillo en maximo
oled.setTextSize(2); // establece tamano de texto en 2
oled.clearDisplay(); // limpia pantalla
}
void loop() {
//..Vida
//SUMA vida
estPulActual = digitalRead(pulsador); //se lee el valor logico del pin de entraday se guarda en la variable estPulActual
if ((estPulAnterior == 1 && estPulActual == 0) || valor_actual == -1) { //valida si el pulsador ha cambiado de 1 a 0 ó si el contador esta en -1
valor_actual++; // suma 1 al valor de la variable contador
if (valor_actual > 99) { // si el contador supera 99
valor_actual = 0; // devuelve el contador a 0
}
}
delay(20); //pausa de 20 milisegundos
estPulAnterior = estPulActual; //el valor booleano actual del contador ya fue procesado asi que se guarda en la variable estPulAnterior
//RESTA vida
estPulActual = digitalRead(despulsador); //se lee el valor logico del pin de entraday se guarda en la variable estPulActual
if ((estPulAnterior == 1 && estPulActual == 0) || valor_actual == -1) { //valida si el pulsador ha cambiado de 1 a 0 ó si el contador esta en -1
valor_actual--; // resta 1 al valor de la variable contador
if (valor_actual < 0) { // si el contador supera 99
valor_actual = 99; // devuelve el contador a 0
}
}
delay(20); //pausa de 20 milisegundos
estPulAnterior = estPulActual; //el valor booleano actual del contador ya fue procesado asi que se guarda en la variable estPulAnterior
//..Veneno
//SUMA veneno
estVenActual = digitalRead(pulsador_veneno); //se lee el valor logico del pin de entraday se guarda en la variable estVenActual
if ((estVenAnterior == 1 && estVenActual == 0) || valor_actual_veneno == -1) { //valida si el pulsador ha cambiado de 1 a 0 ó si el contador esta en -1
valor_actual_veneno++; // suma 1 al valor de la variable contador
if (valor_actual_veneno > 10) { // si el contador supera 10
valor_actual_veneno = 0; // devuelve el contador a 0
}
}
delay(20); //pausa de 20 milisegundos
estVenAnterior = estVenActual; //el valor booleano actual del contador ya fue procesado asi que se guarda en la variable estVenAnterior
//RESTA veneno
estVenActual = digitalRead(pulsador_veneno_negativo); //se lee el valor logico del pin de entraday se guarda en la variable estVenActual
if ((estVenAnterior == 1 && estVenActual == 0) || valor_actual_veneno == -1) { //valida si el pulsador ha cambiado de 1 a 0 ó si el contador esta en -1
valor_actual_veneno--; // resta 1 al valor de la variable contador
if (valor_actual_veneno < 0) { // si el contador menor a 0
valor_actual_veneno = 10; // devuelve el contador a 10
}
}
delay(20); //pausa de 20 milisegundos
estVenAnterior = estVenActual; //el valor booleano actual del contador ya fue procesado asi que se guarda en la variable estPulAnterior
//..Comandantes
//COM1
//SUMA puntos
estCOM1Actual = digitalRead(pulsador_COM1); //se lee el valor logico del pin de entraday se guarda en la variable estPulActual
if ((estCOM1Anterior == 1 && estCOM1Actual == 0) || valor_actual_COM1 == -1) { //valida si el pulsador ha cambiado de 1 a 0 ó si el contador esta en -1
valor_actual_COM1++; // suma 1 al valor de la variable contador
if (valor_actual_COM1 > 21) { // si el contador supera 99
valor_actual_COM1 = 0; // devuelve el contador a 0
}
}
delay(20); //pausa de 20 milisegundos
estCOM1Anterior = estCOM1Actual; //el valor booleano actual del contador ya fue procesado asi que se guarda en la variable estPulAnterior
//RESTA puntos
estCOM1Actual = digitalRead(pulsador_COM1n); //se lee el valor logico del pin de entraday se guarda en la variable estPulActual
if ((estCOM1Anterior == 1 && estCOM1Actual == 0) || valor_actual_COM1 == -1) { //valida si el pulsador ha cambiado de 1 a 0 ó si el contador esta en -1
valor_actual_COM1--; // resta 1 al valor de la variable contador
if (valor_actual_COM1 < 0) { // si el contador supera 99
valor_actual_COM1 = 21; // devuelve el contador a 0
}
}
delay(20); //pausa de 20 milisegundos
estCOM1Anterior = estCOM1Actual; //el valor booleano actual del contador ya fue procesado asi que se guarda en la variable estPulAnterior
//COM2
//SUMA puntos
estCOM2Actual = digitalRead(pulsador_COM2); //se lee el valor logico del pin de entraday se guarda en la variable estPulActual
if ((estCOM2Anterior == 1 && estCOM2Actual == 0) || valor_actual_COM2 == -1) { //valida si el pulsador ha cambiado de 1 a 0 ó si el contador esta en -1
valor_actual_COM2++; // suma 1 al valor de la variable contador
if (valor_actual_COM2 > 21) { // si el contador supera 99
valor_actual_COM2 = 0; // devuelve el contador a 0
}
}
delay(20); //pausa de 20 milisegundos
estCOM2Anterior = estCOM2Actual; //el valor booleano actual del contador ya fue procesado asi que se guarda en la variable estPulAnterior
//RESTA puntos
estCOM2Actual = digitalRead(pulsador_COM2n); //se lee el valor logico del pin de entraday se guarda en la variable estPulActual
if ((estCOM2Anterior == 1 && estCOM2Actual == 0) || valor_actual_COM2 == -1) { //valida si el pulsador ha cambiado de 1 a 0 ó si el contador esta en -1
valor_actual_COM2--; // resta 1 al valor de la variable contador
if (valor_actual_COM2 < 0) { // si el contador supera 99
valor_actual_COM2 = 21; // devuelve el contador a 0
}
}
delay(20); //pausa de 20 milisegundos
estCOM2Anterior = estCOM2Actual; //el valor booleano actual del contador ya fue procesado asi que se guarda en la variable estPulAnterior
//COM3
//SUMA puntos
estCOM3Actual = digitalRead(pulsador_COM3); //se lee el valor logico del pin de entraday se guarda en la variable estPulActual
if ((estCOM3Anterior == 1 && estCOM3Actual == 0) || valor_actual_COM3 == -1) { //valida si el pulsador ha cambiado de 1 a 0 ó si el contador esta en -1
valor_actual_COM3++; // suma 1 al valor de la variable contador
if (valor_actual_COM3 > 21) { // si el contador supera 99
valor_actual_COM3 = 0; // devuelve el contador a 0
}
}
delay(20); //pausa de 20 milisegundos
estCOM3Anterior = estCOM3Actual; //el valor booleano actual del contador ya fue procesado asi que se guarda en la variable estPulAnterior
//RESTA puntos
estCOM3Actual = digitalRead(pulsador_COM3n); //se lee el valor logico del pin de entraday se guarda en la variable estPulActual
if ((estCOM3Anterior == 1 && estCOM3Actual == 0) || valor_actual_COM3 == -1) { //valida si el pulsador ha cambiado de 1 a 0 ó si el contador esta en -1
valor_actual_COM3--; // resta 1 al valor de la variable contador
if (valor_actual_COM3 < 0) { // si el contador supera 99
valor_actual_COM3 = 21; // devuelve el contador a 0
}
}
delay(20); //pausa de 20 milisegundos
estCOM3Anterior = estCOM3Actual; //el valor booleano actual del contador ya fue procesado asi que se guarda en la variable estPulAnterior
//**Impresion de pantalla
//Campos
oled.drawRect(0, 17, 30, 30, WHITE); // dibuja rectangulo X, Y, Pixel de alto , Pixel de ancho
oled.drawRect(31, 17, 30, 30, WHITE); // dibuja rectangulo X, Y, Pixel de alto , Pixel de ancho
oled.drawTriangle(62, 17, 92, 17, 77, 47, WHITE); //(FirstX , FirstY, SecondX, SecondY, ThirdX, ThirdY, WHITE);
oled.drawTriangle(79, 47, 94, 17, 110, 47, WHITE); //(FirstX , FirstY, SecondX, SecondY, ThirdX, ThirdY, WHITE);
oled.drawTriangle(96, 17, 127, 17, 112, 47, WHITE); //(FirstX , FirstY, SecondX, SecondY, ThirdX, ThirdY, WHITE);
//Titulos
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(2, 0);
oled.println("LIFE");
oled.setCursor(31, 0);
oled.println("VENOM");
oled.setCursor(69, 0);
oled.println("COMMANDER");
oled.setCursor(74, 9);
oled.println("1");
oled.setCursor(92, 9);
oled.println("2");
oled.setCursor(109, 9);
oled.println("3");
//Impresion de valores Vida y Veneno
oled.setTextSize(2);
oled.setTextColor(WHITE);
oled.setCursor(3, 25); // ubica cursor en coordenadas 15,32
oled.print(valor_actual); // escribe texto
oled.setCursor(34, 25); // ubica cursor en coordenadas 34,25
oled.print(valor_actual_veneno); // escribe texto
//Impresion de valores COM1/2/3
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(74, 22); // ubica cursor en coordenadas 34,25
oled.print(valor_actual_COM1); // escribe texto
oled.setCursor(92, 35); // ubica cursor en coordenadas 34,25
oled.print(valor_actual_COM2); // escribe texto
oled.setCursor(109, 22); // ubica cursor en coordenadas 34,25
oled.print(valor_actual_COM3); // escribe texto
oled.display(); // muestra en pantalla todo lo establecido anteriormente
}
Desde ya, muchas gracias a la comunidad por el espacio.
Saludos!