main.py 崩溃后如何重置 ESP8266 MicroPython?

How can I reset ESP8266 MicroPython after main.py crashes?

我有一块 NodeMCU ESP8266 板 运行 MicroPython。我是 运行 ESP8266 上的 Web 服务器。这是我基于其中一个开发板的第一个物联网项目。

以下是代码片段。

正在 main.py 内执行。时不时地,某些事情会导致代码崩溃(可能是基于时间和请求)。当 main.py 退出时,无论出于何种原因,我都会回到 python CLI。

发生这种情况时,我希望电路板能够重置(如果没有更好的方法)。

restarting/reseting ESP8266 的最佳方法是什么?

addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(5)
print('listening on', addr)

while True:
    cl, addr = s.accept()
    print('client connected from', addr)
    cl_file = cl.makefile('rwb', 0)
    print("Request:")
    while True:
        line = cl_file.readline()
        print("Line:" , line)
        if not line or line == b'\r\n':
            print("breaking")
            break
        if line == b'GET /active HTTP/1.1\r\n':

您可以从引导程序或 main.py 执行您的代码(应该在 main.py -> 其他文件之外)。如果它退出,它应该执行以下代码,这可能会触发重置。

您可能必须先捕获错误。

希望能帮到你

MicroPython 具有 machine.reset() 重置电路板的功能。

Python(不仅仅是 MicroPython)使用 exception handling 来处理错误。

两者结合,可以轻松实现你想要的效果。例如:

a = 4
b = 2
try:
    a / b
except:
    machine.reset()

如果在上面的代码中将 b 的值替换为 0,您的开发板将重置。如果您稍微考虑一下,您可能会发现它没有多大意义 - 如果您错误地除以 0 或其他原因,您不希望您的电路板突然重置。必须有更好的方法来处理错误!同样,您可能需要考虑自己的情况,看看重置电路板是否真的是最佳选择。如果您认为是,那很好,请始终记住, 将您的电路板编程为突然重置。否则,您的下一个问题可能是 "My board suddenly resets! Why???" ;-)

您可以添加一个 while 循环检查 Flash 按钮(GPIO 引脚 0),如下所示:

import machine
pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)                                                                 
while pin.value():
    print('Put your code here...')
    print('..this will looping until the Flash button is pressed...')

print('...and then it continues here.')

原始问题可能已经晚了,但我要分享的答案可能会对其他人有所帮助。考虑这不是最终解决方案,但在许多情况下,它可能会节省一天的时间。您可以探索您的案例。

解决方法是使用MicroPython的内部调度功能。因为它的执行是有保证的,所以它的行为可以用作模仿功能看门狗的工具。

以下代码将 运行 具有给定的计时器和阈值,这可以根据您的情况进行自定义,如果计时器达到其阈值,并且 wd_buffer 的值此时不会更新,然后可能会调用该函数,我们再次重复该过程。 因此,为了防止 ESP 在这种情况下在 12 秒后重新启动,您必须在代码中的某个位置定期(短于 12 秒或根据需要调整计时器和阈值)更新 Global wd_buffer 变量。希望对你有帮助。

# Simple WD - Global Variable
wd_feeder = 0 
wd_buffer = 0
wd_counter = 0
wd_threshold = 4

def wd_checker(calledvalue):
    print('watchdog is checking... feeder= {} buffer= {}'.format(wd_feeder, wd_buffer))
    global wd_counter
    global wd_buffer
    global wd_feeder
    if wd_feeder == wd_buffer:
        print('state is suspicious ... counter is {} incrementing the counter'.format(wd_counter))
        wd_counter += 1
    else:
        wd_counter = 0
        wd_feeder = wd_buffer
    if wd_counter == wd_threshold:
        print('Counter is reached its threshold, following function will be called')
        wd_feeder = wd_buffer = wd_counter = 0
        machine.reset()


if __name__ == '__main__':
    scheduler_wd = machine.Timer(-1)
    scheduler_wd.init(period=3000, mode=machine.Timer.PERIODIC, callback=wd_checker)