Pessoal, neste vídeo vamos fazer com que ESPs com sensores DHT enviem dados de temperatura e umidade através do protocolo ESPNOW para outro ESP que está conectado à internet. Então, este ESP conectado à internet vai enviar os dados recolhidos dos outros ESPs para um servidor MQTT.
Tudo isso usando o dashboard do IBM Watson ligado em um Gateway do ESP32, que se comunica simultaneamente com WiFi 2.4.
Esse vídeo, portanto, engloba bastante assunto e é bastante útil para a Internet das Coisas.
RECURSOS USADOS
- ESP32
- Resistor 4.7k ohm
- Protoboard
- Jumpers
- DHT22
MONTAGEM ESP32 DHT22
CÓDIGO
Bibliotecas necessárias
SimpleDHT
PubSubClient
FLUXOGRAMA ESP32 GATEWAY
CÓDIGO ESP32 GATEWAY
#include <esp_now.h> #include <WiFi.h> #include <PubSubClient.h> //SSID e senha para se conectar à internet #define SSID "TestESP" #define PASSWORD "12345678" //Server MQTT que iremos utilizar #define MQTT_SERVER "quickstart.messaging.internetofthings.ibmcloud.com" //Nome do tópico que devemos enviar os dados //para que eles apareçam nos gráficos #define TOPIC_NAME "iot-2/evt/status/fmt/json" //ID que usaremos para conectar //QUICK_START deve permanecer como está const String QUICK_START = "d:quickstart:arduino:"; //No DEVICE_ID você deve mudar para um id único //Aqui nesse exemplo utilizamos o MAC Address //do dispositivo que estamos utilizando //Servirá como identificação no site //https://quickstart.internetofthings.ibmcloud.com const String DEVICE_ID = "3C71BF448181"; //Concatenamos o id do quickstart com o id do nosso //dispositivo const String CLIENT_ID = QUICK_START + DEVICE_ID; //Cliente WiFi que o MQTT irá utilizar para se conectar WiFiClient wifiClient; //Cliente MQTT, passamos a url do server, a porta //e o cliente WiFi PubSubClient client(MQTT_SERVER, 1883, wifiClient); //Estrutura de comunicação entre os ESPs com DHT e o gateway //Os ESPs com DHT irão enviar esta estrutura //Para que o gateway receba é necessário que no código dos ESP com DHT tenha outra struct igual a esta typedef struct { char id[30]; float humidity; float temperature; }SensorData;
Setup
void setup() { //Inicia serial Serial.begin(115200); //Inicia WiFi setupWiFi(); //Inicia ESPNOW setupEspNow(); //Conecta ao server MQTT connectToMQTTServer(); }
SetupWiFi
void setupWiFi(){ //Desconecta e reseta as configurações da WiFi WiFi.disconnect(true, true); //O modo deve ser tanto AP quanto Station WiFi.mode(WIFI_AP_STA); //Mandamos conectar na rede WiFi.begin(SSID, PASSWORD); Serial.println(""); //Enquanto não estiver conectado à rede WiFi while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } //Se chegou aqui está conectado Serial.println(""); Serial.print("Connected to "); Serial.println(SSID); Serial.print("IP address: "); Serial.println(WiFi.localIP()); //IMPORTANTE: O valor do softAP mac address deve ir no código dos ESPs com DHT Serial.print("softAPmacAddress: "); Serial.println(WiFi.softAPmacAddress()); }
SetupEspNow
void setupEspNow() { //Se a inicialização foi bem sucedida if (esp_now_init() == ESP_OK) { Serial.println("ESPNow Init Success"); //Registra a função que será executada quando chegarem dados dos ESPs com DHT esp_now_register_recv_cb(OnDataRecv); } //Se houve erro na inicialização else { Serial.println("ESPNow Init Failed"); ESP.restart(); } }
ConnectToMQTTServer
//Função responsável por conectar ao server MQTT void connectToMQTTServer() { Serial.println("Connecting to MQTT Server..."); //Se conecta ao id que definimos if (client.connect(CLIENT_ID.c_str())) { //Se a conexão foi bem sucedida Serial.println("connected"); } else { //Se ocorreu algum erro Serial.print("error = "); Serial.println(client.state()); } }
OnDataRecv
//Função que serve de callback para nos avisar //quando chegou algo dos ESPs com DHT void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) { Serial.println("Received"); SensorData* sensorData = (SensorData*) data; //Envia para o Server MQTT sendToMQTT(sensorData); }
SendToMQTT
void sendToMQTT(SensorData* sensorData) { //Criamos o json que enviaremos para o server MQTT String msg = createJsonString(sensorData); Serial.print("Publish message: "); Serial.println(msg); //Publicamos no tópico onde o servidor espera para receber //e gerar o gráfico client.publish(TOPIC_NAME, msg.c_str()); }
createJsonString
//Função responsável por criar //um Json com os dados lidos String createJsonString(SensorData* sensorData) { String data = "{"; data+= "\"d\": {"; data+="\""+String(sensorData->id)+"\":{"; data+="\"temperature\":"+String(sensorData->temperature); data+=","; data+="\"humidity\":"+String(sensorData->humidity); data+="}"; data+="}"; data+="}"; return data; }
Loop
//Não precisamos fazer nada no loop //Sempre que chegar algo de um dos ESPs com DHT //a função OnDataRecv é executada automaticamente //já que adicionamos como callback utilizando a função //esp_now_register_recv_cb void loop() { }
FLUXOGRAMA ESP32 DHT
Código ESP32 DHT
#include <esp_now.h> #include <WiFi.h> #include <SimpleDHT.h> //Identificação para o gateway saber quem está enviando os dados //Modifique para cada ESP com DHT que for usar #define ID "sensor1" //Canal usado para conexão //Caso a comunicação do ESPNOW não funcione tente mudar para outro canal WiFi #define CHANNEL 6 #define DHTPIN 4 //Pino onde está o DHT #define INTERVAL 5000 //Intervalo entre os envios dos dados do sensor //Marca quando foi feito o último envio os dados uint32_t lastTimeSent = 0; //Objeto que realiza a leitura da umidade e temperatura SimpleDHT22 dht; //IMPORTANTE: //Mac Address do gateway //Primeiro execute o código do gateway, abra o monitor serial dele e altere aqui pelo softAPmacAddress //que aparecer para o gateway uint8_t gatewayMacAdress[6] = {0x3C,0x71,0xBF,0x44,0x81,0x81}; esp_now_peer_info_t gateway; //Estrutura de comunicação entre os ESPs com DHT e o gateway //Os ESPs com DHT irão enviar esta estrutura //Para que o gateway receba é necessário que no código do gateway tenha outra struct igual a esta typedef struct { char id[30]; float humidity; float temperature; }SensorData; //Guarda o valor da umidade e temperatura lida para ser enviada para o gateway SensorData sensorData;
Setup
void setup() { Serial.begin(115200); //Inicializa a WiFi setupWiFi(); //Inicializa o ESPNow e adiciona o callback de envio setupEspNow(); //Adiciona o gateway como um peer do ESPNOW addGatewayAsPeer(); }
SetupWiFi
void setupWiFi() { //Reseta as configurações da WiFi WiFi.disconnect(true, true); //Colocamos o ESP em modo AP WiFi.mode(WIFI_AP); //Faz o AP utilizar o canal passado em "CHANNEL" bool hidden = true; WiFi.softAP(ID, "12345678", CHANNEL, hidden); }
SetupEspNow
void setupEspNow() { //Se a inicialização foi bem sucedida if (esp_now_init() == ESP_OK) { Serial.println("ESPNow Init Success"); //Registra a função que nos informará sobre o status do envio //A função que será executada é onDataSent e está declarada mais abaixo esp_now_register_send_cb(onDataSent); } //Se houve erro na inicialização else { Serial.println("ESPNow Init Failed"); //Reinicializa o ESP ESP.restart(); } }
AddGatewayAsPeer
void addGatewayAsPeer() { //Canal de comunicação gateway.channel = CHANNEL; //0 para não usar criptografia gateway.encrypt = 0; //Interface utilizada na comunicação do ESPNOW gateway.ifidx = WIFI_IF_AP; //Copia o endereço do array para a estrutura memcpy(gateway.peer_addr, gatewayMacAdress, sizeof(gatewayMacAdress)); //Adiciona gateway como peer esp_now_add_peer(&gateway); }
OnDataSent
//Função que serve de callback para nos avisar //sobre a situação do envio que fizemos void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { //Mostramos se o status do envio foi bem sucedido ou não Serial.print("Status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail"); }
Loop
void loop() { uint32_t now = millis(); //Se o tempo desde o último envio for maior que o intervalo definido if(now - lastTimeSent > INTERVAL) { //Faz a leitura da temperatura e umidade readSensor(); //Envia dados do sensor sendSensorData(); //Marca o tempo do último envio como agora lastTimeSent = now; } }
ReadSensor
void readSensor() { Serial.println("READ"); //Faz a leitura da temperatura e umidade float h, t; int status = dht.read2(DHTPIN, &t, &h, NULL); //Se a leitura foi bem sucedida if (status == SimpleDHTErrSuccess) { //Guarda na struct a id e os valores da umidade e da temperatura strcpy(sensorData.id, ID); sensorData.humidity = h; sensorData.temperature = t; } }
SendSensorData
void sendSensorData() { //Envia a struct para o gateway esp_err_t result = esp_now_send(gatewayMacAdress, (uint8_t*) &sensorData, sizeof(sensorData)); Serial.print("Send Status: "); //Se o envio foi bem sucedido if (result == ESP_OK) { Serial.println("Success"); } //Se aconteceu algum erro no envio else { Serial.println("Error"); } }
8 Comentários
Bom dia. não consigo encontrar a lib esp-now.. quem pode me ajudar?
ResponderExcluirhttps://github.com/espressif/arduino-esp32/blob/master/tools/sdk/include/esp32/esp_now.h
Excluirtambem me ajudou! obg!
Excluirtem como fazer um esp nao sleve e server que possa tanto enviar como receber mensagens
ResponderExcluirO .ino tá com o rar corrompido.
ResponderExcluirJá está disponível
ExcluirBoa tarde, isso é possível usar como um ESP32 lê o banco de dados e depois envia as informações para os atuadores? É possível ter as duas formas de comunicação?
ResponderExcluirNao consigo encontrar a biblioteca espnow para download
ResponderExcluir