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