• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

зависание ESP8266 HTTP MicroPython

voffkarostov

New member
Доброго дня! с MicroPython начинаю разбираться, по примерам запустил HTTP сервер с выводом данных с DHT11. плата NodeMCU соответственно с микропитоном.
Проблема такая: плата запускается, появляется в сети, HTTP сервер поднимается норм. захожу по адресу вижу показания DHT, обновляю страницу через 5 минут - уже могу ни чего не увидеть, плата зависает... причем в сети она остается, но ipscaner уже не показывает что есть 80 порт. После этого по USB тоже не факт что подключится.
Полистал темы, вроде чтото похожее уже обсуждалось. Но конкретно не нашел ответа. Или для esp это норм?
 

pvvx

Активный участник сообщества
CircuitPython является производной от MicroPython, предназначенной для упрощения экспериментов и обучения на недорогих микроконтроллерах.

Adafruit FAQ:
Is ESP8266 or ESP32 supported in CircuitPython? Why not?
(ESP8266 или ESP32 поддерживаются в CircuitPython? Почему нет?)
We are dropping ESP8266 support as of 4.x - For more information please read about it here!
(Мы отказываемся от поддержки ESP8266 начиная с версии 4.x - Более подробную информацию вы можете прочитать здесь!)
Welcome to CircuitPython!

Умер ESP8266 везде...
https://cdn-learn.adafruit.com/guid...botics___cnc_IMG_8390.2018-10-09_17_22_14.mp4
 

fps

Active member
pvvx, свежие версии форка микропитона от adafruit не поддерживают 8266. Ну к чему это тут?

voffkarostov, хорошо бы код посмотреть - иначе что тут скажешь?
 

voffkarostov

New member
О как! Спасибо! Изучу!
pvvx, свежие версии форка микропитона от adafruit не поддерживают 8266. Ну к чему это тут?

voffkarostov, хорошо бы код посмотреть - иначе что тут скажешь?
boot.py
Код:
import uos
import webrepl
webrepl.start()

try:
  import usocket as socket
except:
  import socket

from machine import Pin
import network
import dht
import onewire
import ds18x20
import time
import machine

# import esp
# esp.osdebug(None)

import gc
gc.collect()

ssid = 'home'
password = '***'

station = network.WLAN(network.STA_IF)

station.active(True)
station.connect(ssid, password)

while station.isconnected() == False:
  pass

print('Connection successful')
print(station.ifconfig())

sensor = dht.DHT11(Pin(14))

dat = machine.Pin(12)
ds = ds18x20.DS18X20(onewire.OneWire(dat))
roms = ds.scan()
print('Found ds18x20 on:', roms)
main.py
Код:
def read_sensor():
  global temp, hum, ds_temp
  temp = hum = ds_temp = 0
  try:
    sensor.measure()
    temp = sensor.temperature()
    hum = sensor.humidity()
    if (isinstance(temp, float) and isinstance(hum, float)) or (isinstance(temp, int) and isinstance(hum, int)):
      msg = (b'{0:3.1f},{1:3.1f}'.format(temp, hum))

      # uncomment for Fahrenheit
      #temp = temp * (9/5) + 32.0

      hum = round(hum, 2)
      ds.convert_temp()
      time.sleep_ms(750)
      for rom in roms:
        print(rom)
        ds_temp = ds.read_temp(rom)
        # time.sleep(1)
      return(msg)
    else:
      return('Invalid sensor readings.')
  except OSError as e:
    return('Failed to read sensor.')


def web_page():
  html = """<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
   <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .dht-labels{
      font-size: 1.5rem;
      vertical-align:middle;
      padding-bottom: 15px;
    }
  </style>
</head>
<body>
  <h2>ESP DHT Server</h2>
  <p>
    <i style="color:#059e8a;"></i>
    <span class="dht-labels">Temperature</span>
    <span>"""+str(temp)+"""</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <i style="color:#00add6;"></i>
    <span class="dht-labels">Humidity</span>
    <span>"""+str(hum)+"""</span>
    <sup class="units">%</sup>
  </p>
  <p>
    <i style="color:#00add6;"></i>
    <span class="dht-labels">ds18b20</span>
    <span>"""+str(ds_temp)+"""</span>
    <sup class="units">&deg;C</sup>
  </p>
</body>
</html>"""
  return html

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
#roms = ds.scan()
while True:
  conn, addr = s.accept()
  print('Got a connection from %s' % str(addr))
  request = conn.recv(1024)
  # print('Content = %s' % str(request))
  sensor_readings = read_sensor()
  print(sensor_readings)
  response = web_page()
  conn.send('HTTP/1.1 200 OK\n')
  conn.send('Content-Type: text/html\n')
  conn.send('Connection: close\n\n')
  conn.sendall(response)
  conn.close()
 

fps

Active member
voffkarostov, код в целом рабочий (хоть и очень неоптимальный), виснуть не должно.
Вставьте в main.py четвертой строкой (перед try) [inline]return 1[/inline] и проверьте уйдут ли зависания.
Если нет - значит проблема не в коде - а аппаратная, например (самое типовое) питание плохое. Посмотрите, что в консоль пишет.
Если виснуть перестанет - значит что-то виснет конкретно в опросе этого датчика - тут я не помогу, у меня такого нет.
 

voffkarostov

