O ArduinoMqttClient é a biblioteca MQTT oficial mantida pela Arduino e roda em tudo, do UNO R4 WiFi e do Nano 33 IoT às placas MKR e ao ESP32. Este guia percorre a API do ArduinoMqttClient na ordem em que você vai usá-la: configurar, conectar, fazer poll, publicar, receber e definir uma mensagem will. Todos os exemplos se conectam a um broker real, para você testar enquanto lê.
Por Que Escolher o ArduinoMqttClient
O ArduinoMqttClient envolve qualquer objeto Client do Arduino, como WiFiClient, WiFiSSLClient, EthernetClient ou um cliente celular, e acrescenta MQTT 3.1.1 por cima. Sua escolha de design mais marcante é tratar tanto as mensagens enviadas quanto as recebidas como streams, então você nunca precisa de um buffer do tamanho da sua maior mensagem.
| Recurso | ArduinoMqttClient |
|---|---|
| Protocolo | MQTT 3.1.1 |
| QoS de publicação | 0, 1 e 2 |
| QoS de inscrição | 0, 1 e 2 |
| Retained messages | Sim |
| Mensagem will | Sim, em stream com beginWill() / endWill() |
| Tratamento do payload | Em stream (print() / read()) |
| Modelo de eventos | Polling com poll(), callback ao receber mensagem |
| Mantenedor | Arduino |
Se você já conhece o PubSubClient, o tutorial do PubSubClient para Arduino é um bom ponto de comparação; as duas bibliotecas resolvem o mesmo problema com escolhas diferentes.
Instalando a Biblioteca
Abra Tools → Manage Libraries na Arduino IDE, procure por "ArduinoMqttClient" e instale. Você também precisa da biblioteca de rede da sua placa:
| Placa | Biblioteca de rede | Cliente sem criptografia | Cliente TLS |
|---|---|---|---|
| UNO R4 WiFi | WiFiS3 | WiFiClient |
WiFiSSLClient |
| Nano 33 IoT, MKR WiFi 1010 | WiFiNINA | WiFiClient |
WiFiSSLClient |
| ESP32 | WiFi (core) | WiFiClient |
WiFiClientSecure |
| Placas com shield Ethernet | Ethernet | EthernetClient |
Não incluso |
Configurando o Cliente
Crie primeiro o cliente de rede e depois passe-o para o MqttClient:
#include <WiFiNINA.h> // ou WiFiS3.h, WiFi.h ...
#include <ArduinoMqttClient.h>
WiFiClient net;
MqttClient mqttClient(net);
Antes de chamar connect(), defina os parâmetros da sessão:
mqttClient.setId("acm-51e09b"); // client ID, nunca vazio
mqttClient.setUsernamePassword("YOUR_USERNAME", "YOUR_PASSWORD"); // opcional
mqttClient.setKeepAliveInterval(30 * 1000L); // milissegundos!
mqttClient.setConnectionTimeout(10 * 1000L); // milissegundos
mqttClient.setCleanSession(true);
Atenção às unidades: diferentemente do PubSubClient, os valores de keep alive e de timeout são em milissegundos. Passar 30 em vez de 30000 vira um keep alive de zero segundos após a divisão inteira, o que desativa completamente o keep alive; assim, conexões mortas passam despercebidas pelo broker e a sua mensagem will nunca é disparada.
Conectando e Lendo o connectError()
connect(host, port) retorna 1 em caso de sucesso e 0 em caso de falha. Quando falha, connectError() informa o motivo:
| connectError() | Constante | Significado e solução |
|---|---|---|
| -2 | MQTT_CONNECTION_REFUSED |
O socket não pôde ser aberto: problema de Wi-Fi, DNS, porta ou TLS |
| -1 | MQTT_CONNECTION_TIMEOUT |
Sem CONNACK a tempo: tipo de porta errado ou link ruim |
| 0 | MQTT_SUCCESS |
Conectado |
| 1 | MQTT_UNACCEPTABLE_PROTOCOL_VERSION |
O broker rejeitou o MQTT 3.1.1 (raro) |
| 2 | MQTT_IDENTIFIER_REJECTED |
Client ID vazio ou não permitido |
| 3 | MQTT_SERVER_UNAVAILABLE |
O broker não está aceitando conexões agora |
| 4 | MQTT_BAD_USER_NAME_OR_PASSWORD |
Credenciais erradas |
| 5 | MQTT_NOT_AUTHORIZED |
Cliente sem permissão, por exemplo quando o client ID não corresponde às credenciais |
Uma função de conexão completa e reutilizável:
bool connectMqtt(const char* host, int port) {
Serial.print("Connecting to ");
Serial.print(host);
Serial.print(':');
Serial.println(port);
if (!mqttClient.connect(host, port)) {
Serial.print("MQTT connect failed, connectError = ");
Serial.println(mqttClient.connectError());
return false;
}
Serial.println("MQTT connected");
return true;
}
Para testes, use o broker.connectmq.com na porta 1883, o servidor MQTT público (gratuito), pensado para testes e protótipos. Ele aceita conexões anônimas com qualquer client ID único e não vazio. Mantenha seus topics sob um prefixo único, como connectmq/demo/<your-id>/, e não publique nada sensível.
Por Que o poll() Importa
O poll() é o coração do ArduinoMqttClient. Cada chamada:
- Lê os bytes recebidos do cliente de rede e interpreta os pacotes completos.
- Chama o seu callback
onMessage(ou disponibiliza a mensagem paraparseMessage()). - Responde aos handshakes de QoS 1 e QoS 2 das mensagens recebidas.
- Envia um PINGREQ quando o intervalo de keep alive está prestes a expirar.
Se o poll() não for chamado por mais tempo que o intervalo de keep alive, o broker fecha a conexão. Evite chamadas de delay() mais longas que uma fração do keep alive e substitua-as por temporização baseada em millis():
unsigned long lastSend = 0;
void loop() {
mqttClient.poll();
if (millis() - lastSend >= 10000) {
lastSend = millis();
// publique aqui
}
}
Publicando Mensagens
Publicar é um stream em três etapas:
// Mensagem simples com QoS 0
mqttClient.beginMessage("connectmq/demo/acm-51e09b/temperature");
mqttClient.print(22.7);
mqttClient.endMessage();
// Retida, QoS 1
mqttClient.beginMessage("connectmq/demo/acm-51e09b/status", true, 1);
mqttClient.print("online");
mqttClient.endMessage();
A assinatura completa é beginMessage(topic, retain = false, qos = 0, dup = false). Há também uma sobrecarga que recebe o tamanho do payload de antemão, beginMessage(topic, size, retain, qos, dup). Quando você souber o tamanho exato, use-a: assim a biblioteca pode gravar os dados direto na rede, em vez de armazenar a mensagem inteira primeiro, o que faz diferença com payloads grandes em placas com pouca RAM.
endMessage() retorna 1 em caso de sucesso. Para QoS 1 e 2, a biblioteca trata os pacotes de confirmação nas chamadas seguintes de poll().
Como print() aceita números, strings e floats, você pode montar JSON sem buffer temporário:
mqttClient.beginMessage(topicTelemetry);
mqttClient.print("{\"t\":");
mqttClient.print(temperature, 2);
mqttClient.print(",\"h\":");
mqttClient.print(humidity, 1);
mqttClient.print("}");
mqttClient.endMessage();
Recebendo Mensagens
Inscreva-se após uma conexão bem-sucedida e de novo a cada reconexão, quando você usa clean session:
mqttClient.onMessage(onMqttMessage);
mqttClient.subscribe("connectmq/demo/acm-51e09b/cmd/#", 1);
O callback recebe apenas o tamanho da mensagem. Você lê o topic e consome o payload como stream:
void onMqttMessage(int messageSize) {
String topic = mqttClient.messageTopic();
Serial.print("Topic: ");
Serial.print(topic);
Serial.print(", QoS ");
Serial.print(mqttClient.messageQoS());
Serial.print(", retained ");
Serial.println(mqttClient.messageRetain());
char payload[128];
int n = 0;
while (mqttClient.available() && n < (int)sizeof(payload) - 1) {
payload[n++] = (char)mqttClient.read();
}
payload[n] = '\0';
Serial.println(payload);
}
Os bytes que você não ler são descartados quando a próxima mensagem chega. Isso torna seguras as mensagens grandes demais: basta parar de ler no limite do seu buffer.
Como alternativa ao callback, você pode chamar int size = mqttClient.parseMessage(); em loop() e tratar as mensagens ali mesmo quando size for maior que zero. Use um estilo ou o outro, não os dois.
Mensagens Will
Uma mensagem will (Last Will and Testament) é publicada pelo broker se o seu dispositivo se desconectar sem se despedir, por exemplo após uma queda de energia na fazenda ou perda do Wi-Fi no galpão. Configure-a antes de connect():
const char willTopic[] = "connectmq/demo/acm-51e09b/status";
mqttClient.beginWill(willTopic, true, 1); // retida, QoS 1
mqttClient.print("offline");
mqttClient.endWill();
if (connectMqtt("broker.connectmq.com", 1883)) {
mqttClient.beginMessage(willTopic, true, 1);
mqttClient.print("online");
mqttClient.endMessage();
}
Publicar um online retido no mesmo topic logo após conectar dá a todos os dashboards um indicador de presença preciso: online enquanto conectado e offline assim que o broker detecta que o dispositivo sumiu, o que acontece após cerca de um intervalo e meio de keep alive.
Um Padrão Completo e Seguro para Reconexões
Junte as peças com este checklist:
- Conecte o Wi-Fi e espere um endereço IP válido.
- Defina ID, credenciais, keep alive e will.
- Conecte; em caso de falha, imprima
connectError()e tente de novo após um intervalo que cresce a cada falha. - Em caso de sucesso, registre o
onMessage, faça as inscrições e publiqueonlineretido. - Em
loop(), verifique o Wi-Fi, verifiquemqttClient.connected(), chamepoll()e publique com um timer baseado emmillis().
Versões deste padrão específicas para cada placa estão no tutorial Arduino UNO R4 WiFi MQTT e no guia de MQTT com Nano 33 IoT e WiFiNINA. Para um projeto mais amplo, o tutorial IoT com ESP32 mostra como o lado do dispositivo se integra a dashboards e alertas.
Erros Comuns com o ArduinoMqttClient
- Chamar
beginWill()depois deconnect(). O will faz parte do pacote CONNECT, então precisa ser configurado antes. - Inscrever-se apenas no
setup(). Após uma reconexão com clean session, o broker esqueceu suas inscrições. Inscreva-se na sua função de conexão. - Reutilizar um client ID em várias placas. O broker desconecta a sessão mais antiga toda vez que outra placa se conecta, gerando um loop de reconexão sem fim.
- Publicar de dentro do
onMessage. Funciona, mas termine primeiro de ler o payload recebido; caso contrário, os bytes não lidos se perdem. - Esquecer o
endMessage(). Sem ele, nada é enviado, e a próxima chamada debeginMessage()falha.
Produção: TLS e Credenciais
Em implantações reais, troque para um cliente TLS e a porta 8883 e autentique-se com suas próprias credenciais. Um broker MQTT gerenciado como o ConnectMQ emite usuário, senha e client ID para cada broker que você cria no portal; o client ID fica vinculado a essas credenciais, então defina-o exatamente com setId(). O certificado do ConnectMQ vem da Let's Encrypt, em que os módulos Wi-Fi das placas Arduino atuais confiam de fábrica. Revise as boas práticas de segurança MQTT antes de colocar em produção.
Comece a Usar o ConnectMQ
O ConnectMQ é um broker MQTT gerenciado, ou seja, um broker MQTT na nuvem com MQTT 3.1.1 e 5.0, TLS e WebSockets, além de um portal que inclui um cliente MQTT no navegador, um explorador de topics ao vivo e alertas por limite. É a forma mais fácil de ver o que o seu sketch com ArduinoMqttClient está realmente enviando. Crie um broker Serverless gratuito em app.connectmq.com, sem precisar de cartão de crédito.
Perguntas frequentes
O ArduinoMqttClient é melhor que o PubSubClient?
Nenhum dos dois é melhor em todos os casos. O ArduinoMqttClient suporta publicação com QoS 1 e 2 e envia payloads em stream, enquanto o PubSubClient é menor e tem uma enorme base de exemplos. Escolha o ArduinoMqttClient para placas Arduino oficiais e quando precisar de QoS.
O ArduinoMqttClient suporta MQTT 5?
Não, ele implementa MQTT 3.1.1. Brokers modernos atendem clientes 3.1.1 e 5.0 lado a lado, então o seu dispositivo ainda pode compartilhar topics com aplicações MQTT 5.
Por que minha conexão com o ArduinoMqttClient cai a cada minuto?
Normalmente o poll() não é chamado com frequência suficiente, o keep alive foi definido em segundos em vez de milissegundos ou outro cliente usa o mesmo client ID.
Qual é o tamanho máximo de uma mensagem?
A biblioteca envia os payloads em stream, então o limite é principalmente o do seu broker. O servidor MQTT público em broker.connectmq.com aceita até 64 KB por mensagem; o plano Serverless gratuito permite 256 KB.



