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)
我有一块 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)