#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <WiFi.h>
#include <NTPClient.h>
#include <EEPROM.h>
//////// logica botão ///////////////////
bool buttonState = HIGH; // Estado atual do botão ENTER
bool lastButtonState = HIGH; // Estado anterior do botão ENTER
bool buttonState1 = HIGH; // Estado atual do botão CIMA
bool lastButtonState1 = HIGH; // Estado anterior do botão CIMA
bool buttonState2 = HIGH; // Estado atual do botão BAIXO
bool lastButtonState2 = HIGH; // Estado anterior do botão BAIXO
bool buttonState3 = HIGH; // Estado atual do botão DIREITA
bool lastButtonState3 = HIGH; // Estado anterior do botão DIREITA
bool buttonState4 = HIGH; // Estado atual do botão ESQUERDA
bool lastButtonState4 = HIGH; // Estado anterior do botão ESQUERDA
bool CIMA=LOW;
bool BAIXO=LOW;
bool ESQUERDO=LOW;
bool DIREITA=LOW;
/////////////////////////////////////////
int valorGPIO32; // Lê o valor da porta analógica GPIO32
int valorGPIO33; // Lê o valor da porta analógica GPIO33
int valorGPIO34; // Lê o valor da porta analógica GPIO34
int valorGPIO35; // Lê o valor da porta analógica GPIO35
int valorGPIO36; // Lê o valor da porta analógica GPIO36
int valorGPIO39; // Lê o valor da porta analógica GPIO36
// Pin definitions for buttons
#define RL1 18
#define RL2 19
//GRAFICO
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
int xPos = 0; // Posição horizontal da linha
int lastValue = 0; // Valor anterior da entrada analógica
int graphData[OLED_WIDTH]; // Dados do gráfico
bool AL=0;
bool p18;//saida pino 18
int estado = 0;
int indice=0;
bool sobe = 0;
bool desce = 0;
int hora_on;
int hora_off;
int minuto_on;
int minuto_off;
int maior=0;
int menor=0;
int acelera=0;
int acelera1=0;
//HORA DA INTERNET
// Define the time offset for Brazil (GMT -3:00)
const int timeOffset = -3 * 60 * 60;
// Define the NTP server for Brazil
const char* ntpServer = "a.ntp.br";
// Create a WiFiUDP object to communicate with the NTP server
WiFiUDP ntpUDP;
// Create an NTPClient to get the time
NTPClient timeClient(ntpUDP, ntpServer, timeOffset);
// Get the current time from the NTP client
unsigned long epochTime = timeClient.getEpochTime();
struct tm* timeinfo;
char timeString[9]; // HH:MM:SS
char dateString[11]; // DD/MM/YYYY
int hora = 0;
int minuto = 0;
int segundo = 0;
int dia = 0;
int mes = 0; //
int ano = 0; //
///para salvar na EEPROM A DATA
int horaE = 0;
int minutoE = 0;
int diaE = 0;
int mesE = 0; //
int anoE = 0;
////////////////// clp /////////////////////////////////
int funsao;
int SET=0;
bool entrada;
bool in1 = HIGH; // Estado atual do botão ESQUERDA
bool lastin1= HIGH; // Estado anterior do botão ESQUERDA
int Cont=0;
bool TM=0;
int muda=0;
int O1=0;
int ent1=0;
int carre=250;//tempo para carregar a EEPROM
// Endereços da EEPROM onde os valores serão armazenados
int enderecoValor1 = 0;
int enderecoValor2 = sizeof(int);
int enderecoValor3 = 2 * sizeof(int);
int enderecoValor4 = 3 * sizeof(int);
int enderecoValor5 = 4 * sizeof(int);
int enderecoValor6 = 5 * sizeof(int);
int enderecoValor7 = 6 * sizeof(int);
int enderecoValor8 = 7 * sizeof(int);
int enderecoValor9 = 8 * sizeof(int);
int enderecoValor10 = 9 * sizeof(int);
int enderecoValor11 = 10 * sizeof(int);
int enderecoValor12 = 11 * sizeof(int);
int enderecoValor13 = 12 * sizeof(int);
int enderecoValor14 = 13 * sizeof(int);
int enderecoValor15 = 14 * sizeof(int);
int enderecoValor16 = 15 * sizeof(int);
//int enderecoValor17 = 16 * sizeof(int);
//int enderecoValor18 = 17 * sizeof(int);
// Endereços na EEPROM
#define SSID_ADDR 100//ENDEREÇO PARA REDE
#define PASS_ADDR 132 // Endereço após SSID (ajuste conforme necessário)
#define RELE_ADDR 164 //NOME SALVO NA MEMORIA
/////////////////////////////////////////
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// Pin definitions for buttons
#define UP_BUTTON_PIN 14
#define ENTER_BUTTON_PIN 12
#define DOWN_BUTTON_PIN 13
#define UP_BUTTON_PIN 14
#define DIREITA_BUTTON_PIN 27
#define ESQUERDA_BUTTON_PIN 26
#define BUTTON_SELECT 15 // Botão adicional para alternar entre SSID e senha
int edisao=0;
// Initialize the OLED display
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int menu=0;
// Menu options
const int NUM_OPTIONS = 16;
const char* menuOptions[NUM_OPTIONS] = {
"1-INICIAL",
"2-Conf. REDE WIFI",
"3-EDICAO NOMES ",
"4-AJUSTE FUNSAO CLP",
"5-AJUSTE SAIDA CLP",
"6-AJUSTE SET CLP",
"7-AJUSTE IN CLP",
"8-ALARMES",
"9-GRAFICO",
"10-Hora ON",
"11-Minuto ON",
"12-Hora OFF",
"13-Hinuto OFF",
"14-AJ.MAIOR",
"15-AJ.MENOR",
"16-SALVAR"
};
int selectedOption = 0;
int tentativas = 0; // Inicialize a variável tentativas
char RELE[32] = "rele1";//NOME DO RELE
// Variáveis para armazenar SSID e senha
char ssid[32] = " ";
char password[32] = " ";
char ssid1[32] = "Wokwi-GUEST";
char password1[32] = "";
// Índice de edição
int editIndex = 0;
bool editingSSID = true; // true = editando SSID, false = editando senha
bool scanning = true; // true = escaneando redes, false = editando SSID e senha
int numberOfNetworks = 0;
String networks[10];
int selectedNetwork = 0;
int temporeiniciar=0;
void setup() {
// Inicializa a comunicação serial a 9600 baud rate
Serial.begin(9600);
EEPROM.begin(512); // Inicializa a EEPROM com 512 bytes de tamanho
// Initialize the buttons as inputs with internal pull-ups
pinMode(UP_BUTTON_PIN, INPUT_PULLUP);
pinMode(ENTER_BUTTON_PIN, INPUT_PULLUP);
pinMode(DOWN_BUTTON_PIN, INPUT_PULLUP);
pinMode(DIREITA_BUTTON_PIN, INPUT_PULLUP);
pinMode(ESQUERDA_BUTTON_PIN, INPUT_PULLUP);
pinMode(BUTTON_SELECT, INPUT_PULLUP);
pinMode(RL1, OUTPUT);
pinMode(RL2, OUTPUT);
// Initialize the OLED display
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.display();
delay(2); // Pause for 2 seconds
// LEEPROM();//le informação da EEPROM
// Carrega SSID e senha da EEPROM
loadCredentials();
// Escaneia redes Wi-Fi
scanNetworks();
//############ tentativas de conexão ################
boolean conexaoEstabelecida = false;
//WiFi.begin("Wokwi-GUEST","");
WiFi.begin(ssid, password);//usado quando salvo na eeprom
while ((WiFi.status() != WL_CONNECTED)&&(tentativas<25)) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Carregando REDE");
display.print(tentativas);
display.println(" tentativas");
display.display();
tentativas++;
delay(250);
}
// Verifica se a conexão foi estabelecida
if (WiFi.status() == WL_CONNECTED) {
conexaoEstabelecida = true;
timeClient.begin();
timeClient.update();
}
while ((WiFi.status() != WL_CONNECTED)&&(temporeiniciar<100)){
redewifi();
temporeiniciar++;
display.setCursor(100, 50);
display.print(temporeiniciar);
display.display();
}
//########## fim da conexão ########################
if((WiFi.status() != WL_CONNECTED)){//sem conexão
selectedOption = 1;
estado=1;
}
/*
WiFi.begin("Wokwi-GUEST", "");
while (WiFi.status() != WL_CONNECTED) {
delay(250);
}*/
// Clear the display
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("CARREGANDO");
display.display();
// Inicializa os dados do gráfico
for (int i = 0; i < OLED_WIDTH; i++) {
graphData[i] = OLED_HEIGHT / 2;
}
//DADOS DA EEPROM
EEPROM.get(enderecoValor1, menor);
EEPROM.get(enderecoValor2, maior);
EEPROM.get(enderecoValor3, hora_on);
EEPROM.get(enderecoValor4, hora_off);
EEPROM.get(enderecoValor5, minuto_on);
EEPROM.get(enderecoValor6, minuto_off);
EEPROM.get(enderecoValor7, SET);
EEPROM.get(enderecoValor8, funsao);
EEPROM.get(enderecoValor9, O1);
EEPROM.get(enderecoValor10, horaE);
EEPROM.get(enderecoValor11, minutoE);
EEPROM.get(enderecoValor12, diaE);
EEPROM.get(enderecoValor13, mesE);
EEPROM.get(enderecoValor14, anoE);
//EEPROM.get(enderecoValor15, ssid);
//EEPROM.get(enderecoValor16, password);
}
void loop() {
//ZERA OS SINAIS DE BOTAO
CIMA=0;
BAIXO=0;
ESQUERDO=0;
DIREITA=0;
//
clp();
alarme();
comparador();
valorGPIO32 = analogRead(32); // Lê o valor da porta analógica GPIO32
valorGPIO33 = analogRead(33); // Lê o valor da porta analógica GPIO33
valorGPIO34 = analogRead(34); // Lê o valor da porta analógica GPIO34
valorGPIO35 = analogRead(35); // Lê o valor da porta analógica GPIO35
valorGPIO36 = analogRead(36); // Lê o valor da porta analógica GPIO39
valorGPIO39 = analogRead(39); // Lê o valor da porta analógica GPIO39
//HORA DA INTERNET
epochTime = timeClient.getEpochTime();
tm* timeinfo;
timeinfo = localtime((const time_t*)&epochTime);
snprintf(timeString, sizeof(timeString), "%02d:%02d:%02d", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
snprintf(dateString, sizeof(dateString), "%02d/%02d/%04d", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900);
hora = timeinfo->tm_hour ;
minuto = timeinfo->tm_min;
segundo= timeinfo->tm_sec;
dia = timeinfo->tm_mday;
mes = (timeinfo->tm_mon) + 1; // +1 porque tm_mon começa em zero
ano = (timeinfo->tm_year) + 1900; // +1900 porque tm_year é o número de anos desde 1900
//FIM HORA DA INTERNET
// Verifica se há dados disponíveis na entrada serial
if (Serial.available() > 0) {
String receivedText = Serial.readStringUntil('\n');// Lê a linha de texto recebida
receivedText.trim(); // Remove espaços em branco no início e no final
if (receivedText.equalsIgnoreCase(RELE)) { // Verifica se a mensagem recebida é "ON"
digitalWrite(RL1, HIGH); // Acende o LED
Serial.println("LED ligado");
}
// Verifica se a mensagem recebida é "OFF"
else if (receivedText.equalsIgnoreCase("OFF")) {
digitalWrite(RL1, LOW); // Apaga o LED
Serial.println("LED desligado");
}
// Responde para outras mensagens
else {
Serial.println("Comando desconhecido: " + receivedText);
}
}
/////////// FUNÇÃO BOTAO DIREITA //////////////////////////////
buttonState3 = digitalRead(DIREITA_BUTTON_PIN);//botão precionado
if (buttonState3 == LOW && lastButtonState3 == HIGH) {
// Gera um pulso
DIREITA=1;
}
lastButtonState3 = buttonState3;
/////////// FUNÇÃO BOTAO ESQUERDA //////////////////////////////
buttonState4 = digitalRead(ESQUERDA_BUTTON_PIN);//botão precionado
if (buttonState4 == LOW && lastButtonState4 == HIGH) {
// Gera um pulso
ESQUERDO=1;
// ESP.restart(); //reinicia o esp32
}
lastButtonState4 = buttonState4;
/////////// FUNÇÃO BOTAO SOBE //////////////////////////////
buttonState1 = digitalRead(UP_BUTTON_PIN);//botão precionado
if(buttonState1 == LOW){acelera++;}else {acelera=0;}
if ((buttonState1 == LOW && lastButtonState1 == HIGH)|| (acelera>10)) {
// Gera um pulso
CIMA=1;
sobe=1;
if(estado==0){
if (indice !=0){indice--;}//faz subir o menu
selectedOption = (selectedOption + NUM_OPTIONS - 1) % NUM_OPTIONS;
updateDisplay();}
}
else {sobe=0;}
lastButtonState1 = buttonState1;
//informação a ser alterada
////////////inicio do indice //////////////////////////////////
if (selectedOption==0)indice=0;//zera o indice para recomeçar
if (selectedOption==(NUM_OPTIONS-1))indice=(NUM_OPTIONS-7);//iguala o indice para não se perder
if (indice<1 || (selectedOption > NUM_OPTIONS)){indice =0;}
/////////// FUNÇÃO BOTAO DESCE //////////////////////////////
buttonState2 = digitalRead(DOWN_BUTTON_PIN);//botão precionado
if(buttonState2 == LOW){acelera1++;}else {acelera1=0;}
if ((buttonState2 == LOW && lastButtonState2 == HIGH)||(acelera1>10)) {
// Gera um pulso
BAIXO=1;
desce=1;
if(estado==0){
if (selectedOption>5){indice++;}//faz descer o menu
selectedOption = (selectedOption + 1) % NUM_OPTIONS;
updateDisplay();}
}
else {desce=0;}
lastButtonState2 = buttonState2;
/////// ////////função botão MENU /////////////////////////////////////
buttonState = digitalRead(ENTER_BUTTON_PIN);//botão precionado
if (estado == 1) {
handleMenuSelection();//MOSTRA MENU INICIAL
}
if (estado == 0) {updateDisplay();}
// Verifica se o botão foi pressionado
if (buttonState == LOW && lastButtonState == HIGH) {
// Gera um pulso
estado++;
editIndex=0;
}
if(estado>1) {estado=0; }
lastButtonState = buttonState;
}///////////////////////////////////////////////////////////////////
//###########FIM DO LOOP ##########################
void updateDisplay() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
for (int i = 0; i < NUM_OPTIONS; i++) {
if (i == selectedOption) {
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Highlight the selected option
} else {
display.setTextColor(SSD1306_WHITE);
}
display.setCursor(0, (i - indice)* 8);
display.println(menuOptions[i]);//MOSTRA MENU 1
}
display.display();
}
//##################################################
void handleMenuSelection() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
switch (selectedOption) {
case 0:{
display.clearDisplay();
display.setTextSize(1);//TAMANHO DA FONTE
display.setCursor(0, 0);
display.println(" Data e Hora (BR):");
display.setTextSize(2);//TAMANHO DA FONTE
display.setCursor(0, 42);
display.println(dateString);
display.setCursor(10, 16);
display.println(timeString);
break;}
case 1:{//ajuste de rede wifi
redewifi();
break;}
//função para editar palavras com IHM
case 2:{
display.clearDisplay(); // Limpe o display
display.setTextSize(1); // Defina o tamanho do texto
display.setTextColor(SSD1306_WHITE); // Defina a cor do texto
display.setCursor(0, 0); // Defina a posição do cursor
display.println("Editar nome RELE");
display.setCursor(2, 16);
display.print("-> ");
// Imprimir a string RELE com o caractere atual em inversão de cor
for (int i = 0; i < strlen(RELE); i++) {
if (i == editIndex) {display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Inverte as cores para o caractere atual
} else {display.setTextColor(SSD1306_WHITE);} // Define a cor padrão para os outros caracteres
display.print(RELE[i]);}
display.setTextColor(SSD1306_WHITE); // Restaura a cor padrão
// Lógica para editar os caracteres na string RELE
if (buttonState1 == 1) {if (RELE[editIndex] < 126) RELE[editIndex]++;}
if (buttonState2 == 1) {if (RELE[editIndex] > 32) RELE[editIndex]--;}
if (DIREITA == 1) {if (editIndex < strlen(RELE) - 1) editIndex++;}
if (ESQUERDO == 1) {if (editIndex > 0) editIndex--;}
//SALVA NA MEMORIA O NOME
if(editIndex==0 && ESQUERDO == 1){
display.setCursor(2, 56);
display.print("Salvando EEPROM");
int eepromIndex = RELE_ADDR;
for (int i = 0; i < 32; i++) {
if (RELE[i] != ' ' && RELE[i] != '\0') {
EEPROM.write(eepromIndex++, RELE[i]);
EEPROM.commit();}
}delay(100);
}
display.display(); // Atualize o display
break;}
case 3:{//ajuste função
display.clearDisplay(); // Limpa a tela
display.setCursor(2, 2);
display.println("Ajuste FUNCAO CLP");
display.setCursor(2, 16);
display.print("SET: ");
display.print(SET);
display.setCursor(2, 26);
display.print("Cont: ");
display.print(Cont);
display.setCursor(2, 56);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
if(funsao==0)display.println("Delay p/ ON DLYON");
if(funsao==1)display.println("Delay p/ OFF DLYOFF");
if(funsao==2)display.println("Tempo ligado TON");
if(funsao==3)display.println("Pulso PL");
if(funsao==4)display.println("loop LP");
if(funsao==5)display.println("Retensao ON/OFF");
if(funsao==6)display.println("SEM FUNCAO N/C");
display.setTextColor(SSD1306_WHITE); // Highlight the selected option
display.setCursor(2, 36);
display.print("saida:");
if(AL==1) display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
if(O1==0)display.print("RELE1");
if(O1==1)display.print("LED1");
if(O1==2)display.print("X2");
if(O1==3)display.print("X3");
display.setTextColor(SSD1306_WHITE);
display.setCursor(2, 46);
display.print("Entrada:");
if(in1==1)display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
if(ent1==0)display.print("Botao");
if(ent1==1)display.print("Y1");
if(ent1==2)display.print("Y2");
if(ent1==3)display.print("Y3");
display.setTextColor(SSD1306_WHITE);
display.setCursor(60, 26);
display.print("RL1 OUT:");
display.print(AL);
if(sobe==1)funsao++;
if(desce==1)funsao--;
if(funsao>6 || funsao<0) funsao=0;
break;}
case 4:{//ajuste saidas
display.clearDisplay(); // Limpa a tela
display.setCursor(2, 2);
display.println("Ajuste SAIDA CLP");
display.setCursor(2, 16);
display.print("SET: ");
display.print(SET);
display.setCursor(2, 26);
display.print("Cont: ");
display.print(Cont);
display.setCursor(2, 56);
if(funsao==0)display.println("Delay p/ ON DLYON");
if(funsao==1)display.println("Delay p/ OFF DLYOFF");
if(funsao==2)display.println("Tempo ligado TON");
if(funsao==3)display.println("Pulso PL");
if(funsao==4)display.println("loop LP");
if(funsao==5)display.println("Retensao ON/OFF");
if(funsao==6)display.println("SEM FUNCAO N/C");
display.setCursor(2, 36);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Highlight the selected option
display.print("saida:");
if(O1==0)display.print("RELE1");
if(O1==1)display.print("LED1");
if(O1==2)display.print("X2");
if(O1==3)display.print("X3");
display.setTextColor(SSD1306_WHITE); // Highlight the selected option
display.setCursor(60, 26);
display.print("RL1 OUT:");
display.print(AL);
display.setCursor(2, 46);
display.print("Entrada:");
if(in1==1)display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
if(ent1==0)display.print("Botao");
if(ent1==1)display.print("Y1");
if(ent1==2)display.print("Y2");
if(ent1==3)display.print("Y3");
display.setTextColor(SSD1306_WHITE);
if(sobe==1)O1++;
if(desce==1)O1--;
if(O1>3 || O1<0) O1=0;
break;}
case 5:{ //ajuste de SET
display.clearDisplay(); // Limpa a tela
display.setCursor(2, 2);
display.println("Ajuste SET CLP");
display.setCursor(2, 16);
display.print("SET: ");
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Highlight the selected option
display.print(SET);
display.setTextColor(SSD1306_WHITE); // Highlight the selected option
display.setCursor(2, 26);
display.print("Cont: ");
display.print(Cont);
display.setCursor(2, 56);
if(funsao==0)display.println("Delay p/ ON DLYON");
if(funsao==1)display.println("Delay p/ OFF DLYOFF");
if(funsao==2)display.println("Tempo ligado TON");
if(funsao==3)display.println("Pulso PL");
if(funsao==4)display.println("loop LP");
if(funsao==5)display.println("Retensao ON/OFF");
if(funsao==6)display.println("SEM FUNCAO N/C");
display.setCursor(2, 36);
display.print("saida:");
if(AL==1) display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
if(O1==0)display.print("RELE1");
if(O1==1)display.print("LED1");
if(O1==2)display.print("X2");
if(O1==3)display.print("X3");
display.setTextColor(SSD1306_WHITE);
display.setCursor(60, 26);
display.print("RL1 OUT:");
display.print(AL);
display.setCursor(2, 46);
display.print("Entrada:");
if(in1==1)display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
if(ent1==0)display.print("Botao");
if(ent1==1)display.print("Y1");
if(ent1==2)display.print("Y2");
if(ent1==3)display.print("Y3");
display.setTextColor(SSD1306_WHITE);
if(sobe==1)SET++;
if(desce==1)SET--;
break;}
case 6:{//ajuste de entrada
display.clearDisplay(); // Limpa a tela
display.setCursor(2, 2);
display.println("Ajuste entrada CLP");
display.setCursor(2, 16);
display.print("SET: ");
display.print(SET);
display.setTextColor(SSD1306_WHITE); // Highlight the selected option
display.setCursor(2, 26);
display.print("Cont: ");
display.print(Cont);
display.setCursor(2, 56);
if(funsao==0)display.println("Delay p/ ON DLYON");
if(funsao==1)display.println("Delay p/ OFF DLYOFF");
if(funsao==2)display.println("Tempo ligado TON");
if(funsao==3)display.println("Pulso PL");
if(funsao==4)display.println("loop LP");
if(funsao==5)display.println("Retensao ON/OFF");
if(funsao==6)display.println("SEM FUNCAO N/C");
display.setCursor(2, 36);
display.print("saida:");
if(AL==1) display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
if(O1==0)display.print("RELE1");
if(O1==1)display.print("LED1");
if(O1==2)display.print("X2");
if(O1==3)display.print("X3");
display.setTextColor(SSD1306_WHITE);
display.setCursor(60, 26);
display.print("RL1 OUT:");
display.print(AL);
display.setCursor(2, 46);
display.print("Entrada:");
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
if(ent1==0)display.print("Botao");
if(ent1==1)display.print("Y1");
if(ent1==2)display.print("Y2");
if(ent1==3)display.print("Y3");
display.setTextColor(SSD1306_WHITE);
if(sobe==1)ent1++;
if(desce==1)ent1--;
if(ent1>3 || ent1<0)ent1=0;
break;}
case 7:{
display.println("ALARMES");
// Handle settings menu actions
break;}
case 8:{
display.clearDisplay(); // Limpa a tela
display.setCursor(2, 2);
display.print(" Grafico ");
display.println(valorGPIO34);
display.drawRect(0,0,128,64, SSD1306_WHITE);//desenha quadrado
//( inicio > ,inicio v, tamanha horizontal, tamanho vertical,)
display.drawRect(0, menor, 128, 1, SSD1306_WHITE);//desenha linha
// Mapeia o valor lido para o intervalo do display OLED
int displayValue = map(valorGPIO34, 4095, 0,0, OLED_HEIGHT);
// Move o gráfico para a esquerda
for (int i = 1; i < OLED_WIDTH; i++) {
graphData[i - 1] = graphData[i];
}
// Adiciona o novo valor ao gráfico
graphData[OLED_WIDTH - 1] = displayValue;
drawGraph(); // Desenha o gráfico
display.display();// Atualiza o display
if(sobe==1)menor++;
if(desce==1)menor--;
break;}
case 9:{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Ajuste hora ON");
display.setCursor(2, 10);
display.print("AL.ON AL_OFF");
display.setCursor(1, 20);
display.println(hora_on);
display.setCursor(12, 20);
display.print(":");
display.setCursor(16, 20);
display.println(minuto_on);
display.setCursor(45, 20);
display.print(" -> ");
display.setCursor(82, 20);
display.println(hora_off);
display.setCursor(94, 20);
display.print(":");
display.setCursor(100, 20);
display.println(minuto_off);
display.setCursor(30, 30);
display.println(timeString);//hora atual
display.setCursor(60, 54);
display.print(" OUT ALR ");
display.setCursor(110, 54);
display.println(AL);
display.setTextSize(2);
display.setCursor(30, 40);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.println(hora_on);
if(sobe==1)hora_on++;
if(desce==1)hora_on--;
if(hora_on>24 || hora_on<0) hora_on = 0;
break;}
case 10:{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Ajuste minuto ON");
display.setCursor(2, 10);
display.print("AL.ON AL_OFF");
display.setCursor(1, 20);
display.println(hora_on);
display.setCursor(12, 20);
display.print(":");
display.setCursor(16, 20);
display.println(minuto_on);
display.setCursor(45, 20);
display.print(" -> ");
display.setCursor(82, 20);
display.println(hora_off);
display.setCursor(94, 20);
display.print(":");
display.setCursor(100, 20);
display.println(minuto_off);
display.setCursor(30, 30);
display.println(timeString);//hora atual
display.setCursor(60, 54);
display.print(" OUT ALR ");
display.setCursor(110, 54);
display.println(AL);
display.setTextSize(2);
display.setCursor(30, 40);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.println(minuto_on);
if(sobe==1)minuto_on++;
if(desce==1)minuto_on--;
if(minuto_on>59 || minuto_on<0) minuto_on = 0;
break;}
case 11:{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Ajuste hora OFF");
display.setCursor(2, 10);
display.print("AL.ON AL_OFF");
display.setCursor(1, 20);
display.println(hora_on);
display.setCursor(12, 20);
display.print(":");
display.setCursor(16, 20);
display.println(minuto_on);
display.setCursor(45, 20);
display.print(" -> ");
display.setCursor(82, 20);
display.println(hora_off);
display.setCursor(94, 20);
display.print(":");
display.setCursor(100, 20);
display.println(minuto_off);
display.setCursor(30, 30);
display.println(timeString);//hora atual
display.setCursor(60, 54);
display.print(" OUT ALR ");
display.setCursor(110, 54);
display.println(AL);
display.setTextSize(2);
display.setCursor(30, 40);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.println(hora_off);
if(sobe==1)hora_off++;
if(desce==1)hora_off--;
if(hora_off>24 || hora_off<0) hora_off = 0;
break;}
case 12:{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Ajuste minuto OFF");
display.setCursor(2, 10);
display.print("AL.ON AL_OFF");
display.setCursor(1, 20);
display.println(hora_on);
display.setCursor(12, 20);
display.print(":");
display.setCursor(16, 20);
display.println(minuto_on);
display.setCursor(45, 20);
display.print(" -> ");
display.setCursor(82, 20);
display.println(hora_off);
display.setCursor(94, 20);
display.print(":");
display.setCursor(100, 20);
display.println(minuto_off);
display.setCursor(30, 30);
display.println(timeString);//hora atual
display.setCursor(60, 54);
display.print(" OUT ALR ");
display.setCursor(110, 54);
display.println(AL);
display.setTextSize(2);
display.setCursor(30, 40);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.println(minuto_off);
if(sobe==1)minuto_off++;
if(desce==1)minuto_off--;
if(minuto_off>59 || minuto_off<0) minuto_off = 0;
break;}
case 13:{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Ajuste MAIOR >");
display.setCursor(35, 10);
display.print("GPIO32");
display.setCursor(1, 20);
display.println(maior);
display.setCursor(25, 20);
display.print(" > ");
display.setCursor(40, 20);
display.println(valorGPIO32);
display.setCursor(60, 20);
display.print(" < ");
display.setCursor(80, 20);
display.println(menor);
display.setCursor(1, 30);
display.print(" SAIDA PINO 18 ");
display.setCursor(100, 30);
display.println(p18);
display.setTextSize(2);
display.setCursor(30, 40);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.println(maior);
if(sobe==1)maior++;
if(desce==1)maior--;
break;}
case 14:{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Ajuste MENOR <");
display.setCursor(35, 10);
display.print("GPIO32");
display.setCursor(1, 20);
display.println(maior);
display.setCursor(25, 20);
display.print(" > ");
display.setCursor(40, 20);
display.println(valorGPIO32);
display.setCursor(60, 20);
display.print(" < ");
display.setCursor(80, 20);
display.println(menor);
display.setCursor(1, 30);
display.print(" SAIDA PINO 18 ");
display.setCursor(100, 30);
display.println(p18);
display.setTextSize(2);
display.setCursor(30, 40);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.println(menor);
if(sobe==1)menor++;
if(desce==1)menor--;
break;}
case 15:{///menu salvar dados
carre++;
if(carre>70)carre = 70;
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
if(carre==70) {display.println("SALVAR DADOS ");
display.setCursor(0, 10);
display.println("APERTE PARA CIMA ");
display.setCursor(0, 20);
display.println("Salvo em:");
display.print(horaE);display.print(":");
display.print(minutoE);display.print(" ");
display.print(diaE);display.print("/");
display.print(mesE);display.print("/");display.print(anoE);
}
if(sobe==1)carre=0;
if(carre<60){
display.setCursor(0, 0);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.print("Salvando");
if(carre>10)display.print(".");
if(carre>20)display.print(".");
if(carre>30)display.print(".");
if(carre>40)display.print(".");
if(carre>50)display.print(".");}
if(carre>60&&carre<70){ display.setCursor(0, 0);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.print("Dados salvos");
}
if(sobe==1){
horaE=hora;minutoE=minuto;diaE=dia;mesE=mes;anoE=ano;//para salvar hora do salvamento
EEPROM.put(enderecoValor1, menor);
EEPROM.put(enderecoValor2, maior);
EEPROM.put(enderecoValor3, hora_on);
EEPROM.put(enderecoValor4, hora_off);
EEPROM.put(enderecoValor5, minuto_on);
EEPROM.put(enderecoValor6, minuto_off);
EEPROM.put(enderecoValor7, SET);
EEPROM.put(enderecoValor8, funsao);
EEPROM.put(enderecoValor9, O1);
EEPROM.put(enderecoValor10, horaE);
EEPROM.put(enderecoValor11, minutoE);
EEPROM.put(enderecoValor12, diaE);
EEPROM.put(enderecoValor13, mesE);
EEPROM.put(enderecoValor14, anoE);
EEPROM.commit(); // Grava os dados na EEPROM
delay(200);
}
break;}
}
display.display();
}
void comparador(){
if((valorGPIO32<menor && valorGPIO32>maior)|| AL==1)
{digitalWrite(RL1, HIGH);p18=1;}
else {digitalWrite(RL1, LOW);p18=0;}
}
void drawGraph() {// FUNÇÃO GRAFICO
for (int i = 1; i < OLED_WIDTH; i++) {
int y1 = graphData[i - 1];
int y2 = graphData[i];
display.drawLine(i - 1, y1, i, y2, SSD1306_WHITE);
}
}
void alarme(){
if (hora_on == hora && minuto_on == minuto){AL=1;}
if (hora_off == hora && minuto_off == minuto){AL=0;}
}
void clp(){//função para execução da logica
// in1 = digitalRead(DIREITA_BUTTON_PIN);//botão precionado
// SET == VALOR A SER COMPARADO
//funsao == como deve ser execudado
if(ent1 == 0) {in1 = digitalRead(DIREITA_BUTTON_PIN);}//botão precionado
if(ent1 == 1) {if(valorGPIO32>100){in1=1;}else in1=0;}
if(ent1 == 2) {if(valorGPIO33>100){in1=1;}else in1=0;}
if(ent1 == 3) {if(valorGPIO34>100){in1=1;}else in1=0;}
if(funsao == 0){ //FUNÇÃO DELEY PARA LIGAR
if(in1 == 0){Cont++;
if(Cont>=SET){AL=1;Cont=SET;}}
else {AL=0;Cont=0;}
}
if(funsao == 1){ //FUNÇÃO DELEY PARA DESLIGAR
if(in1 == 0){Cont++;AL = 1;
if(Cont>=SET){AL=0;Cont=SET;}}
else {AL=0;Cont=0;}
TM=0;
}
if(funsao == 2){//função tempo ligado
if(TM==1){Cont++;AL=1;}
if(Cont>=SET){TM=0;AL=0;Cont=0;}
}
if(funsao == 3){//função pulso###################################
if(TM==1){Cont++;}
TM=0;
if(Cont>=SET){AL=1;Cont=SET;}
else{AL=0;}
if(estado==0)Cont=0;
}//###########################################################
if(funsao == 4){//função loop
if(in1 == 0){
if(muda==0){Cont++; AL=1;}
if(muda==1){Cont--; AL=0;}
if(Cont>=SET)muda++;
if((muda==1)&&(Cont==0))muda=0;
}
else {muda=0;AL=0;Cont=0;}
}
if(funsao == 5)//liga desliga
{if(TM==1){muda++;TM=0;delay(10);}
if(muda==1){AL=1;}
else AL=0;
if(muda>1)muda=0;
}
if (in1 == LOW && lastin1 == HIGH) {
// Gera um pulso
TM=1;
}
lastin1 = in1;
}
//############### troca de senha pelo IHM ###########
void redewifi()
{
handleButtons();
display.clearDisplay();
if (scanning) {
displayNetworks();
} else {
display.setCursor(0, 0);
display.print(" AJUSTE DE REDE: < ok");
display.setCursor(0, 10);
display.print("SSID: ");
displaySSID();
display.setCursor(0, 20);
display.print("Password: ");
displayPassword();
display.setCursor(3, 30);
display.print(ssid1);
display.print(" ");
display.print(password1);
display.setCursor(3, 40);
if(edisao==2){display.print("Botao < p/salvar");}
}
display.setCursor(0, 50);
if (editingSSID) {
display.print("Editando SSID");
} else {
display.print("Editando Senha");
}
display.display();
delay(100);
}
void handleButtons() {
if (digitalRead(UP_BUTTON_PIN) == LOW) {
temporeiniciar=0;
if (scanning) {
if (selectedNetwork > 0) selectedNetwork--;
} else {
incrementChar();
}
delay(200); // Debounce
}
if (digitalRead(DOWN_BUTTON_PIN) == LOW) {
temporeiniciar=0;
if (scanning) {
if (selectedNetwork < numberOfNetworks - 1) selectedNetwork++;
} else {
decrementChar();
}
delay(200); // Debounce
}
if (digitalRead(ESQUERDA_BUTTON_PIN) == LOW) {
temporeiniciar=0;
if (!scanning) {
moveCursorLeft();
}
delay(200); // Debounce
}
if (digitalRead(DIREITA_BUTTON_PIN) == LOW) {
temporeiniciar=0;
if (!scanning) {
moveCursorRight();
}
delay(200); // Debounce
}
if (digitalRead(ESQUERDA_BUTTON_PIN) == LOW && editIndex==0) {
if (scanning) {
// Seleciona a rede e muda para edição de senha
strncpy(ssid, networks[selectedNetwork].c_str(), sizeof(ssid));
scanning = false;
editIndex = 0;
}
else{ toggleEditing();
// Salva as credenciais na EEPROM ao alternar a edição
saveCredentials();
delay(200); // Debounce
if (edisao==3) {ESP.restart();} //reinicia o esp32
}
}
}
void incrementChar() {
if (edisao==0) {
if (ssid[editIndex] < 126) ssid[editIndex]++;
} else {
if (password[editIndex] < 126) password[editIndex]++;
}
}
void decrementChar() {
if (edisao==0) {
if (ssid[editIndex] > 32) ssid[editIndex]--;
} else {
if (password[editIndex] > 32) password[editIndex]--;
}
}
void moveCursorLeft() {
if (editIndex > 0) editIndex--;
}
void moveCursorRight() {
if (edisao==0) {
if (editIndex < strlen(ssid) - 1) editIndex++;
} else {
if (editIndex < strlen(password) - 1) editIndex++;
}
}
void toggleEditing() {
edisao++;
if(edisao>3){edisao=0;}
editingSSID = !editingSSID;
editIndex = 0; // Reinicia o índice de edição ao alternar
}
void displaySSID() {
for (int i = 0; i < strlen(ssid); i++) {
if (edisao==0 && i == editIndex) {
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Inverte as cores para o caractere atual
} else { display.setTextColor(SSD1306_WHITE); }
display.print(ssid[i]);
}
display.setTextColor(SSD1306_WHITE); // Restaura a cor padrão
}
void displayPassword() {
for (int i = 0; i < strlen(password); i++) {
if (edisao==1 && i == editIndex) {
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Inverte as cores para o caractere atual
} else {display.setTextColor(SSD1306_WHITE); }
display.print(password[i]);
}
display.setTextColor(SSD1306_WHITE); // Restaura a cor padrão
}
///################ salve na eeprom ##################
void saveCredentials() {
// Salva o SSID na EEPROM, ignorando espaços no final
int eepromIndex = SSID_ADDR;
for (int i = 0; i < 32; i++) {
if (ssid[i] != ' ' && ssid[i] != '\0') {
EEPROM.write(eepromIndex++, ssid[i]);
} else { break; }
}
EEPROM.write(eepromIndex, '\0'); // Marca o fim da string
// Salva a senha na EEPROM, ignorando espaços no final
eepromIndex = PASS_ADDR;
for (int i = 0; i < 32; i++) {
if (password[i] != ' ' && password[i] != '\0') {
EEPROM.write(eepromIndex++, password[i]);
} else { break; }
}
EEPROM.write(eepromIndex, '\0'); // Marca o fim da string
EEPROM.commit(); // Necessário no ESP8266 para realmente salvar na EEPROM
}
void loadCredentials() {
int eepromIndex = SSID_ADDR; // Carrega o SSID da EEPROM
for (int i = 0; i < 32; i++) {
char c = EEPROM.read(eepromIndex++);
if (c == '\0') break;
ssid1[i] = c;
}
ssid[31] = '\0'; // Garante que a string seja terminada com null
eepromIndex = PASS_ADDR; // Carrega a senha da EEPROM
for (int i = 0; i < 32; i++) {
char c = EEPROM.read(eepromIndex++);
if (c == '\0') break;
password1[i] = c;
}
password[31] = '\0'; // Garante que a string seja terminada com null
}
void scanNetworks() {
Serial.println("Scanning for Wi-Fi networks...");
numberOfNetworks = WiFi.scanNetworks();
if (numberOfNetworks == 0) {
Serial.println("No networks found.");
} else {
Serial.print(numberOfNetworks);
Serial.println(" networks found:");
for (int i = 0; i < numberOfNetworks && i < 10; i++) {
networks[i] = WiFi.SSID(i);
Serial.println(networks[i]);}
}
}
void displayNetworks() {
display.setCursor(0, 0);
display.print("Selecione REDE: < ok");
for (int i = 0; i < numberOfNetworks && i < 4; i++) {
display.setCursor(0, 10 + i * 10);
if (i == selectedNetwork) {
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
} else {display.setTextColor(SSD1306_WHITE);}
display.print(networks[i]);
}
display.setTextColor(SSD1306_WHITE); // Restaura a cor padrão
}
//################ fim de troca de senha pelo IHM ################
void LEEPROM(){
int eepromIndex = RELE_ADDR; // Carrega a senha da EEPROM
for (int i = 0; i < 32; i++) {
char c = EEPROM.read(eepromIndex++);
if (c == '\0') break;
RELE[i] = c;
}
RELE[31] = '\0'; // Garante que a string seja terminada com null
}