ESP8266 goes down after sometime [SOLVED]

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
navy
Posts: 15
Joined: Sat May 04, 2019 6:37 am

ESP8266 goes down after sometime [SOLVED]

Post by navy » Sat May 04, 2019 6:45 am

Hi!
I have nodemcu v3 or v2 with flashed micropython inside.
There are small python script inside,that reads bme280 and send data to mqtt server of thingspeak.
So, after power on it works several days and poweroff suddenly. LED is off and no data send to server.

I wondering whys its happend? where is problem? in code or in hardware?
Please help.

Here is sources of a script:
https://pastebin.com/fF2UgVVQ
Last edited by navy on Fri May 24, 2019 7:47 am, edited 1 time in total.

User avatar
jimmo
Posts: 206
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia

Re: ESP8266 goes down after sometime

Post by jimmo » Sat May 04, 2019 8:19 am

What makes it start working again once it gets to this state? Does the reset button fix it or do you need to remove power altogether? What power source are you using?

Do you have a multimeter that you can verify that it's still being powered?

kevinkk525
Posts: 391
Joined: Sat Feb 03, 2018 7:02 pm

Re: ESP8266 goes down after sometime

Post by kevinkk525 » Sat May 04, 2019 12:33 pm

It most likely freezes. This happens to all my esp8266 every few days. Using a software watchdog with timer interrupts that resets the board helps with that. This happens especially with cheap chinese boards and bad power supplies.

Of course there's always the possibility of your code failing becasue you don't catch any errors like an error during the connection to the server. You have to debug that too, it might not be the case that your esp freezes.


This is the stripped down version of my wdt, should give you an idea of what to do:

Code: Select all

class WDT:
    def __init__(self, id=0, timeout=120):
        self._timeout = timeout / 10
        self._counter = 0
        self._timer = machine.Timer(id)
        self.init()

    def _wdt(self, t):
        self._counter += self._timeout
        if self._counter >= self._timeout * 10:
            machine.reset()

    def feed(self):
        self._counter = 0

    def init(self, timeout=None):
        timeout = timeout or self._timeout
        self._timeout = timeout
        self._timer.init(period=int(self._timeout * 1000), mode=machine.Timer.PERIODIC, callback=self._wdt)

    def deinit(self):  # will not stop coroutine
        self._timer.deinit()

            
First thing however should be to catch exceptions and make sure you're code doesn't get stuck on an error.

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

Re: ESP8266 goes down after sometime

Post by pythoncoder » Sun May 05, 2019 5:45 pm

I notice you're using `umqtt.simple`. This really isn't suitable for long term use because it does not properly recover from WiFi outages. Brief outages can occur for various reasons including bursts of RF interference. You might like to read this - follow the link to the resilient driver. Also these notes on why achieving reliable WiFi applications is difficult.

There are also hardware issues as referenced by @kevinkk525: I agree with his suggestion of a software WDT,
Peter Hinch

navy
Posts: 15
Joined: Sat May 04, 2019 6:37 am

Re: ESP8266 goes down after sometime

Post by navy » Sun May 05, 2019 5:56 pm

Wow, thank you so much for that deep info, guys!!!

I just changed a power source, and now waiting for freeze. I use old phone charger on 5v. Just changed for different one.
Will use WDT and mqtt driver for a current project with ESP32.

navy
Posts: 15
Joined: Sat May 04, 2019 6:37 am

Re: ESP8266 goes down after sometime

Post by navy » Sun May 05, 2019 6:26 pm

kevinkk525 wrote:
Sat May 04, 2019 12:33 pm

Code: Select all

class WDT:
    def __init__(self, id=0, timeout=120):
        self._timeout = timeout / 10
        self._counter = 0
        self._timer = machine.Timer(id)
        self.init()

    def _wdt(self, t):
        self._counter += self._timeout
        if self._counter >= self._timeout * 10:
            machine.reset()

    def feed(self):
        self._counter = 0

    def init(self, timeout=None):
        timeout = timeout or self._timeout
        self._timeout = timeout
        self._timer.init(period=int(self._timeout * 1000), mode=machine.Timer.PERIODIC, callback=self._wdt)

    def deinit(self):  # will not stop coroutine
        self._timer.deinit()

            
Could you kindly show me, how i should use this code? how i should proper integrate it in my code?
i just haven't any experience with object oriented programming in python.

navy
Posts: 15
Joined: Sat May 04, 2019 6:37 am

Re: ESP8266 goes down after sometime

Post by navy » Sun May 05, 2019 6:40 pm

jimmo wrote:
Sat May 04, 2019 8:19 am
What makes it start working again once it gets to this state? Does the reset button fix it or do you need to remove power altogether? What power source are you using?

Do you have a multimeter that you can verify that it's still being powered?
when i tried to measure voltage on esp pins, esp just started. So, i conclude, that problem is with power.
I tried to measure voltage on power source, but multimeter don't show me any values, so i just change it, maybe its broken. Or battery in my multimeter is low.
I've tested reset button after ESP waked up because of my measure tries. So i cant be sure reset working when ESP in that down state.

kevinkk525
Posts: 391
Joined: Sat Feb 03, 2018 7:02 pm

