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

Нужна помощь Ошибки выделения памяти

arrowcircle

New member
Может быть кто-то сталкивался с проблемой выделения памяти?
Делаю простой скрипт с bme280 и mqtt.
BME280.py залит на плату и подключается из фс. MQTT подключается из стандартной библиотеки.

main.py
Код:
import gc
from machine import Pin
from machine import I2C
import time
import BME280
from umqtt.simple import MQTTClient

i2c = I2C(scl=Pin(4),sda=Pin(5), freq=10000)
bme = BME280.BME280(i2c=i2c)
c = MQTTClient("umqtt_client", "mqtt.server")
c.connect()

while True:
  t, p, h = bme.temperature, bme.pressure * 1000, bme.humidity
  c.publish(b"foo_topic", res)
  c.check_msg()
  time.sleep(1)

c.disconnect()
Ошибка на строке t, p, h = ....
Код:
MemoryError: memory allocation failed, allocating 9001 bytes
Последняя версия микропитона, esp8266 nodemcu v3.
Кто-то сталкивался с такой проблемой? В интернете пишут, что это связано с фрагментацией хипа, но как с этим бороться - непонятно.
Кто-то сталкивался с такой проблемой? Как лучше решать?
 

arrowcircle

New member
что непонятно?
память кончилась
выкидывайте мусор или микро питон или библиотеки .
Вы бы еще линукс запихнули бы в ESP.
Читайте внимательнее, память не кончилась, а фрагментирована.
Если нечего сказать по делу - лучше не писать, кмк.
 

arrowcircle

New member
это Вы такой вывод сделали из этого сообщения?
MemoryError: memory allocation failed, allocating 9001 bytes
Это у Вас она на компе фрагментирована а на ESP она у вас кончилась
я этот вывод делаю на основании информации из issue на гитхабе, а вот откуда вы такие выводы делаете мне не очень понятно. Если вывести количество свободно памяти, то там цифра почти в 2 раза больше 9 кб
 

__ab__

New member
вот это:
Код:
# main.py
import machine, ssd1306, network, time, socket, dht
from umqtt.simple import MQTTClient
from ustruct import unpack
from json import dumps

#import dht22 as LOGIC
import meteo as LOGIC

MQTT =  '10.0.0.1'

devs = None
timer = None
tcnt = 0

