Você já pensou em uma
INDÚSTRIA DE 1 HOMEM SÓ? E se você fosse o projetista e o próprio fabricante?
Sei que falo para muitos engenheiros, empresários, funcionários de empresas,
mas também quero falar aqui com os makers, os que querem transformar seu hobby
em profissão, desenvolver um projeto, fabricar um produto e, por fim, vendê-lo.
Então, neste vídeo, vamos falar um pouco sobre empreendedorismo, isso mencionando
uma placa que montamos no vídeo COMO GANHAR DINHEIRO COM IOT. Vamos demonstrar
a utilização do WiFi Manager junto com uma aplicação utilizando o App FernandoK.
Para tal, utilizaremos um circuito pronto com sensores de gás, temperatura e
umidade.
Captura de tela do aplicativo Fernando K
Gráficos com os dados do Firebase
Comandos dos botões
Recursos usados
Esquema – Sensores
Esquema – Botão
Botão em pull down
Botão que faz com que o ESP entre em AP (Access point)
Esquema – Relés
Esquema – Sinalização
Esquema – Fonte e proteções
CÓDIGO
Declarações e variáveis
#include <SparkFunHTU21D.h> // Biblioteca com as funções do sensor HTU21D #include <IOXhop_FirebaseESP32.h> // Biblioteca com as funçoes do Firebase #include <ArduinoJson.h> // Biblioteca com as funções de manipulação de JSON #include "esp_task_wdt.h" // Biblioteca com as funções de task // Bibliotecas para utilizarmos o WiFi Manager #include <WebServer.h> #include <DNSServer.h> #include <WiFiManager.h> // URL da base de dados fornecido pelo Firebase para a conexão http #define FIREBASE_HOST "URL.firebaseio.com/" #define FIREBASE_AUTH "" // Autenticação const int pin_WiFi = 19; // Led indicador de conexão com WiFi const int pin_digitalMQ2 = 26; // Leitura da saída digital do MQ-2 const int pin_analogicaMQ2 = 39; // Leitura analógica do MQ-2 const int pin_Rele1 = 16; // Acionamento do relé 1 const int pin_Rele2 = 17; // Acionamento do relé 2 const int pin_Buzzer = 18; // Acionamento do Buzzer const int pin_AP = 5; // Pino do botão de configuração do Access Point const String PATH_COMMANDS = "/Commands"; // Caminho padrão para os comandos no Firebase String temp, humd; // Variáveis que receberão a temperatura e umidade do HTU21D // Pinos do sensor (i2c - canal 1) #define SDA 21 // Ligado ao SDA do HTU21D #define SCL 22 // Ligado ao SCL do HTU21D // Nome e senha da rede que o WiFi Manager criará quando estiver no modo AP (quando o botão ligado no pin_AP for pressionado) const char* NOME_REDE_AP = "ESP_AP"; const char* SENHA_REDE_AP = "12345678"; // Objeto que representa o HTU21D HTU21D htudSensor; // Objeto que representa a conexão I2C (wire) do sensor // Usando canal 1 TwoWire wireSensor = TwoWire(1); bool WiFiConfigMode = false;
Setup
void setup() { // Inicia o WatchDog de tasks esp_task_wdt_init(30, true); // Desabilita o WatchDogTimer de Hardware do Core 0 disableCore0WDT(); // Setup dos pinos GPIO's pinMode(pin_WiFi, OUTPUT); pinMode(pin_digitalMQ2, INPUT); pinMode(pin_analogicaMQ2, INPUT); pinMode(pin_Rele1, OUTPUT); pinMode(pin_Rele2, OUTPUT); pinMode(pin_Buzzer, OUTPUT); pinMode(pin_AP, INPUT); // Inicia os pinos do Relé em nível alto, já que os relés operam em lógica invertida digitalWrite(pin_Rele1, HIGH); digitalWrite(pin_Rele2, HIGH);
// Inicia o HTU21D htu21Begin(); // Inicia a saída serial Serial.begin(115200); // Inicia o WiFi Manager wifiManagerBegin(); // Aguarda 3s delay(3000); // Inicia a conexão com o WiFi // WiFi.begin(ssid, password); // Enquanto não conectado, faz o Led indicador de rede piscar e envia uma mensagem pela serial while (WiFi.status() != WL_CONNECTED) { digitalWrite(pin_WiFi, LOW); delay(250); digitalWrite(pin_WiFi, HIGH); delay(500); Serial.println("Conectando ao WiFi ..."); }
// Inicia a conexão com o Firebase Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH); // Inicia a função de callback usando o caminho de COMANDOS Firebase.stream(PATH_COMMANDS, [](FirebaseStream stream) { // Variáveis que recebem o caminho e valor retornado pelo callback String path, value; // Se o evento que vem do callback é de alteração "put" if (stream.getEvent() == "put") { // Obtemos os valores de path e value path = stream.getPath(); value = stream.getDataString(); // Se é o callback inicial quando a conexão é estabelecida if (path.equals("/")) { // Sincronizamos as saídas para os relés de acordo com a mensagem recebida // Executa a função que interpreta o valor recebido e atualiza o estado dos relés syncFirebase(value); // Envia a mensagem pela serial de sincronização Serial.println("Firebase sincronizado"); }
// Imprime na serial o caminho e o valor recebido (para debug) Serial.println(path + " - " + value); // Se o caminho é para o RELE1, ligamos/desligamos conforme o comando ON/OFF if (path == "/RELE1") value == "ON" ? digitalWrite(pin_Rele1, LOW) : digitalWrite(pin_Rele1, HIGH); else if (path == "/RELE2") // Se o caminho é para o RELE2, ligamos/desligamos conforme o comando ON/OFF value == "ON" ? digitalWrite(pin_Rele2, LOW) : digitalWrite(pin_Rele2, HIGH); } }); // Cria a task que irá monitorar a saída digital do MQ-2 e acionará o buzzer se for necessário xTaskCreatePinnedToCore(gasAlerta, "gasAlerta", 10000, NULL, 0, NULL, 0); // Cria a task que lê o botão responsável por mudar o modo de WiFi do ESP para AP e iniciar o WebServer do WiFi Manager xTaskCreatePinnedToCore(wifiManagerEvent, "wifiManagerEvent", 10000, NULL, 0, NULL, 0); }
Loop
void loop() { // Se o modo AP não foi solicitado pelo botão if(!WiFiConfigMode) { // Verificamos a reconexão de WiFi verifyWiFiReconnect(); // Função que obtem os valores do sensor HTU21D readClimate(); // Função que envia os dados para o Firebase sendClimateFirebase(); } // Aguarda 3 segundos delay(3000); }
gasAlerta
// Task que monitora a saída digital do MQ-2 void gasAlerta(void *p) { // Adiciona a task na lista do Watch esp_task_wdt_add(NULL); while (1) // loop da task { if(digitalRead(pin_digitalMQ2) == LOW) // se um disparo for detectado...(nível baixo) { digitalWrite(pin_Buzzer, HIGH); // ...liga o buzzer... Serial.println("Gas detectado!"); // ...envia o alerta para a serial delay(3000);// ...aguarda por 3s.... digitalWrite(pin_Buzzer, LOW);// ...desliga o buzzer. } esp_task_wdt_reset(); // reinicia o WatchDog de task delay(1); // um pequeno intervalo antes de reiniciar o loop da task } }
wifiManagerEvent
// Task que lê o botão e inicia o WebServer do WiFi Manager quando ele estiver em HIGH void wifiManagerEvent(void *p) { // A função de configuração "startConfigPortal" pode levar muito tempo para terminar de ser executada (depende do tempo que usuário leva para configurar a nova conexão WiFi) // Por isso, optamos por não utilizar o watchdog nessa task // esp_task_wdt_add(NULL); // Loop da task while (1) { // Verificamos se o botão foi pressionado if(digitalRead(pin_AP) == HIGH) { // Ativamos o buzzer para indicar que o botão foi pressionado digitalWrite(pin_Buzzer, HIGH); delay(500); digitalWrite(pin_Buzzer, LOW); // Iniciamos o WebServer do WiFi Manager WiFiManager wifiManager;
// Setamos a flag que impede a execução do loop enquanto isso WiFiConfigMode = true; WiFi.disconnect(true); // Iniciamos o modo AP utilizando o nome e senha declarados anteriormente if(!wifiManager.startConfigPortal(NOME_REDE_AP, SENHA_REDE_AP)) { // Se não der certo, exibimos erro Serial.println("Falha ao conectar"); // Sinalizamos no buzzer com dois sons rápidos indicando falha digitalWrite(pin_Buzzer, HIGH); delay(250); digitalWrite(pin_Buzzer, LOW); delay(250); digitalWrite(pin_Buzzer, HIGH); delay(250); digitalWrite(pin_Buzzer, LOW); // Reiniciamos o ESP ESP.restart(); }
// Se não entrar no if, então o ESP não será reiniciado e o código abaixo será executado // Ativamos o buzzer por um tempo para sinalizar sucesso na operação digitalWrite(pin_Buzzer, HIGH); delay(500); digitalWrite(pin_Buzzer, LOW); } // A função de configuração "startConfigPortal" pode levar muito tempo para terminar de ser executada (depende do tempo que usuário leva para configurar a nova conexão WiFi) // Por isso, optamos por não utilizar o watchdog nessa task //esp_task_wdt_reset(); // Aguardamos 1ms delay(1); } }
htu21Begin e wifiManagerBegin
// Função que inicia o sensor de temperatura e umidade HTU21D void htu21Begin() { wireSensor.begin(SDA, SCL, 400000); htudSensor.begin(wireSensor); }
// Função que inicia o WiFi Manager void wifiManagerBegin() { WiFiManager wifiManager; // Utilizando esse comando, as configurações são apagadas da memória // Caso tiver salvo alguma rede para conectar automaticamente, ela é apagada // wifiManager.resetSettings(); // Função callback para quando entra em modo de configuração AP wifiManager.setAPCallback(configModeCallback); // Função callback para quando se conecta em uma rede, ou seja, quando passa a trabalhar em modo estação wifiManager.setSaveConfigCallback(saveConfigCallback); // Cria uma rede de nome ESP_AP com senha 12345678 wifiManager.autoConnect(NOME_REDE_AP, SENHA_REDE_AP); }
syncFirebase
// Função que ativa/desativa todos os relés de acordo com a mensagem recebida ao iniciar o Firebase // (Sincronizando as saídas do ESP com os valores atuais do Firebase) void syncFirebase(String value) { /* EXEMPLO DE MENSAGEM RECEBIDA: "RELE1":"ON","RELE2":"ON" */ //obtem uma substring a partir do texto "RELE1" String aux = value.substring(value.indexOf("RELE1")); //obtem a posição do primeiro separador de valor ":" int posVar = aux.indexOf(":\""); String status = ""; if (posVar != -1) //se foi encontrado o separador .... { posVar += 2; // ...acrescenta duas posição para saltar o separador for (int i = posVar; aux.charAt(i) != '\"'; i++) //varre a substring até as próximas aspas... status += aux.charAt(i);//...obtendo o valor Serial.println("Status RELE1:" + status); //envia para a serial o valor obtido if (status.equals("ON")) //...se o valor é ON, ativa o relé. (lógica invertida de ativação) digitalWrite(pin_Rele1, LOW); else if (status.equals("OFF")) //...se o vlor é OFF, desativa o relé. digitalWrite(pin_Rele1, HIGH); }
//repete o processo para o relé 2 status = ""; aux = value.substring(value.indexOf("RELE2")); posVar = aux.indexOf(":\""); if (posVar != -1) { posVar += 2; for (int i = posVar; aux.charAt(i) != '\"'; i++) status += aux.charAt(i); Serial.println("Status RELE2:" + status); if (status.equals("ON")) digitalWrite(pin_Rele2, LOW); else if (status.equals("OFF")) digitalWrite(pin_Rele2, HIGH); } }
sendClimateFirebase
// Função que envia os dados para o Firebase void sendClimateFirebase() { StaticJsonBuffer<150> jsonBufferSensor; //reserva de memóoria para oobjeto JSON que contem os dados dos sensores StaticJsonBuffer<50> jsonBufferTimestamp; //reserva de memória para o objeto JSON que contem o instante dos dados JsonObject& timestamp = jsonBufferTimestamp.createObject(); //cria o objeto JSON que conterá o instante timestamp[".sv"] = "timestamp"; //cria o campo do instante JsonObject& sensorData = jsonBufferSensor.createObject(); //cria o objeto JSON que conterá os dados dos sensores if (temp != "" && humd != "")//se os valores de temperatura e umidade são válidos... { sensorData["Temperatura"] = temp; //...atribui os valores ao JSON sensorData["Umidade"] = humd; } else //...se não são válidos, atribui uma mensagem de erro. { sensorData["Temperatura"] = "Erro na leitura"; sensorData["Umidade"] = "Erro na leitura"; } 50>150>
//atribui as leituras do sensor MQ-2 ao objeto JSON de dados sensorData["MQ-2 analogico"] = String(analogRead(pin_analogicaMQ2)); sensorData["MQ-2 digital"] = String(digitalRead(pin_digitalMQ2)); sensorData["timestamp"] = timestamp; //atribui o instante Firebase.push("/Dados", sensorData); //envia para o Firebase jsonBufferSensor.clear(); //limpa os objetos JSON criados jsonBufferTimestamp.clear(); }
configModeCallback e saveConfigCallback
// Quando o ESP iniciar e não conseguir conectar em uma rede wifi, essa função é chamada automaticamente pela lib wifi manager // Função callback que indica que o ESP entrou no modo AP void configModeCallback(WiFiManager *myWiFiManager) { // Ativamos o buzzer para sinalizar que o modo AP foi iniciado digitalWrite(pin_Buzzer, HIGH); delay(500); digitalWrite(pin_Buzzer, LOW); Serial.println("Entrou no modo de configuração"); Serial.println(WiFi.softAPIP()); //imprime o IP do AP Serial.println(myWiFiManager->getConfigPortalSSID()); //imprime o SSID criado da rede }
verifyWiFiReconnect
// Função que reconecta o WiFi, se necessário void verifyWiFiReconnect() { // Se a conexão caiu, tenta se conectar novamente if(WiFi.status() != WL_CONNECTED) WiFi.begin(); // Sinaliza as tentativas piscando o LED indicador da conexão while (WiFi.status() != WL_CONNECTED) { digitalWrite(pin_WiFi, LOW); delay(250); digitalWrite(pin_WiFi, HIGH); delay(500); Serial.println("Conectando ao WiFi ..."); } }
readClimate
// Função que lê os valores do sensor HTU21D void readClimate() { // Retorna 999 caso dê erro de leitura float h = htudSensor.readHumidity(); //obtem a umidade float t = htudSensor.readTemperature(); //obtem a temperatura if (t < 900) //verifica se a leitura de temperatura é válida temp = String(t); else temp = ""; if (h < 900) //verifica se a leitura de umidade é válida humd = String(h); else humd = ""; }
0 Comentários