Re: ESP8266 goes down after sometime

Post by kevinkk525 » Sun May 05, 2019 7:08 pm

navy wrote:
Sun May 05, 2019 6:26 pm
kevinkk525 wrote:
Sat May 04, 2019 12:33 pm

Code: Select all

class WDT:
    def __init__(self, id=0, timeout=120):
        self._timeout = timeout / 10
        self._counter = 0
        self._timer = machine.Timer(id)
        self.init()

    def _wdt(self, t):
        self._counter += self._timeout
        if self._counter >= self._timeout * 10:
            machine.reset()

    def feed(self):
        self._counter = 0

    def init(self, timeout=None):
        timeout = timeout or self._timeout
        self._timeout = timeout
        self._timer.init(period=int(self._timeout * 1000), mode=machine.Timer.PERIODIC, callback=self._wdt)

    def deinit(self):  # will not stop coroutine
        self._timer.deinit()

            
Could you kindly show me, how i should use this code? how i should proper integrate it in my code?
i just haven't any experience with object oriented programming in python.
Put the class at the start of your code, then create the object: wdt=WDT()
Then inside your look call wdt.feed()

ThomasChr
Posts: 109
Joined: Sat Nov 25, 2017 7:50 am

Re: ESP8266 goes down after sometime

Post by ThomasChr » Mon May 06, 2019 2:33 pm

Make sure that you've got everything in try/catch-Blocks.
This code: https://github.com/ThomasChr/ESP8266-re ... er/main.py
is running since 13.01.2019 without a restart.

So the ESP8266 can be very stable.

navy
Posts: 15
Joined: Sat May 04, 2019 6:37 am

Re: ESP8266 goes down after sometime

Post by navy » Tue May 07, 2019 9:09 am

Hi all!
ESP8266 still working after i changed a power source. Meanwhile i've refactored code a little bit. Added a few try/except.
kevinkk525 wrote:
Sat May 04, 2019 12:33 pm
wdt
Kevin, explain me please where i should put wdt.feed()? actually i don't understand mechanics. If i uncomment wdt.feed() my program resets after wdt timeout even if my not freezed.

Now i am working on moving from mqtt.simple to resilient driver.
Glad to any feedback, thank you for a help guys!

Code: Select all

import machine
import time
from machine import Pin
import bme280_float
import network
import micropython
from umqtt.simple import MQTTClient

'''
# software watchdog, to prevent ESP freezing
class WDT:
    def __init__(self, id=0, timeout=120):
        self._timeout = timeout / 10
        self._counter = 0
        self._timer = machine.Timer(id)
        self.init()

    def _wdt(self, t):
        self._counter += self._timeout
        if self._counter >= self._timeout * 10:
            print("WDT timeout")
            machine.reset()

    def feed(self):
        self._counter = 0

    def init(self, timeout=None):
        timeout = timeout or self._timeout
        self._timeout = timeout
        self._timer.init(period=int(self._timeout * 1000), mode=machine.Timer.PERIODIC, callback=self._wdt)

    def deinit(self):  # will not stop coroutine
        self._timer.deinit()
#wdt=WDT()
# wdt.feed() ask about right usage
'''


WiFi_SSID = "ssid"
WiFi_PASS = "pass"

SERVER = "mqtt.thingspeak.com"
CHANNEL_ID = "777777"
WRITE_API_KEY = "00000"
led = Pin(2, Pin.OUT)

# Exception in an ISR should be handled, reserve memory for that
micropython.alloc_emergency_exception_buf(100)

    
def collectData():
    temp1, pas1, hum1 = bme.values
    #temp1 = result[0]
    #hum1 = result[2]
    hum1 = hum1.replace("%", "")
    temp1 = temp1.replace("C", "")
    led.on()
    return temp1, hum1


try:

    # esp8266 scl pin 5, sda pin 4
    # esp32 scl pin 22 (gpio 22), sda pin 21 (gpio 21)
    i2c = machine.I2C(scl=machine.Pin(22), sda=machine.Pin(21))
    #bme= BME280(i2c=i2c, mode=BME280_OSAMPLE_8, address=BME280_I2CADDR)
    bme = bme280_float.BME280(i2c=i2c)
    client = MQTTClient("umqtt_client", SERVER)
    topic = "channels/" + CHANNEL_ID + "/publish/" + WRITE_API_KEY

    wlan = network.WLAN(network.STA_IF)
    ap_if = network.WLAN(network.AP_IF)
    ap_if.active(False)
    wlan.active(True)
    if not wlan.isconnected():
        print('connecting to network... ')
        wlan.connect(WiFi_SSID, WiFi_PASS)
        while not wlan.isconnected():
            pass
    print('network config:', wlan.ifconfig())
    print('SSID: ', WiFi_SSID)


    while True:
        temp1, hum1 = collectData()
        #esp8266 bme code: payload = "field1="+str(hum1)+"&field2="+str(temp1)
        payload = "field1="+str(temp1)
        print(payload)
        try:
            client.connect()
            client.publish(topic, payload)
            client.disconnect()
        except:
            continue
        led.off()
        time.sleep(180)
except:
    print('Catched Exception in main. Reset.')
    machine.reset()

Post Reply