Esp32 does not connect to the server

I’m having problems connecting the esp32 to the hive mq server, the esp’s connection to wifi works normally but it can’t connect to MQTT, here’s the code:

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

// Definições de credenciais Wi-Fi e MQTT
const char* ssid = “xxxxx”; // Substitua pelo seu SSID
const char* password = “xxxxxxxxxx”; // Substitua pela sua senha
const char* mqttServer = “27874f98269d4dbf9d7xxxxxxxxxxx.s1.eu.hivemq.cloud”; // Seu broker MQTT
const int mqttPort = 8883; // Porta do broker MQTT

// Configurações do cliente MQTT
WiFiClient espClient; // Usando WiFiClient
PubSubClient client(espClient);

// Função de callback para mensagens recebidas
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Mensagem recebida no tópico: “);
Serial.print(topic);
Serial.print(” com payload: ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}

// Função para conexão Wi-Fi
void setup_wifi() {
delay(10);
Serial.print("Conectando ao WiFi ");
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}

Serial.println(“\nConectado ao WiFi”);
Serial.print("Endereço IP: ");
Serial.println(WiFi.localIP());
}

void reconnect() {
// Tentar reconectar ao broker
while (!client.connected()) {
Serial.print(“Tentando conectar ao MQTT…”);
if (client.connect(“pedro”, “Belson123@”, NULL)) {
Serial.println(“Conectado ao MQTT”);
client.subscribe(“tensao”, 1);
client.subscribe(“corrente”, 1);
client.subscribe(“potencia”, 1);
} else {
Serial.print("Falha na conexão, código: ");
Serial.println(client.state());
delay(5000);
}
}
}

void setup() {
Serial.begin(115200);
setup_wifi();

client.setServer(mqttServer, mqttPort);
client.setCallback(callback); // Definindo a função de callback
}

void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();

// Publicar dados dinâmicos
static unsigned long lastPublish = 0;
if (millis() - lastPublish > 2000) { // Publica a cada 2 segundos
lastPublish = millis();

int tensao_value = random(100, 121);  // Valor de tensão entre 100 e 120
float corrente_value = random(10, 51) / 10.0;  // Valor de corrente entre 1.0 e 5.0
float potencia_value = tensao_value * corrente_value;

client.publish("tensao", String(tensao_value).c_str(), true);
client.publish("corrente", String(corrente_value).c_str(), true);
client.publish("potencia", String(potencia_value).c_str(), true);

}
}

Hello @predro

Welcome to the HiveMQ Community! Feel free to explore the fully functional code below that I use on my ESP32 device to connect to HiveMQ Cloud. You can adapt it as needed to fit your specific requirements.

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

//---- WiFi settings
const char* ssid = "XXXXXXXXXX"; // replace with your WiFi SSID
const char* password = "XXXXXXXXXX"; // replace with your WiFi Password

//---- HiveMQ Cloud Broker settings
const char* mqtt_server = "XXXXXXXXXX"; // replace with your HiveMQ Cluster URL
const char* mqtt_username = "XXXXXXXXXX"; // replace with your Username
const char* mqtt_password = "XXXXXXXXXX"; // replace with your Password
const int mqtt_port = 8883;

WiFiClientSecure espClient;  
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (500)
char msg[MSG_BUFFER_SIZE];
int value = 0;

// HiveMQ Cloud Let's Encrypt CA certificate (hardcoded)
static const char *root_ca PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
)EOF";

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}


void reconnect() {
  // Loop until we’re reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection… ");
    // MQTT client ID
    String clientId = "ESP32Client";
    // Attempt to connect
    if (client.connect(clientId.c_str(), mqtt_username, mqtt_password)) {
      Serial.println("connected!");
      // Once connected, publish an announcement…
      client.publish("testTopic", "Hello World!");
      // … and resubscribe
      client.subscribe("testTopic");
    } else {
      Serial.print("failed, rc = ");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  delay(500);
  // When opening the Serial Monitor, select 9600 Baud
  Serial.begin(9600);
  delay(500);

  setup_wifi();

  espClient.setCACert(root_ca);
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  unsigned long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "Hello World! #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("testTopic", msg);
  }
}

Kind regards,
Diego from HiveMQ Team

Many thanks, Diego. First time success with an ESP32WROVER module (yay). I gather that TLS encryption is essential/required for connecting with HiveMQ, even with the free serverless cluster setup; no TLS, no connection.

As I understand it, I can reuse the Root CA certificate (I obtained one from letsencrypt) in multiple connected client devices, so long as each one has a unique client ID and perhaps also unique credentials, though the only strict requirement is a unique client ID. Is that more or less correct? I am basically an RF guy, have only enough software knowledge to be dangerous. Thank you! Stuckey

Hello @Stuckeymax ,

Thank you for these additional details!

You are absolutely correct - TLS is required when connecting to HiveMQ Cloud serverless and starter editions, including TLS-SNI.

The Root CA certificate from Let’s Encrypt can be used as many times as you’d like - this is not a client certificate for mTLS (mutual TLS), and is instead a server CA file citing that the HiveMQ broker certificate is signed by a trusted source - in this case, Let’s Encrypt. Some devices do not automatically trust certificates signed by authorities, and in these cases providing the root CA will allow trust.

You are also correct in that a unique client ID will be required - credentials can be used by multiple connecting clients to be assigned the role that matches with those credentials. The client identifier itself is what is used to specify each unique connecting client, and therefore will need to be distinct between each client - otherwise, they will start to take over each others sessions, or be rejected entirely!

Best,
Aaron from the HiveMQ Team

Thank you for the pointers, Aaron. I’ve got a couple of ESP32 IoT units linked and synced, publishing to HiveMQ and a Python program linked and working well. I obtained a root CA certificate from letsencrypt, and it’s working well.

I’m guessing that with the free serverless cluster version, that there’s no way to publish a message to a specific ClientID, that messages published to a specific topic are sent to all client IDs. The messages itself could contain a specified ClientID along with other information, separated by commas, for instance, as a means of sending a message to a specific unit or units.

Is there a means of sending a message to, say, just one ClientID in the paid, $250/mo version, or is it a better way of doing things in MQTT to publish by topic and let the message specify the specific receivers?

The whole publish/subscribe way of doing things used by MQTT, placing all operations in external but connected blocks, so that I’ve got monitoring clients, a separate but linked email sending app, a database and so on, all linked via MQTT and HiveMQ. Nice.

Best regards,

Stuckey