def start():
    global timer, devs

    class Devs:
        def __init__(self):
            self.i2c = machine.I2C(scl=machine.Pin(5), sda=machine.Pin(4))
            self.oled = ssd1306.SSD1306_I2C(128, 32, self.i2c, 0x3c)
            self.wlan = network.WLAN(network.STA_IF)
            if self.wlan.active():
                x = 0
                while x < 10 and not self.wlan.isconnected():
                    time.sleep(1)
            self.set_ntp_time()
            from ubinascii import hexlify
            self._client_id = b"esp8266_" + hexlify(machine.unique_id())
            self.mqtt = None
            self._fdir = {
                'IP': self.IP,
                'DATE': self.DATE,
                'TIME': self.TIME,
                'MQTT': 'MQTT Disconnected'
            }

        def init_mqtt(self, broker, topic):
            if not (self.mqtt is None):
                self.mqtt.disconnect()
                self.mqtt = None
            try:
                self.mqtt = MQTTClient(self._client_id, broker)
                self.mqtt.connect()
                self.mqtt.topic = topic
            except:
                self.mqtt = None
            self._fdir['MQTT'] = 'MQTT Error!' if self.mqtt is None else MQTT + ' MQTT'

        def client_id(self):
            return self._client_id.decode()

        def IP(self):
            return self.wlan.ifconfig()[0] if self.wlan.isconnected() else 'Not connected'

        def DATE(self):
            tm = list(time.localtime()[0:3])
            for i, x in enumerate(tm):
                x = str(x)
                tm[i] = x if len(x) > 1 else '0' + x
            return '%s-%s-%s' % tuple(tm)

        def TIME(self):
            tm = list(time.localtime()[3:6])
            for i, x in enumerate(tm):
                x = str(x)
                tm[i] = x if len(x) > 1 else '0' + x
            return '%s:%s:%s' % tuple(tm)

        def screen(self, data):
            if self.oled is None: return

            if type(data) != list:
                data = str(data).split('\n')

            self.oled.fill(0)
            y = 0
            for s in data:
                s = str(s)
                for x in self._fdir:
                    if ('{{ %s }}' % x) in s:
                        if type(self._fdir[x]) == str:
                            s = s.replace('{{ %s }}' % x, self._fdir[x])
                        else:
                            s = s.replace('{{ %s }}' % x, self._fdir[x]())
                self.oled.text(s, 0, y)
                y += 10
            self.oled.show()

        def set_ntp_time(self):
            if self.wlan is None or not self.wlan.isconnected(): return
            NTP_QUERY = bytearray(48)
            NTP_QUERY[0] = 0x1b
            addr = socket.getaddrinfo("pool.ntp.org", 123)[0][-1]
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.settimeout(1)
            msg = s.sendto(NTP_QUERY, addr)
            msg = s.recv(48)
            s.close()
            val = unpack("!I", msg[40:44])[0]
            val -= 3155673600
            tm = time.localtime(val + 3600 * 3)
            tm = tm[0:3] + (0,) + tm[3:6] + (0,)
            machine.RTC().datetime(tm)
            return tm

        def publish(self, message, topic=None):
            if self.mqtt is None:
                return
            if type(message) == dict:
                message = {
                    "Sensor": self.client_id(),
                    "Data": message,
                    "Time": self.DATE() + ' ' + self.TIME(),
                    "IP": self.IP()
                }
                message = dumps(message)
            else:
                message = str(message)
            topic = self.mqtt.topic if topic is None else topic
            self.mqtt.publish(topic, message)

    if devs is None:
        devs = Devs()
        topic, period = LOGIC.setup(devs)
        devs.init_mqtt(MQTT,topic)

        def handler(timer):
            global tcnt, devs
            tcnt += 1
            if tcnt>500:
                devs.set_ntp_time()
                tcnt = 0
            msg = LOGIC.loop(devs)
            if not msg is None:
                devs.publish(msg)

        timer = machine.Timer(0)
        timer.init(period=period, mode=machine.Timer.PERIODIC, callback=handler)
плюс вот это:
Код:
# meteo.py
import dht, machine
from bmp180 import BMP180

switch = None
ext_sensor = None
water_sensor = None
int_sensor = None
tms = 0
int_alt = None

def setup(devs):
    global switch, ext_sensor, water_sensor, int_sensor
    switch = machine.Pin(14,machine.Pin.PULL_UP)
    ext_sensor = dht.DHT22(machine.Pin(12))
    water_sensor = machine.ADC(0)
    int_sensor = BMP180(devs.i2c)
    int_sensor.oversample_sett = 2
    int_sensor.baseline = 101325

    return 'house/wether', 1000

def str2(v):
    v = str(v)
    if '.' in v:
        v = v.split('.')
        v = v[0] + '.'+ v[1][:2]
    return v

def loop(devs):
    global switch, ext_sensor, water_sensor, int_sensor, tms, int_temp, int_press, int_alt

    ret = None
    rd =water_sensor.read()

    if tms == 0:
        ext_sensor.measure()

        int_temp  = int_sensor.temperature
        int_press = int_sensor.pressure * 0.00750062
        int_alt   = int_sensor.altitude

        ret = {
            "Temp":int_temp,
            "Pressure":int_press,
            "Altitude":int_alt,
            "TempExt":ext_sensor.temperature(),
            "mmHgExt":ext_sensor.humidity(),
            "Rain":rd
        }

        tms = 61

    tms -= 1
    if switch()==1:
        devs.screen([
            '%s C %s ' % ( ext_sensor.temperature(), ext_sensor.humidity() ) + '%',
            '%s C %s mmHg' % ( str2(int_temp), str2(int_press)),
            'rain' if rd<900 else 'dry'
        ])
    else:
        devs.screen([
            '{{ IP }}',
            '{{ DATE }} {{ TIME }}',
            '{{ MQTT }}'
        ])

    return ret
