Arduino and MQTT

Hello

I am having a lot of connectivity trouble with my Arduino to my MQTT server. My setup is a Mosquitto Broker on a local computer and then I am trying to have my Arduino subscribe to the Topic "outTopic" and publish to the Topic "inTopic". My arduino is using the Arduino Wifi Shield to connect to my router. I have already updated my IDE to the latest version and my wifi shield to the newest firmware. I have no problem connecting to the router. I have run the WebServer script on my Arduino and it worked perfectly fine. The problem I am having is when the code gets to "if (!client.connect("Arduino"))" it just fails to connect to the server and just does nothing. Any suggestions on what I should do to fix the issue. Below are the code and the resulting serial output. The serial commands are just for troubleshooting. I am using the PubSubClient, from Arduino Client for MQTT · knolleary

/*
Basic MQTT example

** - connects to an MQTT server**
** - publishes "hello world" to the topic "outTopic"**
** - subscribes to the topic "inTopic"**
*/
#include <SPI.h>
#include <WiFi.h>
#include <PubSubClient.h>
// Update these with values suitable for your network.
char ssid[] = "#######"; // your network SSID (name)
char pass[] = "#######"; // your network password
int status = WL_IDLE_STATUS; // the Wifi radio's status
byte server[] = {###,###,#,#};
void callback(char* topic, byte* payload, unsigned int length) {
** // handle message arrived**
}
WiFiClient wifiClient;
PubSubClient client(server, 1883, callback, wifiClient);
void setup()
{
//Initialize serial and wait for port to open:
** Serial.begin(9600);**
** while (!Serial) {**
** ; // wait for serial port to connect. Needed for Leonardo only**
** }**
** // check for the presence of the shield:**
** if (WiFi.status() == WL_NO_SHIELD) {**
** Serial.println("WiFi shield not present");**
** // don't continue:**
** while (true);**
** }**
** String fv = WiFi.firmwareVersion();**
** if ( fv != "1.1.0" )**
** Serial.println("Please upgrade the firmware");**
** // attempt to connect to Wifi network:**
** while ( status != WL_CONNECTED) {**
** Serial.print("Attempting to connect to WPA SSID: ");**
** Serial.println(ssid);**
** // Connect to WPA/WPA2 network:**
** status = WiFi.begin(ssid, pass);**
** // wait 10 seconds for connection:**
** delay(10000);**
** }**
** // you're connected now, so print out the data:**
** Serial.print("You're connected to the network");**
** printCurrentNet();**
** printWifiData();**

** delay(1000);**

** if (!client.connected())**
** {**
** Serial.println("client.connected Passed");**

** if (!client.connect("Arduino")) // Fails everytime right here**
** Serial.println("client.connect FAILED");**

** if (!client.publish("outTopic","hello world"))**
** Serial.println("client.publish FAILED");**

** if (!client.subscribe("inTopic"))**
** Serial.println("client.subscribe FAILED");**

** Serial.println("Publication and Subscription are done");**
** }**
** else**
** Serial.println("Connection Failed");**
}
void loop()
{
** client.loop();**
}
void printWifiData() {
** // print your WiFi shield's IP address:**
** IPAddress ip = WiFi.localIP();**
** Serial.print("IP Address: ");**
** Serial.println(ip);**
** Serial.println(ip);**
** // print your MAC address:**
** byte mac[6];**
** WiFi.macAddress(mac);**
** Serial.print("MAC address: ");**
** Serial.print(mac[5], HEX);**
** Serial.print(":");**
** Serial.print(mac[4], HEX);**
** Serial.print(":");**
** Serial.print(mac[3], HEX);**
** Serial.print(":");**
** Serial.print(mac[2], HEX);**
** Serial.print(":");**
** Serial.print(mac[1], HEX);**
** Serial.print(":");**
** Serial.println(mac[0], HEX);**
}
void printCurrentNet() {
** // print the SSID of the network you're attached to:**
** Serial.print("SSID: ");**
** Serial.println(WiFi.SSID());**
** // print the MAC address of the router you're attached to:**
** byte bssid[6];**
** WiFi.BSSID(bssid);**
** Serial.print("BSSID: ");**
** Serial.print(bssid[5], HEX);**
** Serial.print(":");**
** Serial.print(bssid[4], HEX);**
** Serial.print(":");**
** Serial.print(bssid[3], HEX);**
** Serial.print(":");**
** Serial.print(bssid[2], HEX);**
** Serial.print(":");**
** Serial.print(bssid[1], HEX);**
** Serial.print(":");**
** Serial.println(bssid[0], HEX);**
** // print the received signal strength:**
** long rssi = WiFi.RSSI();**
** Serial.print("signal strength (RSSI):");**
** Serial.println(rssi);**
** // print the encryption type:**
** byte encryption = WiFi.encryptionType();**
** Serial.print("Encryption Type:");**
** Serial.println(encryption, HEX);**
** Serial.println();**
}

Attempting to connect to WPA SSID: ######
You're connected to the networkSSID: ######
BSSID: #########
signal strength (RSSI): ###
Encryption Type:#

IP Address: ########
#########
MAC address: #########
client.connected Passed
client.connect FAILED
client.publish FAILED
client.subscribe FAILED
Publication and Subscription are done

Hi Ajarduino426

byte server[] = {###,###,#,#};
...
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);

What IP addresses are you using for the Arduino and the server running the broker?

Have you tried testing connection to the broker using a differetn MQTT client, such as MQTT.fx?

Regards

Ray

I have tried connecting to the server through multiple applications other than the Arduino. And i have successfully connected. I know the Mosquitto Broker works.

What IP addresses are you using for the Arduino and the server running the broker?

Could you also post your mosquitto.conf file.

Are you getting any relevant messages in your mosquitto output or log file?

Are you using SSL/TLS on the broker server?

Ok i just checked my Mosquitto Log files and my arduino can connect fine but then I get an error. "Socket read error on client (null), disconnecting". Any suggestions how to fix this.

Ok I got it working by commenting out the _client.stop()

boolean PubSubClient::connected() {
int rc = (int)_client->connected();
if (!rc) //_client->stop();
return rc;
}

in the Arduino WiFi.cpp library. I think there is something wrong with the Wifi.cpp file. If anyone wants to find the real error be my guest.

Looking at the examples with the PubSubClient library, none of them calls connected() before calling connect().

So the side effect of connected() that you discovered doesn't happen.

And the documentation on connected() does not mention that it calls stop().

I guess the easier fix is to remove the if statement with the client.connected() from the program.

By the way, the code you posted for connected() is different from the latest version of the library on GitHub. I don't think the differences change this problem but there may be improvements in other parts of the library.

boolean PubSubClient::connected() {
   boolean rc;
   if (_client == NULL ) {
      rc = false;
   } else {
      rc = (int)_client->connected();
      if (!rc) _client->stop();
   }
   return rc;
}

ADDED ...

Looking further into the PubSubClient code, I began to doubt that my suggestion of removing the if (!client.connected()). This is because the first thing that the connect() method does is test if !connected() :frowning:

I found this issue raised a while ago on the Mosquitto Launchpad page:

The symptoms and the workaround are the same as you experienced. Nicholas O'Leary who wrote PubSubClient said that he was able to reproduce the problem and fixed it in his library.

So, definitely worth retesting with the latest version of PubSubClient.

can someone pls explain me how to execute this program and how its working in detail..i am new to arduino and mqtt..kindly help me out here

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
byte mac[] = { 0x78, 0x45, 0xC4, 0xAA, 0xE5, 0x6F };
byte server[] = { 192, 168, 1, 50 };
byte ip[] = { 192, 168, 1, 240 };

int sensorPin=5;
int lastTemperature;
unsigned long lastTime;
char buffer[10];

void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived (no messages expected though)
}

EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);

void setup() {
Ethernet.begin(mac, ip);
if (client.connect("arduinoClient")) {
client.publish("demo/status/arduino01","online");
lastTemperature=0;
lastTime=0;
}
}

void loop() {
int reading=analogRead(sensorPin);
int temperature = ((reading * 0.004882)-0.50)*100;
if(temperature!=lastTemperature) {
if(millis()>(lastTime+1000)) {
sprintf(buffer,"%d",temperature);
client.publish("demo/device/arduino01",buffer);
lastTemperature=temperature;
lastTime=millis();
}
}
client.loop();
}

thanks in advance..kindly reply asap