ESP32 e Arduino

Tutorial ESP32-C6 MQTT: da Placa Wi-Fi 6 ao Broker na Nuvem com Arduino

Faça um ESP32-C6 publicar no broker.connectmq.com com o Arduino core 3.x, controle seu LED RGB pela linha de comando e entenda as diferenças em relação ao ESP32 clássico dual-core.

Placa ESP32-C6 DevKitC-1 com LED RGB aceso conectada a um broker na nuvem em um tutorial esp32-c6 mqtt
Rode isso no seu próprio broker MQTTTenha um broker MQTT privado e gerenciado no plano Free e comece com exemplos de código prontos.
Teste grátis Exemplos de código Sem cartão de crédito

Este tutorial ESP32-C6 MQTT coloca uma placa C6 publicando telemetria e recebendo comandos em cerca de quinze minutos. Você vai instalar o core Arduino correto, publicar a temperatura interna do chip no broker.connectmq.com, controlar o LED RGB da placa a partir do seu notebook e descobrir quais hábitos do ESP32 clássico não valem mais.

O que torna o ESP32-C6 diferente

O ESP32-C6 não é apenas um ESP32 mais novo. Ele usa uma arquitetura de CPU diferente e um conjunto de rádios diferente, e algumas dessas mudanças aparecem imediatamente nos sketches Arduino.

Recurso ESP32 clássico ESP32-C6
CPU Dual-core Xtensa LX6, até 240 MHz RISC-V single-core, até 160 MHz, mais um núcleo RISC-V de baixo consumo
Wi-Fi 802.11 b/g/n, 2,4 GHz 802.11ax (Wi-Fi 6), apenas 2,4 GHz
Bluetooth Classic e BLE 4.2 Apenas BLE 5, sem Classic
802.15.4 Não Sim (Thread, Zigbee)
Core Arduino 2.x e 3.x Apenas 3.x
USB Chip USB-UART externo USB Serial/JTAG nativo mais UART na maioria dos DevKits
LED da placa (DevKitC-1) Normalmente um LED simples no GPIO 2 LED RGB endereçável no GPIO 8

Para MQTT, as consequências práticas são:

  • Você precisa do Arduino core 3.x. O C6 não está disponível nos pacotes de placas 2.x.
  • Há apenas um núcleo de aplicação. Qualquer código que fixe tarefas no core 1 precisa mudar para o core 0.
  • A serial pode aparecer em outra porta. Se nada for impresso, ative "USB CDC On Boot" ou conecte na porta UART.
  • Wi-Fi 6 é opcional, não obrigatório. O C6 também se conecta a access points 802.11n comuns. Ele continua sem enxergar redes de 5 GHz.

O protocolo MQTT em si não se importa com nada disso. O mesmo código PubSubClient que roda em um ESP32 roda em um C6, por isso este tutorial se concentra nos detalhes de configuração que costumam confundir.

Pré-requisitos

  • Uma placa ESP32-C6. Os passos assumem a Espressif ESP32-C6-DevKitC-1; outras placas C6 funcionam com pequenas mudanças de pinos.
  • Arduino IDE 2.x.
  • O pacote de placas esp32 da Espressif Systems, versão 3.0 ou mais recente, pelo Boards Manager.
  • A biblioteca PubSubClient de Nick O'Leary, pelo Library Manager.
  • Clientes de linha de comando do Mosquitto no seu computador.

Configurando o Arduino para o ESP32-C6

  1. Abra o Boards Manager, procure esp32 e instale ou atualize o pacote da Espressif para uma versão 3.x.
  2. Selecione Tools > Board > esp32 > ESP32C6 Dev Module.
  3. Na DevKitC-1, conecte a porta USB-C identificada como UART para a experiência mais simples. Se usar a porta identificada como USB, defina Tools > USB CDC On Boot > Enabled para que o Serial seja mapeado para o USB nativo.
  4. Escolha a porta COM correspondente e faça upload de um sketch vazio uma vez para confirmar que o toolchain funciona.

Se o upload falhar com timeout de conexão, segure BOOT, pressione RESET, solte BOOT e tente novamente. Isso força o bootloader da ROM.

O sketch ESP32-C6 MQTT

O sketch publica a leitura do sensor de temperatura interno, a intensidade do sinal Wi-Fi e o heap livre a cada dez segundos, assina um topic de comando do LED e informa o estado do LED como mensagem retida.

#include <WiFi.h>
#include <PubSubClient.h>

const char* WIFI_SSID     = "YOUR_WIFI_SSID";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
const char* MQTT_HOST     = "broker.connectmq.com";
const uint16_t MQTT_PORT  = 1883;
const char* PREFIX        = "connectmq/demo/c6x41z";   // troque pelo seu próprio id aleatório

WiFiClient   net;
PubSubClient mqtt(net);
String clientId;
String topicTelemetry, topicLedSet, topicLedState, topicStatus;
unsigned long lastPublish = 0;
uint8_t ledR = 0, ledG = 0, ledB = 0;

