Este artigo é o segundo de uma série de três artigos que mostra como construir uma estação de medição de temperatura utilizando Arduino e IoT open source. Para você que perdeu o primeiro artigo, acesse este link antes de ler esse texto. Com esses três textos em mãos e os componentes, placas e ferramentas necessárias, qualquer um com um conhecimento técnico mínimo de eletrônica poderá construir e contribuir para a medição de temperatura em diferentes pontos do Brasil e, quem sabe, claro, do planeta (nada impede isso).
O coração do sistema é uma placa Arduino fácil de ser encontrada e comprada. Para comunicação com internet, será utilizado um módulo Wi-Fi ESP8266 ESP-01, o qual utilizará MQTT. Esta série esta sendo construída por mim e por Douglas Salin Zuqueto.
A série de artigos que está sendo escrita aborda os seguintes assuntos:
- Estação de medição de temperatura Open-Source com Arduino e IoT – Configuração: Criação de um software no Arduino capaz de se comunicar com o sensor de temperatura DHT-22 e configuração da comunicação serial com o módulo ESP8266 ESP-01;
- Estação de medição de temperatura Open-Source com Arduino e IoT – Comunicação: Preparação do ESP8266 ESP-01 para comunicação serial com Arduino e comunicação com o Broker MQTT;
- Estação de medição de temperatura Open-Source com Arduino e IoT – Publicação dos dados: Finalização do software no Arduino, desenvolvimento de um WebSocket para comunicação com o Broker MQTT (através de qualquer navegador, em qualquer dispositivo capaz de navegar na Internet) e finalização do projeto (funcionamento completo).
Esta série foi desenvolvida com o hardware oferecido pelo loja FILIPEFLOP, a qual foi fundamental para o desenvolvimento deste projeto, pois sem o auxílio do hardware, o projeto se tornaria inviável.
Este artigo será dividido em três tópicos gerais: conexão do ESP8266 à rede Wi-Fi, conexão com o broker MQTT e a integração do Arduino com o módulo ESP8266. Salienta-se que para realizar a programação do módulo ESP8266 foi usada a integração da IDE do Arduino. Para mais informações sobre e ela e para baixá-la, acesse este link.
Conexão do ESP8266 à rede Wi-Fi
Para se conectar a uma rede Wi-Fi e usufruir da internet no Arduino e ESP8266, você terá que ter um roteador ou um hotspot por perto. O próximo passo é começar a escrita do firmware. Neste caso, será usada a biblioteca ESP8266WiFi que a integração da IDE disponibiliza para que o ESP possa se conectar à rede Wi-Fi. Para saber como conectar seu ESP8266 ao computador para programá-lo com a IDE Arduino, veja este excelente artigo do Pedro Minatel.
Veja abaixo o código utlizado para se conectar à rede Wi-Fi. Depois do firmware ser carregado para o ESP8266, abra o monitor serial para observar se a conexão foi bem sucedida.
#include <ESP8266WiFi.h> // Importa a Biblioteca ESP8266WiFi
// WIFI
const char* SSID = "localhost.dzuqueto"; // SSID da Rede
const char* PASSWORD = "6YxZ55Ql"; // Senha da Rede
// Prototypes das funções utilizadas no decorrer do Firmware
void initWiFi();
void setup() {
Serial.begin(115200);
}
// Função para iniciar a Conexão com a rede WiFi
void initWiFi() {
delay(1000);
Serial.println();
Serial.print("Conectando-se em: ");
Serial.println(SSID);
WiFi.begin(SSID, PASSWORD); // Conecta na Rede Wireless
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println();
Serial.print("Conectado na Rede ");
Serial.print(SSID);
Serial.print(" | IP ");
Serial.println(WiFi.localIP()); // Mostra o IP que foi atribuido para o ESP8266
}
void reconectar() {
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
}
void loop() {
reconectar(); // Caso o ESP perca conexão com a rede WiFi, ele tenta se reconectar a rede.
Serial.print("Conectado na Rede: ");
Serial.println(SSID);
delay(1000);
}
Conforme observado no código acima, é possível constatar que não existe mistério em se conectar na rede Wi-Fi. Com simples linhas de código, seu ESP8266 já está conectado na internet. Caso desejar estudar mais essa biblioteca ESP8266WiFi e ver mais alguns exemplos, acesse o repositório oficial da biblioteca.
Na figura 1 observamos o debug no monitor serial.
Conexão do ESP8266 com o MQTT utilizando a biblioteca PubSubClient
Agora chegou a hora de comunicarmos de fato com o broker MQTT. Para isso, é necessário fazer o download e a instalação da biblioteca PubSubClient. Para baixá-la, acesse este link. A instalação da biblioteca deve seguir o mesmo processo de outras bibliotecas para o Arduino.
Com a biblioteca instalada, o próximo passo é integrar o firmware anterior com a biblioteca do MQTT. Observe o código abaixo e veja em especial esse trecho:
MQTT.subscribe("EMCOL");
Nele estamos assinando o tópico MQTT EMCOL (EMCOL – Estação Meteorológica Colaborativa), o qual vai ser responsável pela centralização de todas as temperaturas da rede de estações meteorológicas.
No loop principal foi criada uma variável payload, sendo ela responsável pela string que conterá as coordenadas da estação meteorológica, assim como a temperatura medida (string esta que será, futuramente, decodificada e visualizada no artigo 3 desta série). Essas informações serão usadas posteriormente para fazer o mapeamento de todas as estações com base em sua localização. Em outras palavras: se um equipamento (seja um Arduino ou não) for capaz de se comunicar MQTT e medir temperaturas, este pode publicar informações neste tópico e contribuir para este projeto!
Observe o código completo abaixo. Nele supomos a localização geográfica na latitude e longitude iguais a -29.1838681 e -54.8528838 respectivamente.
#include <ESP8266WiFi.h> // Importa a Biblioteca ESP8266WiFi
#include <PubSubClient.h> // Importa a Biblioteca PubSubClient
// WIFI
const char* SSID = "localhost.dzuqueto"; // SSID da Rede
const char* PASSWORD = "6YxZ55Ql"; // Senha da Rede
// MQTT
//const char* BROKER_MQTT = "10.42.0.1"; // IP/URL DO BROKER MQTT
const char* BROKER_MQTT = "test.mosquitto.org"; // IP/URL DO BROKER MQTT
int BROKER_PORT = 1883; // Porta do Broker MQTT
// COORDENADAS
// Importante: substituir estas coordenadas pelas coordenadas geográficas da sua estação meteorológica
#define LAT "-29.1838681"
#define LONG "-54.8528838"
#define ID_MQTT "-29.1838681/-54.8528838" //id mqtt definido como as coordenada geográficas para garantir unicidade
WiFiClient espClient; // Cria o objeto espClient
String temp = "0";
PubSubClient MQTT(espClient); // Instancia o Cliente MQTT passando o objeto espClient
// Declaração das funções utilizadas no decorrer do Firmware
void initSerial();
void initWiFi();
void initMQTT();
void mqtt_callback(char* topic, byte* payload, unsigned int length);
void setup() {
initSerial();
initWiFi();
initMQTT();
}
// Função para iniciar a comunicação serial
void initSerial() {
Serial.begin(115200);
}
// Função para iniciar a Conexão com a rede WiFi
void initWiFi() {
delay(10);
Serial.println();
Serial.print("Conectando-se em: ");
Serial.println(SSID);
WiFi.begin(SSID, PASSWORD); // Conecta na Rede Wireless
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println();
Serial.print("Conectado na Rede ");
Serial.print(SSID);
Serial.println(" | IP ");
Serial.println(WiFi.localIP());
}
// Funcão para se conectar ao Broker MQTT
void initMQTT() {
MQTT.setServer(BROKER_MQTT, BROKER_PORT); // Atribui a biblioteca MQTT o Broker MQTT
MQTT.setCallback(mqtt_callback); // tribui a biblioteca MQTT o callback
}
//Função que recebe as mensagens publicadas
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
String message;
for (int i = 0; i < length; i++) {
char c = (char)payload[i];
message += c;
}
Serial.print("Tópico ");
Serial.print(topic);
Serial.print(" | ");
Serial.println(message);
message = "";
}
// Função para se reconectar ao Broker MQTT caso cai'a a comunicação
void reconnectMQTT() {
while (!MQTT.connected()) {
Serial.print("Tentando se conectar ao Broker MQTT: ");
Serial.println(BROKER_MQTT);
if (MQTT.connect(ID_MQTT)) {
Serial.println("Conectado");
MQTT.subscribe("EMCOL"); // Assina o tópico estação/lat/long
} else {
Serial.println("Falha ao Reconectar");
Serial.println("Tentando se reconectar em 2 segundos");
delay(2000);
}
}
}
// Função para se reconectar a rede WiFi caso caia a comunicação com a rede
void recconectWiFi() {
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
}
void loop() {
if (!MQTT.connected()) {
reconnectMQTT(); // Caso o ESP se desconecte do Broker, ele tenta se reconectar ao Broker
}
recconectWiFi(); // Caso o ESP perca conexão com a rede WiFi, ele tenta se reconetar a rede.
// Variável que irá guardar as coordenadas e a temperatura para posteriormente serem tratadas e enviadas.
String payload = LAT;
payload += ",";
payload += LONG;
payload += ",";
payload += temp;
char payloadChar[payload.length()];
payload.toCharArray(payloadChar, payload.length() + 1); // Converte a String para Char Array
// Publica no tópico EMCOL todas as informações contidas na variável payload.
MQTT.publish("EMCOL", payloadChar);
delay(1000);
MQTT.loop();
}
Abra o monitor serial e veja o que está acontecendo. Basicamente, até o momento, o ESP8266 já está conectando na rede wireless, está se conectando com o Broker MQTT (test.mosquitto.org) e também está simulando o envio dos dados para o Broker MQTT. Veja a figura 2.
Integração do Arduino como Módulo ESP8266
Você lembra do artigo anterior? Nele o Arduino foi preparado para enviar os dados referentes à temperatura via comunicação serial (pelo pinos 2 e 3, RX e TX, respectivamente). Agora será tratado, no firmware final para o ESP8266, a integração do Arduino com o ESP8266. Além disso, será feito um pequeno debug para verificar toda a comunicação do sistema (ou seja, Arduino -> ESP8266 e ESP8266 →Broker).
Agora, será modificado o firmware desenvolvido para o ESP8266 para receber informações da comunicação serial (enviado pelo Arduino), agrupá-las em uma string (informações separadas por vírgulas) e enviar, via MQTT, para o broker.
#include <ESP8266WiFi.h> // Importa a Biblioteca ESP8266WiFi
#include <PubSubClient.h> // Importa a Biblioteca PubSubClient
// WIFI
const char* SSID = "localhost.dzuqueto"; // SSID da Rede
const char* PASSWORD = "6YxZ55Ql"; // Senha da Rede
// MQTT
const char* BROKER_MQTT = "test.mosquitto.org"; // IP/URL DO BROKER MQTT
int BROKER_PORT = 1883; // Porta do Broker MQTT
// COORDENADAS
// Importante: substituir estas coordenadas pelas coordenadas geográficas da sua estação meteorológica
#define LAT "-29.1838681"
#define LONG "-54.8528838"
#define ID_MQTT "-29.1838681/-54.8528838" //id mqtt definido como as coordenada geográficas para garantir unicidade
WiFiClient espClient; // Cria o objeto espClient
PubSubClient MQTT(espClient); // Instancia o Cliente MQTT passando o objeto espClient
// Prototypes das funções utilizadas no decorrer do Firmware
void readData();
void initSerial();
void initWiFi();
void initMQTT();
void setup() {
initSerial();
initWiFi();
initMQTT();
}
// Função para iniciar a comunicação serial
void initSerial() {
Serial.begin(9600);
}
// Função para iniciar a Conexão com a rede WiFi
void initWiFi() {
WiFi.begin(SSID, PASSWORD); // Conecta na Rede Wireless
while (WiFi.status() != WL_CONNECTED) {
delay(100);
}
}
// Funcão para se conectar ao Broker MQTT
void initMQTT() {
MQTT.setServer(BROKER_MQTT, BROKER_PORT); // Informa o broker e porta utilizados
}
// Função para se reconectar ao Broker MQTT caso cair a comunicação
void reconnectMQTT() {
while (!MQTT.connected()) {
if (MQTT.connect(ID_MQTT)) {
} else {
delay(2000);
}
}
}
// Função para se reconectar a rede WiFi caso caia a comunicação com a rede
void recconectWiFi() {
while (WiFi.status() != WL_CONNECTED) {
delay(100);
}
}
void readData() {
if (Serial.available()) {
String temp = "";
while (Serial.available()) {
char c = (char)Serial.read();
if (c != '\n') {
temp += c;
}
delay(10);
}
String payload = LAT;
payload += ",";
payload += LONG;
payload += ",";
payload += temp;
char payloadChar[payload.length()];
payload.toCharArray(payloadChar, payload.length() + 1); // Converte a String para Char Array
// Publica no tópico EMCOL todas as informações contidas na variável payload.
MQTT.publish("EMCOL", payloadChar);
}
}
void loop() {
if (!MQTT.connected()) {
reconnectMQTT(); // Caso o ESP se desconecte do Broker, ele tenta se reconectar ao Broker
}
recconectWiFi(); // Caso o ESP perca conexão com a rede WiFi, ele tenta se reconetar a rede.
readData();
MQTT.loop();
}
Em relação ao código anterior, algumas modificações foram feitas. Uma delas é comentar todas linhas que continha o Serial.println, onde estavamos usando para debugar o firmware. Agora, com a comunicação serial com o Arduino, não podemos mais usar esta serial para debug. Outra modificação foi no loop principal, onde foi chamada a função readData() (criada neste código mais atual), a qual será responsável por receber a temperatura enviada pelo Arduino e, logo depois, publicar as informações no tópico EMCOL.
Para ocorrer a comunicação serial com o Arduino, precisamos ligar o pino RX do ESP8266 ao pino 3 do Arduino (conforme definido no artigo anterior) e também interconectar os dois com o GND. Observe o esquemático abaixo que ilustra estas ligações:
Resultado / verificação do funcionamento
Para verificar se realmente está tudo funcionando corretamente, há dois modos.
O primeiro modo é feito através de comandos digitados no shell de qualquer computador com cliente MQTT Mosquitto instalado. Através do comando mosquitto_sub, você pode assinar o tópico EMCOL e ver as coordenadas e temperatura sendo recebidas. O comando a ser digitado em questão é:
mosquitto_sub -h test.mosquitto.org -t EMCOL
A segunda maneira, mais intuitiva, é utilizando um cliente MQTT visualizável pelo navegador para assinar o tópico EMCOL e visualizar as mensagens. Para isto, utilizei o cliente MQTT grátis e acessível pelo navegador chamado MQTTLens. Observe o screenshot da comunicação na figura 4 (lembrando que todas as informações estão no Payload da mensagem MQTT, na ordem: LATITUDE,LONGITUDE,TEMPERATURA).







