O Arduino UNO R4 WiFi traz Wi-Fi para o conhecido formato UNO, o que o torna uma ótima primeira placa para um projeto de Arduino UNO R4 WiFi com MQTT. Neste tutorial, você vai usar a biblioteca WiFiS3 e o ArduinoMqttClient oficial para publicar leituras de um sensor analógico, receber comandos que desenham na matriz de LEDs integrada e depois passar para uma conexão TLS criptografada com suas próprias credenciais.
Como o UNO R4 WiFi Se Comunica com a Rede
O UNO R4 WiFi tem dois chips. O microcontrolador principal é um Renesas RA4M1, que executa o seu sketch. A rede fica a cargo de um módulo ESP32-S3 que funciona como coprocessador Wi-Fi. O seu sketch conversa com ele pela biblioteca WiFiS3, que vem com o pacote "Arduino UNO R4 Boards".
Essa divisão tem duas consequências práticas:
- O handshake TLS roda no módulo ESP32-S3, que já vem com um conjunto de certificados raiz comuns. Conexões criptografadas com brokers que usam certificados amplamente confiáveis, como os da Let's Encrypt, geralmente funcionam com
WiFiSSLClientsem colar nenhum certificado. - O coprocessador tem seu próprio firmware. Se as conexões se comportarem de forma estranha, atualizar esse firmware é uma das primeiras soluções a tentar.
Para o protocolo MQTT em si, você vai usar o ArduinoMqttClient, a biblioteca oficial mantida pela Arduino. Ela funciona com qualquer objeto Client, incluindo WiFiClient e WiFiSSLClient da WiFiS3.
O Que Você Precisa
| Item | Observações |
|---|---|
| Arduino UNO R4 WiFi | Não o UNO R4 Minima, que não tem rádio |
| Arduino IDE 2.x | Com "Arduino UNO R4 Boards" instalado pelo Boards Manager |
| ArduinoMqttClient | Instale pelo Gerenciador de Bibliotecas |
| Um potenciômetro ou qualquer sensor analógico | Ligado ao A0 (opcional, o código funciona com o pino flutuando) |
| Ferramentas de linha de comando do Mosquitto | Para testar a partir do seu computador |
| Uma rede Wi-Fi de 2,4 GHz | O módulo não se conecta a redes de 5 GHz |
Antes de começar, abra File → Examples → WiFiS3 → CheckFirmwareVersion e faça o upload. Se o monitor serial indicar um firmware desatualizado, atualize-o com o atualizador de firmware da Arduino IDE (Tools → Firmware Updater) ou seguindo as instruções oficiais em docs.arduino.cc.
Passo 1: Publique no Servidor MQTT Público
A primeira versão se conecta sem criptografia ao broker.connectmq.com na porta 1883, o servidor MQTT público (gratuito) oferecido pelo ConnectMQ para testes e protótipos. Conexões anônimas são aceitas desde que o client ID não esteja vazio. Use um prefixo de topic único e não envie dados privados, porque qualquer pessoa pode se inscrever nos topics do servidor MQTT público.
Crie uma segunda aba no sketch chamada arduino_secrets.h:
#define SECRET_SSID "YOUR_WIFI"
#define SECRET_PASS "YOUR_WIFI_PASSWORD"
Depois, o sketch principal:
#include <WiFiS3.h>
#include <ArduinoMqttClient.h>
#include "Arduino_LED_Matrix.h"
#include "arduino_secrets.h"
const char broker[] = "broker.connectmq.com";
const int port = 1883;
const char deviceId[] = "unor4-8d21f0"; // torne-o único
const char topicTelemetry[] = "connectmq/demo/unor4-8d21f0/telemetry";
const char topicCommand[] = "connectmq/demo/unor4-8d21f0/matrix/set";
const char topicStatus[] = "connectmq/demo/unor4-8d21f0/status";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
ArduinoLEDMatrix matrix;
unsigned long lastPublish = 0;
// Dois quadros simples para a matriz 12x8
const uint32_t FRAME_ON[] = { 0xffffffff, 0xffffffff, 0xffffffff };
const uint32_t FRAME_OFF[] = { 0x00000000, 0x00000000, 0x00000000 };
void connectWifi() {
Serial.print("Connecting to ");
Serial.println(SECRET_SSID);
while (WiFi.begin(SECRET_SSID, SECRET_PASS) != WL_CONNECTED) {
Serial.print(".");
delay(3000);
}
// A WiFiS3 pode informar 0.0.0.0 por um instante; espere um endereço real
while (WiFi.localIP() == IPAddress(0, 0, 0, 0)) delay(200);
Serial.print("\nIP address: ");
Serial.println(WiFi.localIP());
}
void onMqttMessage(int messageSize) {
String topic = mqttClient.messageTopic();
String payload;
while (mqttClient.available()) {
payload += (char)mqttClient.read();
}
Serial.print("Received on ");
Serial.print(topic);
Serial.print(": ");
Serial.println(payload);
if (payload == "ON") matrix.loadFrame(FRAME_ON);
if (payload == "OFF") matrix.loadFrame(FRAME_OFF);
}
bool connectMqtt() {
mqttClient.setId(deviceId);
mqttClient.setKeepAliveInterval(30 * 1000L); // milissegundos
// O Last Will precisa ser definido antes de connect()
mqttClient.beginWill(topicStatus, true, 1);
mqttClient.print("offline");
mqttClient.endWill();
Serial.print("Connecting to MQTT broker... ");
if (!mqttClient.connect(broker, port)) {
Serial.print("failed, error = ");
Serial.println(mqttClient.connectError());
return false;
}
Serial.println("connected");
mqttClient.onMessage(onMqttMessage);
mqttClient.subscribe(topicCommand, 1);
mqttClient.beginMessage(topicStatus, true, 1); // retida, QoS 1
mqttClient.print("online");
mqttClient.endMessage();
return true;
}
void setup() {
Serial.begin(115200);
while (!Serial && millis() < 3000) {}
matrix.begin();
connectWifi();
while (!connectMqtt()) delay(5000);
}
void loop() {
if (WiFi.status() != WL_CONNECTED) connectWifi();
if (!mqttClient.connected()) {
delay(5000);
connectMqtt();
return;
}
mqttClient.poll(); // envia os pings de keep alive e entrega as mensagens
if (millis() - lastPublish > 5000) {
lastPublish = millis();
int raw = analogRead(A0);
mqttClient.beginMessage(topicTelemetry);
mqttClient.print("{\"a0\":");
mqttClient.print(raw);
mqttClient.print(",\"rssi\":");
mqttClient.print(WiFi.RSSI());
mqttClient.print(",\"uptime\":");
mqttClient.print(millis() / 1000);
mqttClient.print("}");
mqttClient.endMessage();
}
}
Acompanhe as mensagens e desenhe na matriz a partir do seu computador:
mosquitto_sub -h broker.connectmq.com -p 1883 -i pc-8d21f0 -t "connectmq/demo/unor4-8d21f0/#" -v
mosquitto_pub -h broker.connectmq.com -p 1883 -i ctl-8d21f0 -t "connectmq/demo/unor4-8d21f0/matrix/set" -m ON
Gire o potenciômetro, e o valor de a0 deve acompanhar em até cinco segundos.
Em Que o ArduinoMqttClient Difere do PubSubClient
Se você já usou o PubSubClient, três coisas vão parecer diferentes:
- As mensagens são enviadas em stream.
beginMessage(),print()eendMessage()permitem montar um payload parte por parte, sem um grande buffer de string. Isso combina bem com a RAM do UNO R4. - As mensagens recebidas são lidas como um stream. O callback
onMessagerecebe apenas o tamanho; você chamamessageTopic()e depoisread()atéavailable()retornar zero. - Publicação com QoS 1 e 2 é suportada, assim como retained messages e um Last Will montado com
beginWill()/endWill().
Você ainda precisa chamar poll() regularmente, assim como chama loop() no PubSubClient. Chamadas longas de delay() em loop() atrasam os pings de keep alive e as mensagens recebidas. Nosso guia da biblioteca ArduinoMqttClient cobre toda a API, incluindo o significado de cada valor de connectError().
Passo 2: Arduino UNO R4 WiFi MQTT sobre TLS
Para qualquer coisa além de experimentos, use um broker privado com credenciais e TLS. Em um broker MQTT gerenciado como o ConnectMQ, você cria um broker no portal e recebe usuário, senha e client ID. Graças ao conjunto de certificados do módulo Wi-Fi, migrar para TLS exige mudar só algumas linhas:
WiFiSSLClient wifiClient; // antes era WiFiClient
MqttClient mqttClient(wifiClient);
const char broker[] = "broker.connectmq.com";
const int port = 8883; // MQTT sobre TLS
bool connectMqtt() {
mqttClient.setId("YOUR_CLIENT_ID");
mqttClient.setUsernamePassword("YOUR_USERNAME", "YOUR_PASSWORD");
mqttClient.setKeepAliveInterval(30 * 1000L);
if (!mqttClient.connect(broker, port)) {
Serial.print("TLS MQTT failed, error = ");
Serial.println(mqttClient.connectError());
return false;
}
// inscreva-se e publique como antes
return true;
}
Guarde as credenciais em arduino_secrets.h, e não no sketch principal, para não fazer commit delas por acidente. O ConnectMQ vincula os client IDs às credenciais emitidas, então copie o client ID exatamente. Em um broker privado, você também pode dispensar o prefixo connectmq/demo/ e projetar uma árvore de topics para o seu projeto. O artigo boas práticas de segurança MQTT lista outras medidas de proteção.
Projetando Topics e Payloads Que Escalam
Uma única placa no servidor MQTT público pode usar qualquer estrutura, mas vale a pena projetar os topics como se você fosse ter dez placas no mês que vem, espalhadas por uma fazenda ou por uma planta em Joinville. Uma estrutura previsível permite que dashboards se inscrevam com curingas e mantém os comandos bem separados da telemetria.
| Topic | Direção | QoS | Retido | Finalidade |
|---|---|---|---|---|
<prefix>/<deviceId>/telemetry |
A placa publica | 0 | Não | Leituras periódicas dos sensores |
<prefix>/<deviceId>/status |
A placa publica, Will | 1 | Sim | Presença online / offline |
<prefix>/<deviceId>/matrix/set |
A placa se inscreve | 1 | Não | Comandos de apps ou scripts |
<prefix>/<deviceId>/config |
A placa se inscreve | 1 | Sim | Configurações aplicadas a cada inicialização |
O topic config retido é um truque útil: publique uma vez o intervalo de publicação ou o limite desejado com a flag retain, e toda vez que a placa se reconectar ela recebe as configurações mais recentes na hora, sem nenhuma lógica extra de requisição no firmware.
Mantenha os payloads compactos. O RA4M1 do UNO R4 tem 32 KB de SRAM, o que é generoso em comparação com o UNO clássico, mas ainda é pouco, então evite montar objetos String grandes em sketches que rodam por muito tempo. Enviar em stream com print(), como no exemplo, mantém o uso de memória estável. Para entradas analógicas ruidosas, tire a média de várias amostras de analogRead() antes de publicar e considere publicar apenas quando o valor mudar mais do que um pequeno limite. Menos mensagens, e mais significativas, aliviam a rede e são mais fáceis de ler em um dashboard.
Checklist de Solução de Problemas
connectError()retorna -2 (conexão recusada) ou a chamada de conexão falha na hora: host ou porta errados, ou sem Wi-Fi. Confirme que a placa tem um endereço IP real, e não 0.0.0.0.- A 1883 sem criptografia funciona, mas a 8883 falha: atualize o firmware do módulo Wi-Fi e confirme que usou
WiFiSSLClient, e nãoWiFiClient. - Erro 4 (usuário ou senha incorretos) ou 5 (não autorizado): confira novamente os três valores do portal, incluindo o client ID.
- A conexão cai depois de um tempo: uma chamada bloqueante em
loop()impediupoll()de rodar, ou outro dispositivo usa o mesmo client ID. - Nenhuma mensagem chega:
onMessage()não foi registrado, ou você se inscreveu antes deconnect()ter sucesso. - O upload funciona, mas o monitor serial fica vazio: ajuste o monitor para 115200 baud; o R4 usa USB nativo, então abra o monitor depois que o upload terminar.
Próximos Passos
Com uma conexão confiável, adicione um sensor de verdade e monte um dashboard. Se você precisa de mais GPIOs, Bluetooth ou processamento local, um ESP32 pode ser mais adequado; o tutorial IoT com ESP32 mostra um projeto completo. Se você tem outro Arduino, o guia de MQTT com Arduino Nano 33 IoT segue o mesmo padrão de biblioteca com a WiFiNINA.
Coloque Seu UNO R4 Online com o ConnectMQ
O ConnectMQ é um broker MQTT gerenciado, ou seja, um broker MQTT na nuvem com suporte a MQTT 3.1.1 e 5.0, TLS na 8883 e WebSockets para dashboards no navegador. O portal inclui um cliente MQTT no navegador e um explorador de topics ao vivo para você ver as leituras do seu UNO chegando. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito, e migre seu sketch para TLS hoje mesmo.
Perguntas frequentes
Preciso enviar um certificado raiz para o UNO R4 WiFi?
Normalmente não. O módulo Wi-Fi ESP32-S3 traz um conjunto de certificados raiz comuns, então o WiFiSSLClient consegue verificar brokers que usam autoridades amplamente confiáveis, como a Let's Encrypt. Se a verificação falhar, atualize primeiro o firmware do módulo.
Posso usar o PubSubClient no UNO R4 WiFi?
Sim, o PubSubClient funciona com qualquer Client do Arduino, incluindo os clientes da WiFiS3. O ArduinoMqttClient é a opção com suporte oficial e acrescenta publicação com QoS 1 e 2.
O UNO R4 WiFi suporta MQTT 5?
O ArduinoMqttClient implementa MQTT 3.1.1, que o ConnectMQ suporta totalmente junto com o MQTT 5. Seus dashboards e backends com MQTT 5 podem se inscrever nos mesmos topics.
Por que meu UNO R4 WiFi mostra o IP 0.0.0.0?
A WiFiS3 pode informar que está conectada antes de o DHCP terminar. Espere até WiFi.localIP() retornar um endereço real antes de se conectar ao broker, como faz o exemplo.