cутками работает на ESP и никуда не падает ;)
поэтому я бы предложил поискать в BME280, а для начала проверить все то же, но на другом контроллере.
и while я бы заменил на таймер (как и сделал), дабы мусор не копился в памяти

таймер во фрагменте main.py:
Код:
def handler(timer):
            global tcnt, devs
            tcnt += 1
            if tcnt>500:
                devs.set_ntp_time()
                tcnt = 0
            msg = LOGIC.loop(devs)
            if not msg is None:
                devs.publish(msg)

timer = machine.Timer(0)
timer.init(period=period, mode=machine.Timer.PERIODIC, callback=handler)
 
Последнее редактирование:

arrowcircle

New member
вот это:
Код:
# main.py
import machine, ssd1306, network, time, socket, dht
from umqtt.simple import MQTTClient
from ustruct import unpack
from json import dumps

#import dht22 as LOGIC
import meteo as LOGIC

MQTT =  '10.0.0.1'

devs = None
timer = None
tcnt = 0

def start():
    global timer, devs

    class Devs:
        def __init__(self):
            self.i2c = machine.I2C(scl=machine.Pin(5), sda=machine.Pin(4))
            self.oled = ssd1306.SSD1306_I2C(128, 32, self.i2c, 0x3c)
            self.wlan = network.WLAN(network.STA_IF)
            if self.wlan.active():
                x = 0
                while x < 10 and not self.wlan.isconnected():
                    time.sleep(1)
            self.set_ntp_time()
            from ubinascii import hexlify
            self._client_id = b"esp8266_" + hexlify(machine.unique_id())
            self.mqtt = None
            self._fdir = {
                'IP': self.IP,
                'DATE': self.DATE,
                'TIME': self.TIME,
                'MQTT': 'MQTT Disconnected'
            }

        def init_mqtt(self, broker, topic):
            if not (self.mqtt is None):
                self.mqtt.disconnect()
                self.mqtt = None
            try:
                self.mqtt = MQTTClient(self._client_id, broker)
                self.mqtt.connect()
                self.mqtt.topic = topic
            except:
                self.mqtt = None
            self._fdir['MQTT'] = 'MQTT Error!' if self.mqtt is None else MQTT + ' MQTT'

        def client_id(self):
            return self._client_id.decode()

        def IP(self):
            return self.wlan.ifconfig()[0] if self.wlan.isconnected() else 'Not connected'

        def DATE(self):
            tm = list(time.localtime()[0:3])
            for i, x in enumerate(tm):
                x = str(x)
                tm[i] = x if len(x) > 1 else '0' + x
            return '%s-%s-%s' % tuple(tm)

        def TIME(self):
            tm = list(time.localtime()[3:6])
            for i, x in enumerate(tm):
                x = str(x)
                tm[i] = x if len(x) > 1 else '0' + x
            return '%s:%s:%s' % tuple(tm)

        def screen(self, data):
            if self.oled is None: return

            if type(data) != list:
                data = str(data).split('\n')

            self.oled.fill(0)
            y = 0
            for s in data:
                s = str(s)
                for x in self._fdir:
                    if ('{{ %s }}' % x) in s:
                        if type(self._fdir[x]) == str:
                            s = s.replace('{{ %s }}' % x, self._fdir[x])
                        else:
                            s = s.replace('{{ %s }}' % x, self._fdir[x]())
                self.oled.text(s, 0, y)
                y += 10
            self.oled.show()

        def set_ntp_time(self):
            if self.wlan is None or not self.wlan.isconnected(): return
            NTP_QUERY = bytearray(48)
            NTP_QUERY[0] = 0x1b
            addr = socket.getaddrinfo("pool.ntp.org", 123)[0][-1]
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.settimeout(1)
            msg = s.sendto(NTP_QUERY, addr)
            msg = s.recv(48)
            s.close()
            val = unpack("!I", msg[40:44])[0]
            val -= 3155673600
            tm = time.localtime(val + 3600 * 3)
            tm = tm[0:3] + (0,) + tm[3:6] + (0,)
            machine.RTC().datetime(tm)
            return tm

        def publish(self, message, topic=None):
            if self.mqtt is None:
                return
            if type(message) == dict:
                message = {
                    "Sensor": self.client_id(),
                    "Data": message,
                    "Time": self.DATE() + ' ' + self.TIME(),
                    "IP": self.IP()
                }
                message = dumps(message)
            else:
                message = str(message)
            topic = self.mqtt.topic if topic is None else topic
            self.mqtt.publish(topic, message)

    if devs is None:
        devs = Devs()
        topic, period = LOGIC.setup(devs)
        devs.init_mqtt(MQTT,topic)

        def handler(timer):
            global tcnt, devs
            tcnt += 1
            if tcnt>500:
                devs.set_ntp_time()
                tcnt = 0
            msg = LOGIC.loop(devs)
            if not msg is None:
                devs.publish(msg)

        timer = machine.Timer(0)
        timer.init(period=period, mode=machine.Timer.PERIODIC, callback=handler)
