#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Keypad.h>
#include <ESP32Servo.h>
#define ANCHO 128
#define ALTO 64
#define OLED_RESET 4
Adafruit_SSD1306 oled(ANCHO, ALTO, &Wire, OLED_RESET);
const byte FILAS = 4;
const byte COLUMNAS = 4;
char keys[FILAS][COLUMNAS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte pinesFilas[FILAS] = {19,18,5,17};
byte pinesColumnas[COLUMNAS] = {16, 4, 0, 2};
Keypad teclado = Keypad(makeKeymap(keys), pinesFilas, pinesColumnas, FILAS, COLUMNAS);
char tecla; // Variable de teclado
int Contador_desplazamiento = 0; // Contador de desplazamiento de pantalla
String Id_pantalla = "MPrincipal"; // Identificador de pantalla actual
int Contador_pulsador = 0; // Contador de pulsador
// Pines
#define Pulsador_pin 25
#define Switch1_pin 35
#define Switch2_pin 32
#define Switch3_pin 34
#define LED1_pin 27
#define Buzzer_pin 15
#define Rele_pin 14
#define Servo_pin 23
#define Pot_pin 33
#define LED2_pin 26
#define NuevoBoton_pin 13 // Pin del nuevo botón
Servo servo1;
int PULSOMIN = 800; // Pulso mínimo de servomotor
int PULSOMAX = 2500; // Pulso máximo de servomotor
bool ReleIntermitencia = false;
bool ReleON;
unsigned long lastTimeSinceExecuting; //Variable para la intermitencia del rele
int ANGULO = 0; // Inicia el valor del ángulo en 0
void Mostrar (String menu[], int n) { // Función que muestra el menú en la pantalla
oled.setCursor(0, 0);
if (n > 2) {
for (int i = 0; i < 3; i++) { // Muestra solo tres elementos a la vez
oled.print(Contador_desplazamiento + i + 1);
oled.print(".");
oled.println(menu[Contador_desplazamiento + i]);
}
} else {
for (int i = 0; i < 2; i++) { // Muestra solo tres elementos a la vez
oled.print(Contador_desplazamiento + i + 1);
oled.print(".");
oled.println(menu[Contador_desplazamiento + i]);
}
}
}
void Desplazamiento (int n, int elementos) { // Función para desplazar el menú
switch (tecla) {
case 'A':
// Desplaza hacia arriba si el contador es mayor a 0
if (Contador_desplazamiento > 0) {
Contador_desplazamiento--;
}
break;
case 'B':
// Desplaza hacia abajo si el contador es menor al tamaño del vector menos los elementos mostrados en pantalla
if (Contador_desplazamiento < n - elementos) {
Contador_desplazamiento++;
}
break;
}
}
void setup() {
Serial.begin(9600);
Wire.begin(21, 22);
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
pinMode(Switch1_pin, INPUT); // Switch 1
pinMode(Switch2_pin, INPUT); // Switch 2
pinMode(Switch3_pin, INPUT); // Switch 3
pinMode(Pulsador_pin, INPUT); // Pulsador
pinMode(NuevoBoton_pin, INPUT); // Nuevo botón
pinMode(LED1_pin, OUTPUT); // LED 1
pinMode(Buzzer_pin, OUTPUT); // Buzzer
pinMode(Rele_pin, OUTPUT); // Relé
servo1.attach(Servo_pin, PULSOMIN, PULSOMAX);
servo1.write(ANGULO); // Inicia el servomotor con 0 grados
}
void loop() {
int Pulsador = digitalRead(Pulsador_pin); // Lee el estado del pulsador
int Estado_SW1 = digitalRead(Switch1_pin); // Lee el estado del switch 1
int Estado_SW2 = digitalRead(Switch2_pin); // Lee el estado del switch 2
int Estado_SW3 = digitalRead(Switch3_pin); // Lee el estado del switch 2
int Valor_pot = analogRead(Pot_pin); // Lee el valor del potenciómetro
int Velocidad_pot = map(Valor_pot, 0, 4095, 0, 100); // Mapea el valor del potenciómetro al rango 0 - 100
int nuevoPulsador = digitalRead(NuevoBoton_pin);
if (Pulsador == 1) { // Pulsador se presiona
Contador_pulsador++; // Aumenta el contador del pulsador
digitalWrite(Buzzer_pin, HIGH); // Buzzer emite sonido
delay(200);
digitalWrite(Buzzer_pin, LOW);
}
if(nuevoPulsador == 1 && ANGULO != 90){
ANGULO = 90;
servo1.write(ANGULO);
}
// Control de brillo de LED2
dacWrite(LED2_pin, Valor_pot / 16); // Escribe valores entre 0 y 255
if (Estado_SW2 == 0) { // MODO LOCAL
oled.clearDisplay(); // Limpia pantalla
oled.setTextColor(WHITE);
oled.setTextSize(2);
digitalWrite(LED1_pin, 1); // Enciende led
tecla = teclado.getKey(); // Obtiene la tecla presionada
Serial.println(tecla);
// Vectores donde se almacenan los menús
String Menu_Principal[5] = {"Entradas", "Salidas", "Fecha y hora", "Memoria", "Motor"};
String Menu_Entradas[3] = {"Switch 1", "Contador", "Vel"};
String Menu_Salidas[2] = {"Rele", "Servo"}; //Anadir Intermitencia
String Menu_Rele[3] = {"ON", "OFF", "Intermitencia"};
String Menu_Servo[2] = {"+10 grados", "-10 grados"};
String Menu_Memoria[2] = {"Historico pulsador", "Borrado de memoria"};
String Menu_Motor[4] = {"ON", "OFF", "Giro L", "Giro R"};
// Cambios de identificador de pantalla según la tecla presionada
switch (tecla) { // Tecla es presionada
case '1':
Contador_desplazamiento = 0;
if (Id_pantalla == "MPrincipal") {
Id_pantalla = "MEntradas";
} else if (Id_pantalla == "MEntradas") {
Id_pantalla = "MSwitch1";
} else if (Id_pantalla == "MSalidas") {
Id_pantalla = "MRele";
} else if (Id_pantalla == "MMemoria") {
Id_pantalla = "MHistorico";
} else if (Id_pantalla == "MMotor") {
} else if (Id_pantalla == "MRele") {
digitalWrite(Rele_pin, 1);
} else if (Id_pantalla == "MServo") {
if(ANGULO <= 170) {
ANGULO += 10;
servo1.write(ANGULO);
}
}else if(Id_pantalla == "MReleInter"){
if(!ReleIntermitencia){
ReleIntermitencia = true;
lastTimeSinceExecuting = millis();
ReleON = true;
digitalWrite(Rele_pin, ReleON? 1: 0);
}
}
break;
case '2':
Contador_desplazamiento = 0;
if (Id_pantalla == "MPrincipal") {
Id_pantalla = "MSalidas";
} else if (Id_pantalla == "MEntradas") {
Id_pantalla = "MContador";
} else if (Id_pantalla == "MSalidas") {
Id_pantalla = "MServo";
} else if (Id_pantalla == "MMemoria") {
} else if (Id_pantalla == "MMotor") {
} else if (Id_pantalla == "MRele") {
digitalWrite(Rele_pin, 0);
} else if (Id_pantalla == "MServo") {
if(ANGULO >= 10) {
ANGULO -= 10;
servo1.write(ANGULO);
}
}else if(Id_pantalla == "MReleInter"){
ReleIntermitencia = false;
}
break;
case '3':
Contador_desplazamiento = 0;
if (Id_pantalla == "MPrincipal") {
Id_pantalla = "MFecha";
} else if (Id_pantalla == "MEntradas") {
Id_pantalla = "MVelocidad";
} else if (Id_pantalla == "MMotor") {
}else if(Id_pantalla == "MSalidas"){
Id_pantalla = "MReleInter";
}
break;
case '4':
Contador_desplazamiento = 0;
if (Id_pantalla == "MPrincipal") {
Id_pantalla = "MMemoria";
} else if (Id_pantalla == "MMotor") {
}
break;
case '5':
Contador_desplazamiento = 0;
if(Id_pantalla == "MPrincipal") {
Id_pantalla = "MMotor";
}
break;
case 'C':
Contador_desplazamiento = 0;
if (Id_pantalla == "MEntradas" || Id_pantalla == "MSalidas" || Id_pantalla == "MFecha" || Id_pantalla == "MMemoria" || Id_pantalla == "MMotor") {
Id_pantalla = "MPrincipal";
} else if (Id_pantalla == "MSwitch1" || Id_pantalla == "MContador" || Id_pantalla == "MVelocidad") {
Id_pantalla = "MEntradas";
} else if (Id_pantalla == "MRele" || Id_pantalla == "MServo") {
Id_pantalla = "MSalidas";
} else if (Id_pantalla == "MHistorico") {
Id_pantalla = "MMemoria";
} else if(Id_pantalla == "MReleInter"){
Id_pantalla = "MSalidas";
}
break;
}
if (Id_pantalla == "MPrincipal") {
Mostrar (Menu_Principal, 5);
Desplazamiento(5, 3); // Tamaño del vector es 5 y los elementos mostrados en pantalla 3
} else if (Id_pantalla == "MEntradas") {
Mostrar (Menu_Entradas, 3);
Desplazamiento(3, 3);
} else if (Id_pantalla == "MSalidas") {
Mostrar (Menu_Salidas, 3);
} else if (Id_pantalla == "MFecha") {
} else if (Id_pantalla == "MMemoria") {
Mostrar (Menu_Memoria, 2);
} else if (Id_pantalla == "MMotor") {
Mostrar (Menu_Motor, 4);
Desplazamiento(4, 3);
} else if (Id_pantalla == "MSwitch1") {
oled.setCursor(45, 20);
if (Estado_SW1 == 0) {
oled.print("OFF");
} else {
oled.print("ON");
}
} else if (Id_pantalla == "MContador") {
oled.setCursor(45, 20);
oled.print(Contador_pulsador);
} else if (Id_pantalla == "MVelocidad") {
oled.setCursor(45, 20);
oled.print(Velocidad_pot);
} else if (Id_pantalla == "MRele") {
Mostrar (Menu_Rele, 3);
} else if (Id_pantalla == "MServo") {
Mostrar (Menu_Servo, 2);
} else if (Id_pantalla == "MHistorico") {
}else if(Id_pantalla == "MReleInter"){
oled.setCursor(20, 0);
if (ReleIntermitencia) {
oled.print("ON");
} else {
oled.print("OFF");
}
oled.setCursor(20, 30);
oled.print("1. ON");
oled.setCursor(20, 50);
oled.print("2. OFF");
}
oled.display();
//Logica del Rele Intermitente
if(ReleIntermitencia){
if(millis() - lastTimeSinceExecuting > 5000){
ReleON = !ReleON;
lastTimeSinceExecuting = millis();
digitalWrite(Rele_pin, ReleON? 1: 0);
}
}
} else { // MODO REMOTO
Id_pantalla = "MPrincipal"; // Vuelve al menú principal
Contador_desplazamiento = 0; // Reinicia el contador de desplazamiento
digitalWrite(LED1_pin, 0); // Apaga el LED
oled.clearDisplay();
oled.setTextColor(WHITE);
oled.setTextSize(2);
oled.setCursor(0, 20);
if (Estado_SW3 == 0) {
oled.print("BLUETOOTH");
} else {
oled.print("WIFI");
}
oled.display();
}
}