[FOR REVIEW] ESP32 fails to connect to UbiDot's MQTT broker => rc=-2 and rc=-4 failure modes

Been trying on and off for sometime to get the sample program that you posted in your tutorial for interfacing the ESP32 to UbiDots via MQTT using PubSubClient. Tried on two diff boards (DFRobot and SparkFun) but no luck. If I use a different MQTT broker (“broker.mqtt-dashboard.com”), no problems connecting to that broker. The following is the code snippet that I have been using:

/****************************************
 * Include Libraries
 ****************************************/
#include <WiFi.h>
#include <PubSubClient.h>

/****************************************
 * Define Constants
 ****************************************/
#define WIFISSID "myWIFISSID" // Put your WifiSSID here
#define PASSWORD "myPASSWORD" // Put your wifi password here
#define TOKEN "myTOKEN" // Put your Ubidots' TOKEN
#define MQTT_CLIENT_NAME "MqTtClIeNt" // MQTT client Name, please enter your own 8-12 alphanumeric character ASCII string; 
                                           //it should be a random and unique ascii string and different from all other devices

#define VARIABLE_LABEL "sensor" // Assing the variable label
#define DEVICE_LABEL "esp32" // Assig the device label

#define SENSOR 12 // Set the GPIO12 as SENSOR

char mqttBroker[]  = "things.ubidots.com";
//char mqttBroker[] = "broker.mqtt-dashboard.com";
char payload[100];
char topic[150];
// Space to store values to send
char str_sensor[10];
char str_lat[6];
char str_lng[6];

/****************************************
 * Auxiliar Functions
 ****************************************/
WiFiClient ubidots;
PubSubClient client(ubidots);

void callback(char* topic, byte* payload, unsigned int length) {
  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  String message(p);
  Serial.write(payload, length);
  Serial.println(topic);
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    
    // Attemp to connect
    if (client.connect(MQTT_CLIENT_NAME, TOKEN, "")) {
      Serial.println("Connected");
    } else {
      Serial.print("Failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 2 seconds");
      // Wait 2 seconds before retrying
      delay(2000);
    }
  }
}

/****************************************
 * Main Functions
 ****************************************/
void setup() {
  Serial.begin(115200);
  WiFi.begin(WIFISSID, PASSWORD);
  // Assign the pin as INPUT 
  pinMode(SENSOR, INPUT);

  Serial.println();
  Serial.print("Wait for WiFi...");
  
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback);  
}

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

  sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
  sprintf(payload, "%s", ""); // Cleans the payload
  sprintf(payload, "{\"%s\":", VARIABLE_LABEL); // Adds the variable label
  
  float sensor = analogRead(SENSOR); 
  float lat = 6.101;
  float lng= -1.293;

  /* 4 is mininum width, 2 is precision; float value is copied onto str_sensor*/
  dtostrf(sensor, 4, 2, str_sensor);
  dtostrf(lat, 4, 2, str_lat);
  dtostrf(lng, 4, 2, str_lng);  
  
  sprintf(payload, "%s {\"value\": %s", payload, str_sensor); // Adds the value
  sprintf(payload, "%s, \"context\":{\"lat\": %s, \"lng\": %s}", payload, str_lat, str_lng); // Adds coordinates
  sprintf(payload, "%s } }", payload); // Closes the dictionary brackets
  Serial.println("Publishing data to Ubidots Cloud");
  client.publish(topic, payload);
  client.loop();
  delay(1000);
}

And the errors I get are:

MQTT_CONNECTION_TIMEOUT     -4
MQTT_CONNECT_FAILED         -2

From the Arduino window, I see the following:

which I believe others have commented about.

Note 1: From UbiDot’s Devices webpage, I see that it tried to communicate because the “Last Activity” was 5 minutes ago.
Note 2: I have checked the token a couple of times and it is good.
Note 3: For PubSubClient I have used versions 2.5 and 2.6. Version 2.6 uses
MQTT_VERSION MQTT_VERSION_3_1_1

image

Any suggestions how I can get the ESP32’s to communicate with UbiDots?

Hello, @statespacesystems,

