
ESP32 publicando dados no Mosquitto
Passo a passo para conectar o ESP32 a um broker MQTT Eclipse Mosquitto, tratando autenticação e formato JSON de telemetria.
Objetivo e arquitetura
Este tutorial monta um caminho mínimo e autenticado para publicar telemetria de um ESP32 em um broker Eclipse Mosquitto hospedado no Ubuntu. O fluxo é:
| 1 | ESP32 -> Wi-Fi -> Mosquitto -> mosquitto_sub / aplicação supervisória |
O exemplo usa MQTT 3.1.1, um tópico próprio para o dispositivo e uma carga JSON pequena. Os nomes de usuário, senha, endereço IP e SSID abaixo são placeholders: substitua-os localmente e nunca publique credenciais no firmware ou no repositório.
Instalar o Mosquitto no Ubuntu
Em um Ubuntu sob seu controle, instale o broker e os clientes de teste:
| 1 | sudo apt update |
| 2 | sudo apt install mosquitto mosquitto-clients |
| 3 | sudo systemctl enable --now mosquitto |
| 4 | sudo systemctl status mosquitto |
Para uma instalação de homologação, confirme se a porta MQTT está ouvindo:
| 1 | sudo ss -ltnp | grep 1883 |
Não exponha um broker anônimo diretamente à internet. Mesmo em uma rede industrial, trate o broker como um serviço autenticado e restrinja a porta no firewall à rede necessária.
Criar usuário e exigir autenticação
Crie o arquivo de senhas com o comando oficial mosquitto_passwd. A senha é solicitada de forma interativa:
| 1 | sudo mosquitto_passwd -c /etc/mosquitto/passwd esp32-homolog |
| 2 | sudo chown mosquitto:mosquitto /etc/mosquitto/passwd |
| 3 | sudo chmod 640 /etc/mosquitto/passwd |
Crie um arquivo de configuração separado, por exemplo /etc/mosquitto/conf.d/iiot.conf:
| 1 | listener 1883 |
| 2 | allow_anonymous false |
| 3 | password_file /etc/mosquitto/passwd |
Reinicie e valide os logs:
| 1 | sudo systemctl restart mosquitto |
| 2 | sudo journalctl -u mosquitto -n 50 --no-pager |
Para produção ou redes não confiáveis, configure TLS e use a porta 8883 com certificados válidos. A porta 1883 deste tutorial serve para uma rede de homologação protegida.
Testar o broker antes do ESP32
Abra um terminal assinante:
| 1 | mosquitto_sub -h 192.168.1.10 -p 1883 \ |
| 2 | -u esp32-homolog -P 'SENHA_LOCAL' \ |
| 3 | -t 'iiot/esp32/esp32-01/telemetria' -v |
Em outro terminal, publique uma mensagem:
| 1 | mosquitto_pub -h 192.168.1.10 -p 1883 \ |
| 2 | -u esp32-homolog -P 'SENHA_LOCAL' \ |
| 3 | -t 'iiot/esp32/esp32-01/telemetria' \ |
| 4 | -m '{"device":"esp32-01","temperature":24.7,"rssi":-61}' |
Se a mensagem aparecer no primeiro terminal, o endereço, a porta, a autenticação e o tópico estão coerentes. O endereço 192.168.1.10 é apenas um exemplo de rede local; use o IP real do seu broker.
Configurar o projeto PlatformIO
No platformio.ini, declare a biblioteca PubSubClient:
| 1 | [env:esp32dev] |
| 2 | platform = espressif32 |
| 3 | board = esp32dev |
| 4 | framework = arduino |
| 5 | monitor_speed = 115200 |
| 6 | lib_deps = |
| 7 | knolleary/PubSubClient |
O exemplo usa WiFiClient e PubSubClient. Ele reconecta sem prender o loop em um while infinito e publica uma carga JSON compacta:
| 1 | #include <Arduino.h> |
| 2 | #include <WiFi.h> |
| 3 | #include <PubSubClient.h> |
| 4 | |
| 5 | const char* WIFI_SSID = "SSID_LOCAL"; |
| 6 | const char* WIFI_PASSWORD = "SENHA_WIFI"; |
| 7 | const char* MQTT_HOST = "192.168.1.10"; |
| 8 | const uint16_t MQTT_PORT = 1883; |
| 9 | const char* MQTT_USER = "esp32-homolog"; |
| 10 | const char* MQTT_PASSWORD = "SENHA_MQTT"; |
| 11 | const char* MQTT_TOPIC = "iiot/esp32/esp32-01/telemetria"; |
| 12 | |
| 13 | WiFiClient network; |
| 14 | PubSubClient mqtt(network); |
| 15 | unsigned long lastMqttAttempt = 0; |
| 16 | unsigned long lastPublish = 0; |
| 17 | |
| 18 | void connectWifi() { |
| 19 | if (WiFi.status() == WL_CONNECTED) return; |
| 20 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); |
| 21 | } |
| 22 | |
| 23 | void connectMqtt() { |
| 24 | if (WiFi.status() != WL_CONNECTED || mqtt.connected()) return; |
| 25 | if (millis() - lastMqttAttempt < 5000) return; |
| 26 | |
| 27 | lastMqttAttempt = millis(); |
| 28 | const char* clientId = "esp32-01"; |
| 29 | if (mqtt.connect(clientId, MQTT_USER, MQTT_PASSWORD)) { |
| 30 | Serial.println("MQTT conectado"); |
| 31 | } else { |
| 32 | Serial.printf("MQTT recusado, rc=%d\n", mqtt.state()); |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | void publishTelemetry() { |
| 37 | if (!mqtt.connected()) return; |
| 38 | |
| 39 | char payload[128]; |
| 40 | const float temperature = 24.7f; // substitua pela leitura do sensor |
| 41 | snprintf(payload, sizeof(payload), |
| 42 | "{\"device\":\"esp32-01\",\"temperature\":%.2f,\"rssi\":%d}", |
| 43 | temperature, WiFi.RSSI()); |
| 44 | |
| 45 | if (!mqtt.publish(MQTT_TOPIC, payload)) { |
| 46 | Serial.println("Falha ao publicar telemetria"); |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | void setup() { |
| 51 | Serial.begin(115200); |
| 52 | mqtt.setServer(MQTT_HOST, MQTT_PORT); |
| 53 | connectWifi(); |
| 54 | } |
| 55 | |
| 56 | void loop() { |
| 57 | connectWifi(); |
| 58 | connectMqtt(); |
| 59 | mqtt.loop(); |
| 60 | |
| 61 | if (millis() - lastPublish >= 10000) { |
| 62 | lastPublish = millis(); |
| 63 | publishTelemetry(); |
| 64 | } |
| 65 | } |
O mqtt.loop() precisa ser chamado com frequência. Ele processa o protocolo e mantém o keepalive; um delay longo ou um processamento bloqueante pode fazer o broker considerar o cliente desconectado. O clientId também precisa ser único por placa.
Diagnóstico rápido
- rc=4 normalmente indica usuário ou senha incorretos.
- rc=5 indica que o broker não autorizou a operação.
- rc=-2 aponta para falha ao resolver o host ou abrir a conexão.
- rc=-4 costuma ser timeout: confirme IP, porta, rota e firewall.
- Se o assinante não receber nada, compare o tópico caractere por caractere.
- O PubSubClient usa um buffer padrão pequeno; para JSON maiores, dimensione-o explicitamente com mqtt.setBufferSize(512) e valide o tamanho da mensagem antes de publicar.
Segurança e operação
Não coloque senhas reais no código, em commits ou em exemplos públicos. Para uma rede não confiável, troque a conexão simples por TLS na porta 8883, valide o certificado do broker e configure ACLs com o menor privilégio necessário. Em produção, monitore espaço em disco, logs, reinícios e quantidade de clientes; a autenticação sozinha não substitui segmentação de rede e backup da configuração.
Fontes oficiais
- Eclipse Mosquitto — métodos de autenticação
- Eclipse Mosquitto — referência do mosquitto.conf
- Eclipse Mosquitto — mosquitto_passwd
- Eclipse Mosquitto — mosquitto_pub e mosquitto_sub
- PubSubClient — repositório e limitações
