• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 и всем прочим - всё так же:
 

Вложения

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