плюс вот это:
Код:
# meteo.py
import dht, machine
from bmp180 import BMP180

switch = None
ext_sensor = None
water_sensor = None
int_sensor = None
tms = 0
int_alt = None

def setup(devs):
    global switch, ext_sensor, water_sensor, int_sensor
    switch = machine.Pin(14,machine.Pin.PULL_UP)
    ext_sensor = dht.DHT22(machine.Pin(12))
    water_sensor = machine.ADC(0)
    int_sensor = BMP180(devs.i2c)
    int_sensor.oversample_sett = 2
    int_sensor.baseline = 101325

    return 'house/wether', 1000

def str2(v):
    v = str(v)
    if '.' in v:
        v = v.split('.')
        v = v[0] + '.'+ v[1][:2]
    return v

def loop(devs):
    global switch, ext_sensor, water_sensor, int_sensor, tms, int_temp, int_press, int_alt

    ret = None
    rd =water_sensor.read()

    if tms == 0:
        ext_sensor.measure()

        int_temp  = int_sensor.temperature
        int_press = int_sensor.pressure * 0.00750062
        int_alt   = int_sensor.altitude

        ret = {
            "Temp":int_temp,
            "Pressure":int_press,
            "Altitude":int_alt,
            "TempExt":ext_sensor.temperature(),
            "mmHgExt":ext_sensor.humidity(),
            "Rain":rd
        }

        tms = 61

    tms -= 1
    if switch()==1:
        devs.screen([
            '%s C %s ' % ( ext_sensor.temperature(), ext_sensor.humidity() ) + '%',
            '%s C %s mmHg' % ( str2(int_temp), str2(int_press)),
            'rain' if rd<900 else 'dry'
        ])
    else:
        devs.screen([
            '{{ IP }}',
            '{{ DATE }} {{ TIME }}',
            '{{ MQTT }}'
        ])

    return ret
cутками работает на ESP и никуда не падает ;)
поэтому я бы предложил поискать в BME280, а для начала проверить все то же, но на другом контроллере.
и while я бы заменил на таймер (как и сделал), дабы мусор не копился в памяти

таймер во фрагменте main.py:
Код:
def handler(timer):
            global tcnt, devs
            tcnt += 1
            if tcnt>500:
                devs.set_ntp_time()
                tcnt = 0
            msg = LOGIC.loop(devs)
            if not msg is None:
                devs.publish(msg)

timer = machine.Timer(0)
timer.init(period=period, mode=machine.Timer.PERIODIC, callback=handler)
Спасибо, попробую.
while из базового примера, который отказался работать.

PS. Почистил еще раз флеш, перезалил прошивку, залил скомпилированный bme280.mpy и вроде все завелось. По памяти не вылетает
 
Последнее редактирование:

arrowcircle

New member
вот это:
Код:
# main.py
import machine, ssd1306, network, time, socket, dht
from umqtt.simple import MQTTClient
from ustruct import unpack
from json import dumps