At first, I thoughte that I was an issue related with the Ubidots MQTT Broker, but we didn’t present any inconsistency on it during the last hours. I made a simple test using MQTT Lens to verify the right functionality of it, and as you can see everything is working properly:

To connect the ESP32 over MQTT you can refer to this guide, which provides a detailed explanation of how to establish the communication with the Ubidots Broker.

I hope this would help you!

All the best,
Maria C.

Maria,

Thank you for your quick response. I followed (checked and double checked) your tutorial: http://help.ubidots.com/connect-your-devices/connect-the-esp32-devkitc-to-ubidots-in-under-30-minutes and the above code snippet came from that tutorial. The guide that you refer to is for Python whilst I am using C++ on the ESP32 via the arduino framework. Kinda strange when UbiDots acknowledges the MQTT request but times out.

Hello @statespacesystems,

Regrettably, I’m not able to reproduce your inconvenience. As you can see below, I made a test with the sample code provided in the article mentioned and everything is working properly:

The Ubidots MQTT Broker didn’t present any downtime during last hours. For this reason, I highly recommend you verify if the TOKEN assigned is the right one. To learn how to get your Ubidots TOKEN please refer to this article.

All the best,
Maria C.

Hi,
I’ve been taking same problem.
But, after a couple weeks of test using the PubSubClient lib and getting same position from Ubidots, I decided to compare the updates to ubidots cloud from the PubSubClient code from my sketch with CURL update commands. What happened? The curl command updates all time on ubidots!
So I gave up PubSubClient and now I’m using HTTPClient lib. It works all quite every time. Take a look at the simple code:

#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = **<YOUR_SSID_NETWORK>**;
const char* password = **<PASSWORD>**;

void setup() {

	Serial.begin(115200);
	delay(4000);   //Delay needed before calling the WiFi.begin

	WiFi.begin(ssid, password);

	while (WiFi.status() != WL_CONNECTED) { //Check for the connection
		delay(1000);
		Serial.println("Connecting to WiFi..");
	}

	Serial.println("Connected to the WiFi network");
}

void loop() {
	if (WiFi.status() == WL_CONNECTED) {   //Check WiFi connection status

		HTTPClient http;

		http.begin("http://things.ubidots.com/api/v1.6/devices/**<YOUR_DEVICE_LABEL>**?token=**<YOUR_TOKEN>**");  //Specify destination for HTTP request
		http.addHeader("Content-Type", "application/json");             //Specify content-type header
		
		int httpResponseCode = http.POST("{\"temperatura\":20.4,\"umidade\":67.33,\"pressao\":93500,\"altitude\":911,\"reset\":1,\"memory\":145007,\"luminosidade\":7}");   //Send the actual POST request

		if (httpResponseCode>0) {
			String response = http.getString();                       //Get the response to the request
			Serial.println(httpResponseCode);   //Print return code
			Serial.println(response);           //Print request answer
		}
		else {
			Serial.print("Error on sending POST: ");
			Serial.println(httpResponseCode);
		}
		http.end();  //Free resources
	}
	else {
		Serial.println("Error in WiFi connection");
	}
	delay(10000);  //Send a request every 10 seconds
}

Good luck!

Cristiano

2 Likes

Hey @Cristiano,

Thanks for sharing your thoughts with the community! :smiley:

I would love if you give me a little bit more info about the inconvenience presented during your tests using MQTT so I can try to reproduce it and verify from where became the issue.

All the best,
Maria C.

Hello @mariahernandez!

I confes you I didn’ get deeper do really understand what was wrong with PubSubClient lib.
The fact was that using it my sensor values didn’t update to ubitos cloud all time publish method was called, but just some of them.
I’ve been reading a lot about ESP32 and available libs to use with it. And I’ve found most libs to use with ESP8266. I don’t know, but I think the problem could be an incompatible PubSubClient lib with ESP32 and it’ WiFi lib. Could it be?

PS: the clean HTTPClient lib has been working with no problem for three days ago from now.

I can´t thank you enough!
I was having troubles connecting the esp32 to some networks…weird stuff really, mostly on old routers and such.
This code connected instantly! genius

I found this video as a problem solver, This may help you.
All MQTT Errors explained very well and Suggester Different troubleshooting techniques