void setLed(uint8_t r, uint8_t g, uint8_t b) {
  ledR = r; ledG = g; ledB = b;
  rgbLedWrite(RGB_BUILTIN, r, g, b);   // API do Arduino core 3.x
  char state[40];
  snprintf(state, sizeof(state), "{\"r\":%u,\"g\":%u,\"b\":%u}", r, g, b);
  mqtt.publish(topicLedState.c_str(), state, true);
}

void onMessage(char* topic, byte* payload, unsigned int length) {
  String msg;
  for (unsigned int i = 0; i < length; i++) msg += (char)payload[i];
  msg.trim();
  msg.toUpperCase();
  Serial.printf("Command on %s: %s\n", topic, msg.c_str());

  if (msg == "OFF")        setLed(0, 0, 0);
  else if (msg == "RED")   setLed(40, 0, 0);
  else if (msg == "GREEN") setLed(0, 40, 0);
  else if (msg == "BLUE")  setLed(0, 0, 40);
  else if (msg == "WHITE") setLed(30, 30, 30);
}

void connectWifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.printf("\nIP %s, RSSI %d dBm\n", WiFi.localIP().toString().c_str(), WiFi.RSSI());
}

void connectMqtt() {
  while (!mqtt.connected()) {
    Serial.print("Connecting to MQTT... ");
    if (mqtt.connect(clientId.c_str(), topicStatus.c_str(), 1, true, "offline")) {
      Serial.println("connected");
      mqtt.publish(topicStatus.c_str(), "online", true);
      mqtt.subscribe(topicLedSet.c_str(), 1);
    } else {
      Serial.printf("failed, state %d, retrying in 5 s\n", mqtt.state());
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  delay(500);

  clientId       = "esp32c6-" + String((uint32_t)ESP.getEfuseMac(), HEX);
  topicTelemetry = String(PREFIX) + "/telemetry";
  topicLedSet    = String(PREFIX) + "/led/set";
  topicLedState  = String(PREFIX) + "/led/state";
  topicStatus    = String(PREFIX) + "/status";

  connectWifi();
  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  mqtt.setCallback(onMessage);
  mqtt.setBufferSize(512);
  connectMqtt();
  setLed(0, 0, 0);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) connectWifi();
  if (!mqtt.connected()) connectMqtt();
  mqtt.loop();

  if (millis() - lastPublish >= 10000) {
    lastPublish = millis();
    char payload[160];
    snprintf(payload, sizeof(payload),
             "{\"chipTemp\":%.1f,\"rssi\":%d,\"freeHeap\":%lu,\"uptime\":%lu}",
             temperatureRead(), WiFi.RSSI(),
             (unsigned long)ESP.getFreeHeap(), millis() / 1000);
    mqtt.publish(topicTelemetry.c_str(), payload);
    Serial.println(payload);
  }
}

O sensor de temperatura interno mede o die do chip, não o ambiente, então espere valores vários graus acima da temperatura ambiente. Ele é útil como sinal de saúde e como valor de demonstração sem fiação.

Testando as mensagens ESP32-C6 MQTT

Abra um terminal e assine tudo abaixo do seu prefixo:

mosquitto_sub -h broker.connectmq.com -p 1883 -i c6-viewer-x41z -t "connectmq/demo/c6x41z/#" -v

Você deve ver status online, o estado retido do LED e uma mensagem de telemetria a cada dez segundos. Em um segundo terminal, envie um comando:

mosquitto_pub -h broker.connectmq.com -p 1883 -i c6-cmd-x41z -t "connectmq/demo/c6x41z/led/set" -m "green" -q 1

O LED RGB fica verde e um novo estado retido aparece. Como o estado é retido, qualquer cliente que assinar depois descobre imediatamente a cor atual. A área pública do ConnectMQ não exige conta, mas é visível para todos, então use apenas dados de demonstração, nunca dados de produção; a página do servidor MQTT público (gratuito) explica seus limites, incluindo 10 mensagens por segundo por cliente.

Portando código do ESP32 clássico para o C6

A maioria dos sketches compila sem alterações. Estas são as mudanças que você provavelmente vai precisar:

  1. Fixação de tarefas. Substitua xTaskCreatePinnedToCore(..., 1) pelo core 0 ou chame xTaskCreate. O guia ESP32 FreeRTOS MQTT mostra uma organização de tarefas que funciona nas duas famílias de chips com essa única mudança.
  2. Pinos de LED. digitalWrite(2, HIGH) não acende nada em uma DevKitC-1. Use rgbLedWrite(RGB_BUILTIN, r, g, b).
  3. Pinos de ADC. O C6 tem um único ADC nos GPIO 0 a 6. Números de pino como 34 ou 36 dos exemplos do ESP32 clássico não existem.
  4. APIs obsoletas. O core 3.x renomeou ou removeu várias funções; por exemplo, neopixelWrite virou rgbLedWrite e a API de PWM LEDC mudou para ledcAttach. Compare os erros do compilador com as notas de migração na documentação do Arduino-ESP32.
  5. Bluetooth Classic. O BluetoothSerial não é suportado. Use BLE.

Se você compila com PlatformIO, defina a plataforma para uma versão que traga o Arduino core 3.x para o C6; a configuração MQTT com PlatformIO mostra um arquivo de projeto reproduzível.

Solução de problemas

  • mqtt.state() retorna -2. A conexão TCP falhou. Verifique se a placa realmente tem um endereço IP e se sua rede permite saída na porta 1883. Algumas redes de convidados a bloqueiam; tente a porta 8883 com TLS.
  • mqtt.state() retorna 2. O broker rejeitou o client ID. Na área pública ele precisa ser não vazio e único, o que o sufixo do MAC do eFuse garante.
  • Conecta e cai a cada poucos segundos. Dois dispositivos estão usando o mesmo client ID, e cada nova conexão derruba a outra. Isso acontece muito quando você grava o mesmo ID fixo em duas placas.
  • O Wi-Fi nunca conecta a um roteador Wi-Fi 6. Confirme que a banda de 2,4 GHz está ativa e não escondida atrás de um band steering que empurra os clientes apenas para 5 GHz. Redes somente WPA3 também podem causar problemas; tente o modo misto WPA2/WPA3.
  • Sem saída serial. Alterne o USB CDC On Boot ou mude para a porta UART.

Indo para produção em um broker na nuvem

Para dispositivos reais, passe para TLS na porta 8883 com credenciais. Crie um broker em app.connectmq.com e copie o usuário, a senha e o client ID gerados. Troque WiFiClient por WiFiClientSecure, carregue o certificado ISRG Root X1 com net.setCACert(...), defina a porta como 8883 e passe as credenciais para mqtt.connect("YOUR_CLIENT_ID", "YOUR_USERNAME", "YOUR_PASSWORD", ...). O C6 lida com o handshake TLS com tranquilidade, embora demore um pouco mais do que em um ESP32 clássico de 240 MHz.

A partir daí, o explorador de topics ao vivo do portal mostra as mensagens do seu C6 conforme chegam, e a visão de dispositivos agrupa as placas por site e linha se você usar nomes de topic no estilo ISA-95. Se você é novo em brokers, o que faz um broker MQTT é uma introdução curta, e o tutorial de IoT com ESP32 lista todos os projetos desta série.

Rode sua frota de ESP32-C6 no ConnectMQ

O ESP32-C6 é uma ótima escolha para novos projetos: eficiência do Wi-Fi 6, BLE 5 e um toolchain moderno. Combine-o com um broker MQTT na nuvem que você não precisa operar. O ConnectMQ, um broker MQTT gerenciado, oferece TLS na porta 8883, MQTT 3.1.1 e 5.0 e um plano gratuito Serverless sem cartão de crédito, para você sair do servidor MQTT público e chegar a dispositivos autenticados em minutos. Se quiser propriedades do MQTT 5 no C6, o caminho é o ESP-IDF; veja esp-mqtt com MQTT 5.

Perguntas frequentes

O ESP32-C6 suporta MQTT sobre Wi-Fi 6?

Sim. O MQTT roda sobre TCP, então funciona em qualquer padrão Wi-Fi que o C6 suporte, incluindo 802.11ax em 2,4 GHz. O Wi-Fi 6 ajuda principalmente na eficiência energética e em redes congestionadas.

Posso usar Thread ou Zigbee no C6 para chegar a um broker MQTT?

O rádio do C6 suporta 802.15.4, mas o MQTT precisa de um caminho IP até o broker. Uma rede Thread precisa de um border router, e dispositivos Zigbee normalmente precisam de um gateway que traduza para MQTT.

Por que meu sketch antigo de ESP32 não compila para o C6?

O C6 exige o Arduino core 3.x, que mudou várias APIs, e não tem Bluetooth Classic nem o segundo núcleo. Atualize as funções renomeadas e remova a fixação no core 1.

O sensor de temperatura interno é preciso o bastante para medir o ambiente?

Não. Ele mede o die do chip e fica mais quente que o ambiente. Use um sensor externo, como DHT22 ou BME280, para leituras ambientes.

Artigos relacionados

Exemplo de MQTT com ESP-IDF: Monte um Cliente esp-mqtt do Zero

Monte um projeto ESP-IDF a partir de uma pasta vazia com o componente esp-mqtt: configuração do Wi-Fi em modo station, o handler de eventos MQTT, publicação e inscrição, propriedades do MQTT 5 e TLS com o bundle de certificados.

8 min de leitura

Usando os Recursos do MQTT 5 do esp-mqtt no ESP32 com ESP-IDF

Um projeto ESP-IDF prático que ativa o MQTT 5.0 no esp-mqtt e usa user properties, expiração de mensagens, topic aliases, expiração de sessão e response topics com um broker MQTT 5 real.

8 min de leitura

Todos os artigos →

Seu broker MQTT privado está a poucos cliques de distância

Crie uma conta, receba as credenciais do seu broker e conecte seu primeiro dispositivo — sem servidores para instalar, atualizar ou escalar.