#import dht22 as LOGIC
import meteo as LOGIC

MQTT =  '10.0.0.1'

devs = None
timer = None
tcnt = 0

def start():
    global timer, devs

    class Devs:
        def __init__(self):
            self.i2c = machine.I2C(scl=machine.Pin(5), sda=machine.Pin(4))
            self.oled = ssd1306.SSD1306_I2C(128, 32, self.i2c, 0x3c)
            self.wlan = network.WLAN(network.STA_IF)
            if self.wlan.active():
                x = 0
                while x < 10 and not self.wlan.isconnected():
                    time.sleep(1)
            self.set_ntp_time()
            from ubinascii import hexlify
            self._client_id = b"esp8266_" + hexlify(machine.unique_id())
            self.mqtt = None
            self._fdir = {
                'IP': self.IP,
                'DATE': self.DATE,
                'TIME': self.TIME,
                'MQTT': 'MQTT Disconnected'
            }

        def init_mqtt(self, broker, topic):
            if not (self.mqtt is None):
                self.mqtt.disconnect()
                self.mqtt = None
            try:
                self.mqtt = MQTTClient(self._client_id, broker)
                self.mqtt.connect()
                self.mqtt.topic = topic
            except:
                self.mqtt = None
            self._fdir['MQTT'] = 'MQTT Error!' if self.mqtt is None else MQTT + ' MQTT'

        def client_id(self):
            return self._client_id.decode()

        def IP(self):
            return self.wlan.ifconfig()[0] if self.wlan.isconnected() else 'Not connected'

        def DATE(self):
            tm = list(time.localtime()[0:3])
            for i, x in enumerate(tm):
                x = str(x)
                tm[i] = x if len(x) > 1 else '0' + x
            return '%s-%s-%s' % tuple(tm)

        def TIME(self):
            tm = list(time.localtime()[3:6])
            for i, x in enumerate(tm):
                x = str(x)
                tm[i] = x if len(x) > 1 else '0' + x
            return '%s:%s:%s' % tuple(tm)

        def screen(self, data):
            if self.oled is None: return

            if type(data) != list:
                data = str(data).split('\n')

            self.oled.fill(0)
            y = 0
            for s in data:
                s = str(s)
                for x in self._fdir:
                    if ('{{ %s }}' % x) in s:
                        if type(self._fdir[x]) == str:
                            s = s.replace('{{ %s }}' % x, self._fdir[x])
                        else:
                            s = s.replace('{{ %s }}' % x, self._fdir[x]())
                self.oled.text(s, 0, y)
                y += 10
            self.oled.show()

        def set_ntp_time(self):
            if self.wlan is None or not self.wlan.isconnected(): return
            NTP_QUERY = bytearray(48)
            NTP_QUERY[0] = 0x1b
            addr = socket.getaddrinfo("pool.ntp.org", 123)[0][-1]
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.settimeout(1)
            msg = s.sendto(NTP_QUERY, addr)
            msg = s.recv(48)
            s.close()
            val = unpack("!I", msg[40:44])[0]
            val -= 3155673600
            tm = time.localtime(val + 3600 * 3)
            tm = tm[0:3] + (0,) + tm[3:6] + (0,)
            machine.RTC().datetime(tm)
            return tm

        def publish(self, message, topic=None):
            if self.mqtt is None:
                return
            if type(message) == dict:
                message = {
                    "Sensor": self.client_id(),
                    "Data": message,
                    "Time": self.DATE() + ' ' + self.TIME(),
                    "IP": self.IP()
                }
                message = dumps(message)
            else:
                message = str(message)
            topic = self.mqtt.topic if topic is None else topic
            self.mqtt.publish(topic, message)

    if devs is None:
        devs = Devs()
        topic, period = LOGIC.setup(devs)
        devs.init_mqtt(MQTT,topic)

        def handler(timer):
            global tcnt, devs
            tcnt += 1
            if tcnt>500:
                devs.set_ntp_time()
                tcnt = 0
            msg = LOGIC.loop(devs)
            if not msg is None:
                devs.publish(msg)

        timer = machine.Timer(0)
        timer.init(period=period, mode=machine.Timer.PERIODIC, callback=handler)