New member
voffkarostov, код в целом рабочий (хоть и очень неоптимальный), виснуть не должно.
Вставьте в main.py четвертой строкой (перед try) [inline]return 1[/inline] и проверьте уйдут ли зависания.
Если нет - значит проблема не в коде - а аппаратная, например (самое типовое) питание плохое. Посмотрите, что в консоль пишет.
Если виснуть перестанет - значит что-то виснет конкретно в опросе этого датчика - тут я не помогу, у меня такого нет.
Большое спасибо за ответ!

return 1 попробую.
на оптимальность кода вообще не притендую ))) первый раз с micropython да и с python вообще первые шаги, раньше как то его обходил.
Вся схема собрана на монтажке, питание идет от зарядки телефонной асус по юсб.
По поводу зависания в опросе датчика, скорее всего да... чтото мне кажется что в этом и дело. Я правильно понимаю что код датчик инициирует один раз при запуске, а потом только его опрашивает по запросу? я к чему, если в процессе работы, предположим, отваливается питание с датчика, потом восстанавливается Python должен его заново инициировать или нет?
Консоль помониторю. Я так думаю самое просто для проверки самой платы: вытащить все датчики и переписать код на какую нибудь статическую страничку, да посмотреть сколько он протянет в работе?
 

fps

Active member
отваливается питание с датчика, потом восстанавливается Python должен его заново инициировать или нет?
Сами датчики, насколько я понимаю, питоном вообще не инициализируются, просто периодически опрашиваются. При старте просто создаются объекты питона, а инициализируются эти датчики сами при включении.
 

voffkarostov

New member
Вставьте в main.py четвертой строкой (перед try) [inline]return 1[/inline] и проверьте уйдут ли зависания.
вставил return 1, перестал показывать показания датчиков. т.е. страница загружается, а показания "0"
пару раз нажал f5 перестала отвечать страница. в консоле WebREPL нажал ctr+c выскочило такое сообщение

Got a connection from ('192.168.1.18', 52972)
Traceback (most recent call last):
File "main.py", line 81, in <module>
KeyboardInterrupt:

MicroPython v1.11-8-g48dcbbe60 on 2019-05-29; ESP module with ESP8266
Type "help()" for more information.

если я все правильно понял, то 81 строка это:
Код:
request = conn.recv(1024)
 

fps

Active member
вставил return 1, перестал показывать показания датчиков. т.е. страница загружается, а показания "0"
Так и должно было быть.

пару раз нажал f5 перестала отвечать страница.
А вот такого быть не должно. Проверяйте железо.

если я все правильно понял, то 81 строка это:
Да. Только в этой строке проблем нет. Просто вы нажали ctrl+c в во время ожидания данных в этой строке. О чем вам питон в консоль и написал.

Старая версия. Обновите при случае на 1.12. Но проблема не в этом.
 

voffkarostov

New member
Всем доброго дня!
Возвращаясь к теме зависания. обновился до 1.12, и отмониторил зависание в консоли. Код не менял, код указанный выше. Железо глючит?
bag.jpg
 

voffkarostov

New member
Всем привет! Походу решил проблему и по всей видимости прикручиванием костыля, но 3 день работает стабильно без зависаний. в код добавил сбор мусора и таймаут коннекта.

Python:
def read_sensor():
  global temp, hum, ds_temp
  temp = hum = ds_temp = 0
  try:
    sensor.measure()
    temp = sensor.temperature()
    hum = sensor.humidity()
    if (isinstance(temp, float) and isinstance(hum, float)) or (isinstance(temp, int) and isinstance(hum, int)):
      msg = (b'{0:3.1f},{1:3.1f}'.format(temp, hum))

      # uncomment for Fahrenheit
      #temp = temp * (9/5) + 32.0

      hum = round(hum, 2)
      ds.convert_temp()
      time.sleep_ms(750)
      for rom in roms:
        print(rom)
        ds_temp = ds.read_temp(rom)
      return(msg)
    else:
      return('Invalid sensor readings.')
  except OSError as e:
    return('Failed to read sensor.')


def web_page():
  sensor_readings = read_sensor()
  html = """<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
   <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .dht-labels{
      font-size: 1.5rem;
      vertical-align:middle;
      padding-bottom: 15px;
    }
  </style>
</head>
<body>
  <h2>ESP DHT Server</h2>
  <p>
    <i style="color:#00add6;"></i>
    <span class="dht-labels">ds18b20</span>
    <span>"""+str(ds_temp)+"""</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <i style="color:#059e8a;"></i>
    <span class="dht-labels">Temperature</span>
    <span>"""+str(temp)+"""</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <i style="color:#00add6;"></i>
    <span class="dht-labels">Humidity</span>
    <span>"""+str(hum)+"""</span>
    <sup class="units">%</sup>
  </p>
</body>
</html>"""
  return html

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
#roms = ds.scan()
while True:
  try:
    mem_free = gc.mem_free()
    print (mem_free)
    if gc.mem_free() < 102000:
      gc.collect()
    mem_free = gc.mem_free()
    print (mem_free)
    conn, addr = s.accept()
    conn.settimeout(3.0)
    print('Got a connection from %s' % str(addr))
    request = conn.recv(1024)
    conn.settimeout(None)
    request = str(request)
    print('Content = %s' % request)
    response = web_page()
    conn.send('HTTP/1.1 200 OK\n')
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')
    conn.sendall(response)
    conn.close()
    print('Connection closed')
  except OSError as e:
    conn.close()
    print('Connection closed Error')
 
Сверху Снизу