#include <U8x8lib.h>
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE, /* clock=*/ A5, /* data=*/ A4);
// U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
const int BUTTON_MENU = 12;
const int BUTTON_UP = 4;
const int BUTTON_DOWN = 8;
bool updateScreen = true;
// Variables para controlar el estado del menú
int currentMenu = 0; // Índice del menú actual
int currentScreen = 0; // Índice de la pantalla actual dentro del menú
int currentOption = 0; // Índice de la opcion actual dentro del submenú
// Variables de configuración
int tamGota = 300; // 300 por defecto aumenta 50
float altAplicacion = 2; // 2.5 por defecto aumenta 0,5
const char* TITLE = "ZenSur";
// Tipo de datos para el renderizador de pantalla
typedef void (*ScreenRenderer)();
// Enumeraciones para indexar los menús, pantallas y opciones
enum MenuIndex {
MENU_1,
MENU_2,
MENU_3
};
enum ScreenIndex {
SCREEN_1,
SCREEN_2
};
enum OptionIndex {
OPTION_1,
OPTION_2,
OPTION_3
};
// Función para renderizar el título en la pantalla
void renderTitle() {
u8x8.clearDisplay();
u8x8.setFont(u8x8_font_amstrad_cpc_extended_f);
u8x8.setCursor(0, 0);
u8x8.setInverseFont(1);
u8x8.print(" ");
int titleStartX = (u8x8.getCols() - strlen(TITLE)) / 2;
u8x8.setCursor(titleStartX, 0);
u8x8.print(TITLE);
u8x8.print(" ");
u8x8.setInverseFont(0);
}
// Función para imprimir la altura de aplicación en la pantalla
void printAltAplicacion(){
int altAplicacionInt = altAplicacion * 10; // Multiplica por 10 para obtener un número entero
int decimal = altAplicacionInt % 10; // Obtiene el dígito decimal
u8x8.print(altAplicacionInt / 10); // Imprime la parte entera
u8x8.print("."); // Imprime el punto decimal
u8x8.print(decimal); // Imprime el dígito decimal
u8x8.print("mts");
}
void renderMenu1Screen1() {
// Serial.println("M1 - P1");
u8x8.clearDisplay();
u8x8.setFont(u8x8_font_amstrad_cpc_extended_f);
renderTitle();
u8x8.setCursor(0, 1);
u8x8.print("Com: Ok");
u8x8.setCursor(0, 2);
u8x8.print("Temp: 20");
u8x8.write(0xB0);
u8x8.print("C");
u8x8.setCursor(0, 3);
u8x8.print("HR: 68%");
u8x8.setCursor(0, 4);
u8x8.print("DeltaT: 3.3");
u8x8.write(0xB0);
u8x8.print("C");
u8x8.setCursor(0, 5);
u8x8.print("Viento: 8 Km/h");
u8x8.setCursor(0, 6);
u8x8.print("Dir: 218");
u8x8.write(0xB0);
u8x8.setCursor(0, 7);
u8x8.print("Bat: 89%");
}
void renderMenu1Screen2() {
// Serial.println("M1 - P2");
u8x8.clearDisplay();
u8x8.setFont(u8x8_font_amstrad_cpc_extended_f);
renderTitle();
u8x8.setCursor(0, 2);
u8x8.print("T Vida: 2 min");
u8x8.setCursor(0, 4);
u8x8.print("T Caida: 10 seg");
u8x8.setCursor(0, 6);
u8x8.print("Max Deriv: 15mts");
}
void renderMenu2Screen1() {
// Serial.println("M2 - P1");
u8x8.clearDisplay();
u8x8.setFont(u8x8_font_amstrad_cpc_extended_f);
renderTitle();
// Opciones del menú
u8x8.setCursor(0, 2);
if (currentOption == OPTION_1) {
u8x8.print(">");
} else {
u8x8.print(" ");
}
u8x8.print("Tam Gota: ");
u8x8.print(tamGota);
u8x8.print("um");
u8x8.setCursor(0, 4);
if (currentOption == OPTION_2) {
u8x8.print(">");
} else {
u8x8.print(" ");
}
u8x8.print("Alt: ");
printAltAplicacion();
u8x8.setCursor(0, 6);
if (currentOption == OPTION_3) {
u8x8.print(">");
} else {
u8x8.print(" ");
}
u8x8.print("Volver");
}
void renderMenu3Screen1() {
// Serial.println("M3 - P1");
u8x8.clearDisplay();
u8x8.setFont(u8x8_font_amstrad_cpc_extended_f);
renderTitle();
u8x8.setCursor(0, 2);
u8x8.print(" ");
u8x8.print("Tam Gota:");
u8x8.print(" ");
u8x8.setCursor(0, 4);
u8x8.print(" ");
u8x8.print(tamGota);
u8x8.print("um");
u8x8.print(" ");
}
void renderMenu3Screen2() {
// Serial.println("M3 - P2");
u8x8.clearDisplay();
u8x8.setFont(u8x8_font_amstrad_cpc_extended_f);
renderTitle();
u8x8.setCursor(0, 2);
u8x8.print(" ");
u8x8.print("Alt: ");
u8x8.print(" ");
u8x8.setCursor(0, 4);
u8x8.print(" ");
printAltAplicacion();
u8x8.print(" ");
}
// Menus y pantallas
ScreenRenderer menus[][3] = {
{renderMenu1Screen1, renderMenu1Screen2},
{renderMenu2Screen1},
{renderMenu3Screen1, renderMenu3Screen2}
};
void nextScreen() {
// tamanio de gota
if(currentMenu == MENU_3 && currentScreen == SCREEN_1){
tamGota += 50;
return;
}
// altura de aplicacion
if(currentMenu == MENU_3 && currentScreen == SCREEN_2){
altAplicacion += 0.5;
return;
}
// si estamos en el menu 2 pantalla 1 manejamos las opciones internas
if (currentMenu == MENU_2 && currentScreen == SCREEN_1) {
currentOption++;
if (currentOption > OPTION_3) {
currentOption = 0; // Asegurarse de que el índice de opción no supere el máximo
}
return;
}
currentScreen++;
if (currentScreen >= sizeof(menus[currentMenu]) / sizeof(menus[currentMenu][0])) {
currentScreen = 0;
if (currentMenu == sizeof(menus) / sizeof(menus[0]) - 1) {
currentMenu = 0;
}
}
}
void previousScreen() {
// tamanio de gota
if(currentMenu == MENU_3 && currentScreen == SCREEN_1){
tamGota -= 50;
return;
}
// altura de aplicacion
if(currentMenu == MENU_3 && currentScreen == SCREEN_2){
altAplicacion -= 0.5;
return;
}
if (currentMenu == MENU_2) {
currentOption--;
if (currentOption < OPTION_1) {
currentOption = OPTION_3; // si el índice de opción supera el mínimo volvemos a la última opción
}
return;
}
currentScreen--;
if (currentMenu == MENU_1 && currentScreen < SCREEN_1) {
currentScreen = sizeof(menus[currentMenu]) / sizeof(menus[currentMenu][0]) - 1;
}
else if (currentScreen < SCREEN_1) {
if (currentMenu == MENU_1) {
currentMenu = sizeof(menus) / sizeof(menus[0]) - 1;
}
else {
currentMenu--;
}
currentScreen = sizeof(menus[currentMenu]) / sizeof(menus[currentMenu][0]) - 1;
}
}
void nextMenu() {
// si selecciona "volver" cargar el menu 2 pantalla 1
if (currentMenu == MENU_2 && currentOption == OPTION_3) {
currentMenu = MENU_1;
currentScreen = SCREEN_1;
currentOption = OPTION_1; // Reiniciar el índice de opción al cambiar de menú
return;
}
// si selecciona "tam gota" cargar el menu 2 pantalla 1
if (currentMenu == MENU_2 && currentOption == OPTION_1) {
currentMenu = MENU_3;
currentScreen = SCREEN_1;
currentOption = OPTION_1; // Reiniciar el índice de opción al cambiar de menú
return;
}
// si selecciona "alt aplic" cargar el menu 2 pantalla 1
if (currentMenu == MENU_2 && currentOption == OPTION_2) {
currentMenu = MENU_3;
currentScreen = SCREEN_2;
currentOption = OPTION_1; // Reiniciar el índice de opción al cambiar de menú
return;
}
// si estamos en el sub menu de apli
if(currentMenu == MENU_3 && currentScreen == SCREEN_2){
currentMenu = MENU_2;
currentScreen = SCREEN_1;
currentOption = OPTION_1; // Reiniciar el índice de opción al cambiar de menú
return;
}
// si estamos en el sub menu de gota
if(currentMenu == MENU_3 && currentScreen == SCREEN_1){
currentMenu = MENU_2;
currentScreen = SCREEN_1;
currentOption = OPTION_1; // Reiniciar el índice de opción al cambiar de menú
return;
}
currentMenu++;
if (currentMenu >= sizeof(menus) / sizeof(menus[0])) {
currentMenu = MENU_1;
}
currentScreen = SCREEN_1;
}
void renderCurrentScreen() {
menus[currentMenu][currentScreen]();
}
void setup() {
u8x8.begin();
pinMode(BUTTON_MENU, INPUT_PULLUP);
pinMode(BUTTON_UP, INPUT_PULLUP);
pinMode(BUTTON_DOWN, INPUT_PULLUP);
// Serial.begin(9600);
}
void loop() {
int btnMenu = digitalRead(BUTTON_MENU);
int btnNext = digitalRead(BUTTON_UP);
int btnPrev = digitalRead(BUTTON_DOWN);
if (btnMenu == LOW) {
nextMenu();
// Serial.println("Botón MENU presionado");
updateScreen = true;
}
if (btnNext == LOW) {
// Serial.println("Botón UP presionado");
nextScreen();
updateScreen = true;
}
if (btnPrev == LOW) {
// Serial.println("Botón DOWN presionado");
previousScreen();
updateScreen = true;
}
if(updateScreen){
renderCurrentScreen();
updateScreen = false;
}
// delay(1000);
}