Problem with Multiple ESP8266 and MQTT. Blocked Sockets?

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
hsmade
Posts: 4
Joined: Thu Jan 12, 2017 9:31 pm

Re: Problem with Multiple ESP8266 and MQTT. Blocked Sockets?

Post by hsmade » Sat Jan 14, 2017 2:27 pm

Well, in object oriented programming (ie. using classes), it makes perfect sense to have more sockets open to one endpoint.
For example, when having multiple sensors that have their own class.

I can't reproduce this issue all the time though, so there must be something else contributing or causing the issue.

Wim

jpj
Posts: 60
Joined: Sat Dec 10, 2016 3:07 pm

Re: Problem with Multiple ESP8266 and MQTT. Blocked Sockets?

Post by jpj » Sat Jan 14, 2017 2:42 pm

I have also been using MQTT with an Adafruit Huzzah. I have the esp8266 subscribed to a broker, messages being received and actions taken like lighting LEDs and scrolling text across a matrix, all working fine.

I tried to "publish" a message from the esp8266 back to the broker over the same "subscribe" channel and the code crashed. I haven't had time to dig deeper into the issue, but it seemed like "a single instance of the MQTTClient class" should be all that is required as pythoncoder writes.

torwag
Posts: 220
Joined: Fri Dec 13, 2013 9:25 am

Re: Problem with Multiple ESP8266 and MQTT. Blocked Sockets?

Post by torwag » Sat Jan 14, 2017 4:19 pm

I believe it has nothing to do with two sockets on the same unit.
As I understood this was only an example.
The original poster, said he used two units each connected to the MQTT broker.
Again, I can not see how micropython or the umqtt lib has anything to do with this. As there is no way for a unit to "see" in any way what kind or how many other devices are connected to the broker as well.
The only thing I could thing of would be some wrong settings in the MQTT broker, which for whatever reasons reject a second esp8266 but still allows a PC to connect.

However, all this is speculation I guess to really solve this mystery, we need to code of both units and possibly the MQTT broker config file

User avatar
The Royal We
Posts: 8
Joined: Thu Jan 12, 2017 5:40 pm

Re: Problem with Multiple ESP8266 and MQTT. Blocked Sockets?

Post by The Royal We » Sat Jan 21, 2017 5:35 am

However, all this is speculation I guess to really solve this mystery, we need to code of both units and possibly the MQTT broker config file
I have been planning on posting my code on github for everyone to take a look at. However, before posting I wanted to have clean code with nice comments. While going through this process I managed to get it operating as intended. I am now able to send data via MQTT from one ESP8266 to the other.

I wish I knew for sure what I did differently. I changed the mosquitto config file back to default and simplified the code. Maybe there is something in that, or maybe I am off. Anyway, thank you to everyone that commented. I appreciate the help!

If there is still any interest in viewing the code and config files please let me know.

BigL3g
Posts: 3
Joined: Thu May 19, 2016 1:23 am

Re: Problem with Multiple ESP8266 and MQTT. Blocked Sockets?

Post by BigL3g » Wed Jan 25, 2017 11:11 am

I am having similar issues with MQTT.

If your code is cleaned up for sharing will you post it as a working example? Seems like there is a gotcha that is easy to write into MQTT implementations unless specifically avoided.

I am new to MQTT so maybe we are all just following the same slightly flawed tutorials. :geek:

warren
Posts: 74
Joined: Tue Jul 12, 2016 5:47 pm

Re: Problem with Multiple ESP8266 and MQTT. Blocked Sockets?

Post by warren » Wed Feb 01, 2017 9:11 pm

This is only tangential to this specific thread, but I am learning that often with ESP units, lateral thinking can yield surprising results!

I spent the best part of a week doing various tests with multiple ESP8266 units sharing a common MQTT server. The initial observations led me to believe that it was some form of mutual interference that led the units to randomly reset every few minutes. None of them would escape a reboot after more than 20 mins...,

This behaviour was slightly worsened if they were moved further away from the MQTT server (which is also the wifi AP for all the units).

I had previously used code code which posted sensor data to a php script over http - the units were incredibly reliable, rarely resetting. So this made me rethink the 'mutual wifi distiurbace' theory. I started to feel that the existing MQTT code is susceptible to subtle timing errors on their socket code...

Then I read someone else's MQTT code on this forum (please excuse me for forgetting who it was...). I noticed that they had a delay in the code for publishing. I tried a couple of experiments with delays and within a matter of minutes I had a system which was hugely more reliable. Units now stay subscribed for hours at a time (sometimes over a day). All other factors have remained same (particularly distance from wifi/MQTT server).

It remains true that units further away (with a weaker wifi signal) are more prone to 'random resets', but overal performance is improved substantially.

