Как сбросить ESP8266 MicroPython после сбоя main.py?

У меня есть плата NodeMCU ESP8266, на которой работает MicroPython. Я запускаю веб-сервер на моем ESP8266. Это мой первый IoT-проект, основанный на одной из этих плат.

Ниже приведен фрагмент кода.

Это выполняется в течение main.py. Время от времени что-то вызывает сбой кода (возможно, на основе времени и запроса). Когда main.py по какой-то причине выходит, я возвращаюсь к интерфейсу командной строки python.

Я бы хотел, чтобы плата перезагрузилась, когда это произойдет (если нет лучшего способа).

Каков наилучший способ перезапуска/сброса 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':

person user1600747    schedule 05.03.2017    source источник
comment
Это ошибка, о которой сообщается при выходе из веб-сервера. OSError: [Errno 104] ECONNRESET   -  person user1600747    schedule 05.03.2017
comment
Хотя в документах говорится, что сторожевой таймер machine.WDT не доступно для esp8266, это сообщение на форуме подразумевает, что сейчас реализован в базовой форме. Это, наверное, первое, что нужно попробовать. (Нулевая вещь, которую нужно попробовать, это выяснить, как остановить сбой вашего кода, конечно). В этой ветке также обсуждается создание сторожевого таймера на ЕСП.   -  person nekomatic    schedule 08.03.2017


Ответы (4)


Вы можете выполнить свой код (который должен быть за пределами main.py -> другой файл) из загрузки или main.py. если он выпадает, он должен выполнить следующий код, который может вызвать сброс.

Возможно, вам придется сначала поймать ошибку.

надеюсь я помог

person Claus Spitzer    schedule 03.04.2017
comment
Возможно, фрагмент кода поможет прояснить ваш ответ. - person gareththegeek; 03.04.2017
comment
Это подход, который я выбрал. Я переместил свой основной код в boot.py, а затем в main.py включил вызов для сброса ESP8266. Если что-то заставит цикл веб-службы прерваться, boot.py завершится, а main.py выполнится, перезагрузив устройство. Однако я обнаружил лучшую надежность при переходе на lua и mqtt на ESP8266 и перемещении компонента веб-службы на реальный веб-сервер apache, работающий на другом хосте. - person user1600747; 05.04.2017

MicroPython имеет функцию machine.reset() для сбросить плату.

Python (не только MicroPython) использует обработку исключений для обработки ошибок.

Сочетая эти две вещи, вы легко добьетесь желаемого. Например:

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

Если в приведенном выше коде вы замените значение b на 0, ваша плата перезагрузится. Если вы немного подумаете об этом, вы, вероятно, обнаружите, что это не имеет особого смысла - вы не хотите, чтобы ваша доска внезапно сбрасывалась, если вы просто разделите на 0 по ошибке или по другой причине. Должны быть лучшие способы обработки ошибок! Точно так же вы можете подумать о своем собственном случае и посмотреть, действительно ли сброс платы является лучшим выбором. Если вы думаете, что да, это нормально, просто всегда помните, что вы запрограммировали доску на внезапный сброс. В противном случае ваш следующий вопрос здесь может быть «Моя доска внезапно сбрасывается! Почему???» ;-)

person pfalcon    schedule 29.06.2017
comment
Это хороший ответ, эффективный способ выполнить то, что было запрошено, И некоторые мысли о лучших методах или путях решения основной проблемы. - person Ezekiel Kruglick; 07.08.2017

Возможно, для исходного вопроса уже поздно, но ответ, которым я собираюсь поделиться, может помочь другим людям. Учтите, что это не окончательное решение, но во многих случаях оно может сэкономить день. Вы можете изучить свое дело.

Решение использует внутреннюю функцию планирования MicroPython. поскольку его выполнение гарантировано, его поведение можно использовать как инструмент для имитации функционального сторожевого таймера.

Следующий код будет работать с заданными таймерами и порогом, которые можно настроить в вашем случае, и если таймер достигает своего порога, а значение wd_buffer не обновляется за это время, тогда может быть вызвана функция, и мы повторяем процесс снова . Таким образом, чтобы предотвратить перезапуск ESP в этом случае через 12 секунд, вы должны где-то в своем коде периодически (короче 12 секунд или настроить таймер и порог в соответствии с вашими потребностями) обновить значение глобальной переменной 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)
person DeFoG    schedule 12.01.2018

вы можете добавить проверку цикла while для кнопки Flash (контакт 0 GPIO) следующим образом:

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.')
person ExploWare    schedule 05.10.2017