No meu caso, estou fazendo manipulação de umidade do solo para uma horta. Como eu posso adaptar para o meu código? Sem o MQTT, Já que eu entendi que é para uma outra pessoa colocar dados em determinada coordenada e não preciso disso para o meu projeto. Por favor, me ajude, Eu preciso que os dados da minha horta sejam acessados sem o cabo USB do arduino para que a bomba libere água.
Laysa, você pode usar sim MQTT. Por exemplo, veja este post sobre monitoramento e controle de um LED com MQTT: https://www.filipeflop.com/blog/controle-monitoramento-iot-nodemcu-e-mqtt/
Fica aqui meu alertar, tem um esp8266 ching link que não roda todas as bibliotecas, não entendi ainda o porque, mas fica aqui minha experiencia pessoal
Muito bom, com sua ajuda consegui fazer funcionar o esp8266, já estava achando que meu esp8266 estava com defeito, kkkkk
Aguardando a parte 3. Muito bom!
Luciano, muito obrigado!
Também no aguardo da parte 3 Pedro!
Show de bola!
Alguma dica para fazer este projeto com termômetro laser?
Elton, boa tarde.
Não é possível fazer este projeto com este tipo de termômetro.
Sem contar a parte de interface e comunicação com Arduino (algo que já é um desafio em si, devido aos leitores não serem padronizados quanto à comunicação com outros equipamentos), o termômetro laser não mede temperatura ambiente.
Logo, não se aplica ao propósito do projeto.
acredito que seu proposito é ler a temperatura de uma superficie (para isso server termometro a laser). Se você consegue traduzir a leitura para dentro do arduino, é só formar o payload e usa-lo. Entre em contato, talvez possa ajuda-lo.
Pedro Bertoleti eu estou tendo dificuldades para fazer o meu ESP8266 conectar na rede Wi-Fi. Eu fiz a upload do código conforme o Pedro Minatel fez, mas quando eu abro o meu monitor serial ele não mostra que recebeu um IP a única coisa que o monitor serial mostra é “wi-fi evt: 7” o que isso significa? Eu tenho que configurar o meu roteador? por favor me ajuda estou perdido.
estou desenvolvendo uma estação meteorologica completa com dht22, ldr, bmp180, biruta, anemometro, pluviometro, sensor de raios uv e sensor de poeira e fumaça, eu consigo jogar todos esses dados com estes programas, é claro sei q terei de aumentar o progarma, mas a comunicação vai dar conta?