плюс вот это:
Код:
# meteo.py
import dht, machine
from bmp180 import BMP180

switch = None
ext_sensor = None
water_sensor = None
int_sensor = None
tms = 0
int_alt = None

def setup(devs):
    global switch, ext_sensor, water_sensor, int_sensor
    switch = machine.Pin(14,machine.Pin.PULL_UP)
    ext_sensor = dht.DHT22(machine.Pin(12))
    water_sensor = machine.ADC(0)
    int_sensor = BMP180(devs.i2c)
    int_sensor.oversample_sett = 2
    int_sensor.baseline = 101325

    return 'house/wether', 1000

def str2(v):
    v = str(v)
    if '.' in v:
        v = v.split('.')
        v = v[0] + '.'+ v[1][:2]
    return v

def loop(devs):
    global switch, ext_sensor, water_sensor, int_sensor, tms, int_temp, int_press, int_alt

    ret = None
    rd =water_sensor.read()

    if tms == 0:
        ext_sensor.measure()

        int_temp  = int_sensor.temperature
        int_press = int_sensor.pressure * 0.00750062
        int_alt   = int_sensor.altitude

        ret = {
            "Temp":int_temp,
            "Pressure":int_press,
            "Altitude":int_alt,
            "TempExt":ext_sensor.temperature(),
            "mmHgExt":ext_sensor.humidity(),
            "Rain":rd
        }

        tms = 61

    tms -= 1
    if switch()==1:
        devs.screen([
            '%s C %s ' % ( ext_sensor.temperature(), ext_sensor.humidity() ) + '%',
            '%s C %s mmHg' % ( str2(int_temp), str2(int_press)),
            'rain' if rd<900 else 'dry'
        ])
    else:
        devs.screen([
            '{{ IP }}',
            '{{ DATE }} {{ TIME }}',
            '{{ MQTT }}'
        ])

    return ret
cутками работает на ESP и никуда не падает ;)
поэтому я бы предложил поискать в BME280, а для начала проверить все то же, но на другом контроллере.
и while я бы заменил на таймер (как и сделал), дабы мусор не копился в памяти

таймер во фрагменте main.py:
Код:
def handler(timer):
            global tcnt, devs
            tcnt += 1
            if tcnt>500:
                devs.set_ntp_time()
                tcnt = 0
            msg = LOGIC.loop(devs)
            if not msg is None:
                devs.publish(msg)

timer = machine.Timer(0)
timer.init(period=period, mode=machine.Timer.PERIODIC, callback=handler)
А как Вы работает с микропитоном? Как заливаете файлы? Есть ли какой-то удобный способ заливки и отладки? Makefile или что-то подобное?
 

__ab__

New member
Как заливаете файлы?
Есть такая удобная штука WEBREPL. Как ставить описано на сайте микиропитона.
Отладка, как правило, заливкой в контроллер и проверкой как работает.
Опять же, через REPL.
Делал попытки написать модули - заглушки подо все и через это получить отладку в PyCharm, но пока некогда и лень ;)

Кстати, Webrepl работает параллельно с тем кодом, что я привел выше - никаких проблем с памятью.
 

arrowcircle

New member
Есть такая удобная штука WEBREPL. Как ставить описано на сайте микиропитона.
Отладка, как правило, заливкой в контроллер и проверкой как работает.
Опять же, через REPL.
Делал попытки написать модули - заглушки подо все и через это получить отладку в PyCharm, но пока некогда и лень ;)

Кстати, Webrepl работает параллельно с тем кодом, что я привел выше - никаких проблем с памятью.
WebRepl - это адски неудобный инструмент.
Заливать файлы по одному - это ужас. К тому же после ребута соединение рвется.
В идеале иметь мейкфайл/интеграцию с иде для проверки синтаксиса, прекомпиляции всего, кроме main.py, заливки всех изменившихся файлов, запуск тестов и тд.
 

gwvsol

