[SOLVED] Arduino Mega2560, ESP8266-01, MQTT problem receiving messages

I have an ESP8266-01 (AT command set, with 3.3v supply & level conversions) & Arduino Mega
My MQTT broker is Mosquitto on RPi 3 - Emonpi 2016
The plan is to use openHab for control

Arduino code:

includes:
WiFiEsp.h
WiFiEspClient.h
WiFiEspUdp.h
PubSubClient.h
SPI.h

IPAddress server(192,168,1,xxx); //RPi address
char ssid[] = "xxxxxxxxx"; // your network SSID (name)
char pass[] = "xxxxxxxxxx"; // your network password
int status = WL_IDLE_STATUS; // the Wifi radio's status

// Initialize the Ethernet client object
WiFiEspClient espClient;

PubSubClient client(espClient);

//SoftwareSerial soft(2,3); // RX, TX //not used
void setup() {
// initialize serial for debugging
Serial.begin(115200);
// initialize serial for ESP module
Serial1.begin(115200);
// initialize ESP module
WiFi.init(&Serial1);

// check for the presence of the shield
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue
while (true);
}

// 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);
}

// you're connected now, so print out the data
Serial.println("You're connected to the network");

//connect to MQTT server
client.setServer(server, 1883);
client.setCallback(callback);
}

//print any message received for subscribed topic
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++) {
char receivedChar = (char)payload;
Serial.print(receivedChar);
if (receivedChar == '0')
Serial.println("Off");
if (receivedChar == '1')
Serial.println("On");

}
Serial.println();
}

void loop() {
// put your main code here, to run repeatedly:
if (!client.connected()) {
reconnect();
}
client.loop();
}

void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting connection…");
// Attempt to connect, just a name to identify the client
if (client.connect("AMega","xxxxxx","xxxxxxxxxxx")) {
Serial.println("connected");
// Once connected, publish an announcement…
// client.publish("command","Hello World");
// … and resubscribe
client.subscribe("switch",0);

} else {
Serial.print("failed");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}

This connects to WiFi fine & to an MQTT broker running on a raspberry Pi(3)
(Mosquitto 1.4.10 as part of emonpi software from OpenEnergyMonitor)

Serial Monitor:

[WiFiEsp] Initializing ESP module
[WiFiEsp] Initilization successful - 1.3.0
Attempting to connect to WPA SSID: xxxxxxxxxx
[WiFiEsp] Connected to xxxxxxxxxxxx
You’re connected to the network
Attempting MQTT connection…[WiFiEsp] Connecting to xxxxxx
connected
[WiFiEsp] Disconnecting 3
Attempting MQTT connection…[WiFiEsp] Connecting to xxxxxx
connected
(It disconnects every 30 seconds or so and reconnects)

It posts to the Pi (If // client.publish(“command”,“Hello World”); is uncommented) but does not receive subscribed messages. - “Message arrived” is never printed
I also have an MQTT client on my android phone. This communicates fine with the RPi
Again the Arduino can publish to my phone but cannot receive with subscribe

I am not sure where to go next - everything I look at seems to be working but it won’t receive subscribed topics?

UPDATE:

client.subscribe(“switch”,0) returns “true” so maybe the problem is with “callback”?
No messages are printed out, I have tried many different formats
I am basically wish to use this for control The messages will generally be short!

WiFiEsp.h compiles fine for the Mega where as I had problems using ESP8266WiFi.h with board set to Mega2560 (Arduno 1.6.13 with ESP core downloaded for the ESP8266)

Error:
functional: No such file or directory
include functional

I wish to leave the ESP with AT command set & compile the code for the Mega NOT the ESP

command line publish on the Rpi works fine
$mosquitto_pub -u ‘xxxxx’ -P ‘xxxxxxx’ -t ‘switch’ -m ‘1switchon’
This is received on my android mqtt client but not the arduino

I have tried installing mosquitto on my PC…
The results are exactly the same!

I have tried an ESP8266-12 with the Mega with the same result It connects to the WiFi network & to the MQTT broker, It publishes fine client.subscribe() returns true but no messages are received

I am an amateur programmer, new to the ESP & MQTT
I am probably missing something really simple!

Any help would be appreciated

Richard

UPDATE2:

Thanks for all the replies!
The problem occurs if you call
if (!client.connected())
reconnect();
& client.loop();
every loop if the ESP is connected to an arduino via a serial connection
I believe the problem is overwhelming the connection with status messages, blocking incoming messages.

The solution is to add a 100 ms delay after client.loop() or use a non blocking technique calling
if (!client.connected())
reconnect();
& client.loop();
I tried several different delays - the incoming messages came through a delay as little as 1ms but not all messages arrived & communication seemed more reliable at 100 ms

Richard

Richard, take a look at the documentation for the esp8266 WiFi library

Down the main page a bit you’ll see this statement:

Note: if connection is established, and then lost for some reason, ESP will automatically reconnect to last used access point once it is again back on-line. This will be done automatically by Wi-Fi library, without any user intervention.

So you can ditch all of your code in the loop(). The library does the reconnection for you.

I had a similar issue and built loads of code to reconnect under all sorts of conditions, router down, comms down etc. All redundant!! :sob:

But fixed now since I ripped all the code out. :grin:

Simon

Hi simon

The problem was not with WiFi connection/disconnection but with connection to the MQTT broker
This is handled by the PubSubClient library. This is an excellent MQTT library but it needs regular calls to client.loop() (to receive messages in callback) and reconnect() (To maintain connection to the MQTT broker) All the examples with the PubSubClient library call these functions every loop. It would appear that most people use this library in sketches that are flashed to the ESP boards - in which case they work fine. The problem seems to arise if the program is used on an arduino (in my case a Mega2560 with a spare hardware serial) which is connected to an ESP via a serial connection - This connection can become overwhelmed by status messages from the ESP which block incoming messages. Outgoing messages to the MQTT broker are fine!
I am very much a newbie with regard to ESP & MQTT but this is my understanding of the situation

Regards

Richard

I’m trying to do the same thing, but feel a bit overwhelmed. Could you please post the updated code? Trying to make the arduino read several analog sensors and transmit the values over mqtt to Rpi running openhabian.

Make sure you have a timer calling the client.loop (). At least 1 second, but 10 would be more stable.

Or, at least put a delay(10000); after the client.loop(); But in general timers work better than delays.