Error called on mqtt.publish after a while of running the program

382 Views Asked by At
Traceback (most recent call last):
File "<stdin>", line 115, in wind_Speed_Pulse
File "<stdin>", line 65, in publish_Wind_Speed
File "umqtt/simple.py", line 134, in publish
OSError: [Errno 104] ECONNRESET

'''Import Libraries'''
from machine import ADC, Pin
from umqtt.simple import MQTTClient
import micropython
import network
import time


'''Weather Sensor Constants'''
WIND_DIRECTION_PIN    = 0
WIND_SPEED_PIN        = 14
RAINFALL_AMOUNT_PIN   = 12


'''Global Variables'''
pulse_duration  = 0
start_time      = 0
stop_time       = 0
pulse_count     = 0
state           = 0
counter         = 0
last_speed      = 0
Ar              = 1.585
B               = 0.52225 


'''MQTT Server Parameters'''
MQTT_CLIENT_ID      = "Weather Station Vcom"
MQTT_BROKER         = "broker.mqttdashboard.com"
MQTT_USER           = ""
MQTT_PASSWORD       = ""
MQTT_TOPIC_RAIN     = "vcom/weather/rain"
MQTT_TOPIC_WIND     = "vcom/weather/wind"
MQTT_TOPIC_DIR      = "vcom/weather/direction"


'''WiFi Parameters'''
WIFI_NAME     = "Embeded"
WIFI_PASSWORD = "password"


'''Connect ESP8266 to WiFi''' 
def connect_WiFi():
    print("Connecting to WiFi", end="")
    sta_if = network.WLAN(network.STA_IF)
    sta_if.active(True)
    sta_if.connect(WIFI_NAME, WIFI_PASSWORD)
    while not sta_if.isconnected():
      print(".", end="")
      time.sleep(0.1)
    print(" Connected!")


'''Connect to MQTT Broker'''
def connect_MQTT_broker():
    print("Connecting to MQTT server... ", end="")
    client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, user=MQTT_USER, password=MQTT_PASSWORD)
    client.connect()
    print("Connected!")
    return client


'''Publish Variables'''
def publish_Wind_Speed(wind_speed):
        client.publish(MQTT_TOPIC_WIND, str(wind_speed))
        
def publish_Wind_Direction(direction):
        client.publish(MQTT_TOPIC_DIR, direction)
        
def publish_check_Rain():
        client.publish(MQTT_TOPIC_RAIN, "It's raining")
        

'''Interrupt called upon high pulse. Start and stop time when pulse is high. when clk starts,
pulse_count set to 1. When clk stops, pulse_count set to 0'''
def start_Calc_Time():
    global start_time
    global stop_time
    global pulse_count
    global pulse_duration
    
    if(pulse_count == 0):
        start_time = time.time_ns()
        time.sleep(0.005)
        pulse_count = 1
        return
    
    if(pulse_count == 1):
        stop_time = time.time_ns()
        time.sleep(0.005)
        pulse_count = 0
        return
    

'''Calculate the speed of the anemometer'''
def calculate_Speed(pulse_time):
    if(pulse_time == 0):
        return 0
    else: speed = round(Ar * (1 / (pulse_time / 1000000000)) + B, 3)# / 1000 * 3600
    time.sleep(0.01)
    return speed


'''Calculate and publish wind Speed'''
def wind_Speed_Pulse(wind_sensor):
    if(wind_sensor.value() == 1):
        start_Calc_Time()
        pulse_duration = start_time - stop_time
        wind_speed = calculate_Speed(pulse_duration)
        if(pulse_duration > 10000000):
            time.sleep(0.01)
            if(wind_speed>0 and wind_speed<70):
                time.sleep(0.01)
                print(wind_speed)
                publish_Wind_Speed(wind_speed)
                


'''Calculate the direction of the wind and map to directions'''
def wind_Direction(dir_sensor):
    
    if(dir_sensor>2.6 and dir_sensor<2.7):
        direction = "north"
    elif(dir_sensor>1.6 and dir_sensor<1.7):
        direction = "north-east"
    elif(dir_sensor>0.3 and dir_sensor<0.4):
        direction = "east"
    elif(dir_sensor>0.6 and dir_sensor<0.7):
        direction = "south-east"
    elif(dir_sensor>0.96 and dir_sensor<1.06):
        direction = "south"
    elif(dir_sensor>2.1 and dir_sensor<2.2):
        direction = "south-west"
    elif(dir_sensor>3.15 and dir_sensor<3.25):
        direction = "west"
    elif(dir_sensor < 2.95 or dir_sensor > 3.05):
        direction = "north-east"
    else: direction = "north-west"
    time.sleep(3)
    publish_Wind_Direction(direction)


'''Check if it is raining'''
def check_Rain():        
    publish_check_Rain()
    time.sleep(0.02)
         
         
try:
    connect_WiFi() #Connect to WiFi
    client = connect_MQTT_broker() #Connect to MQTT Broker      
    while True:
        wind_sensor = Pin(WIND_SPEED_PIN, Pin.IN)
        dir_sensor = (ADC(WIND_DIRECTION_PIN).read()) * (3.3 / 1023.0)
        rain_sensor = Pin(RAINFALL_AMOUNT_PIN, Pin.IN, Pin.PULL_UP)
        wind_sensor.irq(trigger = Pin.IRQ_RISING, handler = wind_Speed_Pulse)
        rain_sensor.irq(trigger = Pin.IRQ_FALLING, handler = check_Rain())
        wind_Direction(dir_sensor)
except KeyboardInterrupt:
    print("STOP!!")

The code is basically used to power a weather station with an ESP8266. Once the readings are measured and the speed is calculated, the speed is to be published to an MQTT broker called "broker.mqttdashboard.com". When I run the code, it starts of perfectly fine for around 5-10 minutes. After this, the error attached above starts occurring. I don't really know how to continue in this. I tried to check the file the error was occurring in and I didn't figure out why the error occurred.

1

There are 1 best solutions below

0
On

I also run into a similar problem on pi pico using the same library. It seems publishing alone does not help to keep the connection open and it closes after 60 seconds. I added a ping after each publish and it helped to keep the connection open.

Consider using the robust version of the library.