New member
Я сейчас разрабатываю управление системой электрического отопления.
После того как добавил библиотеки для работы с LCD по шине i2c, так же библиотеку для RTC DS3231, DS18B20 и uasyncio (uasyncio не работает без collections) и дописал свою для обновление времени с NTP сервера и по временным зонам у меня появилось примерно такое сообщение.
uasyncio и collections забрали под себя почти всю память.
Решение проблемы: перенести все библиотеки на флеш. Для этого необходимо собрать свой бинарник micropython с уже добавленными в него библиотеками.
Это не сложно. Нужно установить среду esp-open-sdk, скачать исходники micropython, добавить к ним нужные библиотеки и скомпилить все. Не могу как все это работает под Windows, под Linux не возникло никаких сложностей. Самое длительное из этого процесса, сборка из исходников esp-open-sdk.
После сборки бинарника заливаем его на ESP8266 и заливаем исходник. А еще лучше скомпилить файл проекта через MicroPython cross compiler и залить их в скомпилированном виде. (вообще это наверное первое что нужно сделать если наблюдается нехватка памяти, скомпилить все и не заставлять контроллер заниматься компилированием).
Внимание: файлы boot.py и main.py компилить нельзя! Они должны быть как есть с расширением py.
Если же весь проект писать в файл main.py тогда лишаемся возможности компилировать свой проект. Вообще в файле main.py должна быть только одна строка для импорта проекта. А сам проект вынести в отдельный файл, который можно с случае необходимости скомпилить.
 

__ab__

New member
перейти на луа. там уже все сделано. все ваши скрипты можно хранить в файловой системе на флеш и динамически их загружать когда надо
В micropython тоже все сделано и скрипты можно хранить в ФС на внутренней флеш. А для динамической загрузки в любом питоне есть __import__ в коде или import в REPL.
Можно перейти на C, но на языках более высокого уровня все пишется и отлаживается быстрее.
Если при этом все работает - зачем переходить на низкий? Ну разве если в том у кого свое удовольствие...
файлы boot.py и main.py компилить нельзя!
То что я писал выше работает не будучи вшитым ни в какую прошивку, хотя там тоже есть и работа с экраном и NTP(одна функция в main) и MQTT.
Я не стал плодить файлов и вписал общую для разных проектов функциональность в main.
boot.py у меня выглядит всегда так:
Код:
import gc, webrepl

webrepl.start()
gc.collect()

import main
main.start()
Импорт main после webrepl на случай если при правке main там будет косяк. Соответственно можно зайти в webrepl и посмотреть что пошло не так.
В самом main, при этом, практически нет кода, который бы выполнялся при его импорте.
 

gwvsol

New member
WebRepl - это адски неудобный инструмент.
Заливать файлы по одному - это ужас. К тому же после ребута соединение рвется.
В идеале иметь мейкфайл/интеграцию с иде для проверки синтаксиса, прекомпиляции всего, кроме main.py, заливки всех изменившихся файлов, запуск тестов и тд.
WebRepl - интересный инструмент, но согласен не удобный. Чтобы видеть что происходит сразу после reboot я использую подключение через COM порт. Я использую программу minicom для Windows есть Putty.
А дальше все просто, расставляешь по программе вывод информации обычным print, делаешь reboot и видишь что происходит. Чтобы увидеть сколько доступно всего и сколько свободной памяти при работающем коде необходимо импортировать
import gc
и использовать:
gc.mem_alloc() - для вывода сколько всего памяти
gc.mem_free() - для вывода сколько свободной памяти
upload_2018-11-8_7-48-27.png
Вот так это выглядит у меня мониторинг работы через minicom
 

__ab__

New member
WebRepl - интересный инструмент, но согласен не удобный.
Я под Linux использую picocom, когда включаю через USB. Но чаще WebRepl - устройства то не у компа ;) И аптайм уже месяцами исчисляется...
WebRepl тот же minicom по сути, только с возможностью загрузки файлов. C print и всем прочим - всё так же:
 

Вложения

Последнее редактирование:
Сверху Снизу