If you are trying to improve your system reliability with MQTT, then do try adding a simple delay. This is a portion of my publish code:

Code: Select all

        
        mq.connect()
        mq.publish(topic, msg, retain)
        mq.disconnect()
        time.sleep(0.3)  #<== Try a delay here...
        etc
That 'time.sleep(0.3)' seems to make a big difference, although the difference between values of .1 and .5 seconds is negligible. I had tried a delay between 'publish' and 'disconnect' but this didn't really make a difference..but do experiment - it is only one line of code!

It would be really interesting to hear from people with different MQTT configurations to see whether or not the delay idea similarly improves (or worsens!) reliability...it may help the developers to come up with improvements...?

@The_Royal_We: it seems possible to me that that the changes to your Mosquitto config introduced precisely such beneficial timing changes ....

User avatar
The Royal We
Posts: 8
Joined: Thu Jan 12, 2017 5:40 pm

Re: Problem with Multiple ESP8266 and MQTT. Blocked Sockets?

Post by The Royal We » Thu Feb 02, 2017 7:45 pm

BigL3g wrote:If your code is cleaned up for sharing will you post it as a working example?
Here you go: https://github.com/andrewlrogers/Microp ... mp-Display

Hopefully this will work for you.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Problem with Multiple ESP8266 and MQTT. Blocked Sockets?

Post by pythoncoder » Fri Feb 03, 2017 7:28 am

Nice code ;)

I would raise one point. You're sending a float (as a string). In your display code you have

Code: Select all

msg = round(int(msg))
To avoid unnecessary loss of precision I'd suggest

Code: Select all

msg = round(float(msg))
Peter Hinch
Index to my micropython libraries.

User avatar
The Royal We
Posts: 8
Joined: Thu Jan 12, 2017 5:40 pm

Re: Problem with Multiple ESP8266 and MQTT. Blocked Sockets?

Post by The Royal We » Fri Feb 03, 2017 8:12 pm

Thanks @pythoncoder, that was giving me trouble and I was sure there was a solution.

chikku
Posts: 1
Joined: Wed Feb 22, 2017 7:14 pm

Re: Problem while communicating two ESP8266 with sockets

Post by chikku » Sat Mar 11, 2017 11:50 am

I am trying to communicate between two esp8266 node mcu boards without any wifi router , i wish to implement this using basic sockets , i am new to programming and this is my first project with the node mcu , any inputs would be much appreciated . Thank you ! :D this code gives me the error OSError: [Errno 103] ECONNABORTED


###########################################################################################################
#SERVER
###########################################################################################################
import socket
import time
import sys
import network


# Create Access Point
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid="ESP8266", authmode=network.AUTH_WPA_WPA2_PSK, password="password")
print ('Yaaayyy Created Access Point')

##create a socket object
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('', 31350)
#bind to port'
try:
serversocket.bind(server_address)
except socket.error as msg:
print ('Bind failed. Error Code : ' + str(msg[0]) + ' Message' + msg[1])
sys.exit()
print ('Socket bind complete')
# queue up to 10 requests
serversocket.listen(10)
print ('Socket now listening')


while True:

# establish a connection
print('waiting for a connection')
connection,client_address = serversocket.accept()
try:
print('connection from',client_address)
# Receive the data
while True:
data = connection.recv(3)
print('received "%s"' % data)
if data == b'end':
print('Socket closed')
connection.close()
serversocket.close()
break
try:
if data == b'FFF': ##edit switch function
print ("SW1")
elif data == b'SSS':
print ("SW2")
except:
print ("Input undefined",data)
continue
else:
connection,client_address = serversocket.accept()
continue

finally:
break



#Client
###########################################################################################################
import network
import time
import sys

def talk(data_to_send):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = (package_server_ip, 31350)
sock.connect(server_address)
try:
message = (data_to_send)
print (message)
sock.sendall(message)
print ('sent')
amount_received = 0
amount_expected = len(data_to_send)
while amount_received < amount_expected:
if(data_to_send == 'end'):
break
data = sock.recv(3)
amount_received += len(data)
finally:
sock.close()

#connect to esp8266 access point
sta_if = network.WLAN(network.STA_IF); sta_if.active(True)
sta_if.connect('ESP8266', 'password') # Connect to an AP (name,password)
time.sleep(5) # wait for connection to complete

state = sta_if.status()
status = ['STA_IDLE','STA_CONNECTING','STA_WRONGPWD','STA_APNOTFOUND','STA_FAIL','STA_GOTIP']
print ('Status : ',status[state])#*DEBUGGING*#
print ('Is connected to router :' , sta_if.isconnected())#*DEBUGGING*#

package_server_ip='192.168.4.1' #Default IP address of esp8266 check if correct???
talk("FFF")
talk("end")# send 3 bytes to close sockets

Post Reply