ESP-8266/ESP32 NodeMCU Lua: азы программирования.

Тема в разделе "ESP8266, ESP32", создана пользователем ИгорьК, 25 июл 2017.

  1. Ilya._.Light

    Ilya._.Light Нуб

    тожесамое
    Код (Text):
    > dofile("setglobals.lua")
    > Got wifi
    iot.eclipse.org!!!!!!!
    Connected to Broker
    Subscribed.

    ets Jan  8 2013,rst cause:1, boot mode:(3,6)

    load 0x40100000, len 26040, room 16
    tail 8
    chksum 0xa3
    load 0x3ffe8000, len 2180, room 0
    tail 4
    chksum 0xf9
    load 0x3ffe8884, len 136, room 4
    tail 4
    chksum 0x07
    csum 0x07
    „гмГ'д’{Гуo<дЊlЏ8{lc›џ|;“lњoаѓgг
     
  2. Ilya._.Light

    Ilya._.Light Нуб

  3. ИгорьК

    ИгорьК Гуру

    И зачем во это:
    SmartSelect_20180813-001731_Opera Mini.jpg
     
  4. ИгорьК

    ИгорьК Гуру

    Lua, JavaScript категорически не оперируют задержками типа tmr.delay(...).
    Вы туда загнали 6 мсекунд - так нельзя.

    SmartSelect_20180813-002530_Opera Mini.jpg
     
  5. Ilya._.Light

    Ilya._.Light Нуб

    я загнал эту задержку уже после того как нашел баг, я в Lua не разбегаюсь мне нужно было что бы сообщение в консоли вышло явно позже срабатывания таймера с рекурсией, так стало понятно что таймер не отрабатывает

    rst cause:1 у меня даже если я по команде перезагружаю контролер
     
  6. Ilya._.Light

    Ilya._.Light Нуб

    print(node.bootreason()) показал что срабатывает WDT exception reset
    Exception Causes
    Processor internal physical address or data error during instruction fetch

    и начало проскакивать rst cause:4

    магия(
     
    Последнее редактирование: 13 авг 2018
  7. Ilya._.Light

    Ilya._.Light Нуб

    причем 1 раз из 10 все отрабатывает как надо
     
  8. ИгорьК

    ИгорьК Гуру


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

    Диагноз ясен - модуль mqtt от производителя nodemcu шалит.

    К вечеру перепишем код с учетом вашей информации.
     
  9. ИгорьК

    ИгорьК Гуру

    (Так, с телефона мне чего только не померещится...)

    Начнем заново. Скажите, Вы в модуль загоняете файл с комменртариями на русском языке?
     
  10. ИгорьК

    ИгорьК Гуру

    Итак, отчет о работе. Роутер дважды, практически подряд, выключается и включается:
    upload_2018-8-13_15-25-50.png

    Как я не мучил модуль, получить молчаливую перезагрузку мне не удалось.

    Скрипт прилагаю.
     

    Вложения:

    • setmqtt.zip
      Размер файла:
      678 байт
      Просмотров:
      269
    Последнее редактирование: 13 авг 2018
  11. ИгорьК

    ИгорьК Гуру

    Теперь ваш код.
    - удалил весь комментарий
    - чуть переназвал файлы - у меня рабочий проект
    - уточнил вашу подписку, у Вас:
    upload_2018-8-13_16-20-24.png

    Мне не удалось завалить ваш код два раза подряд:

    upload_2018-8-13_16-21-19.png

    upload_2018-8-13_16-21-45.png

    Скрипты (ваши), которые здесь работали прилагаю.
     

    Вложения:

  12. ИгорьК

    ИгорьК Гуру

    Общие замечания. Повторять опыт Си в части дефайнов здесь не следует.
    Это скриптовый язык, и если вы объявили:

    upload_2018-8-13_16-27-2.png

    то все, что помечено желтым будет бесполезно висеть в памяти как глобальные переменные.
    Для работы всего скрипта они не нужны. (В Си компилятор за вас повтыкает дефайны в код, здесь - нет.)

    Понимаю, что это непривычно и кажется не удобным. К этому надо привыкнуть.

    Все определения следует делать в том файле, к которому они относятся и как "local", и только те, что для всех частей программы объявлять глобальными. Но даже и их лучше собирать в одну таблицу в данном случае dat.

    Конечно, можно и так как у вас, но смысла в этом немного.
     
    Последнее редактирование: 13 авг 2018
  13. Ilya._.Light

    Ilya._.Light Нуб

    взял ваш код с правками для дружбы с моим сервером
    и добавил принты в функции-обработчик для наглядности,

    Код (Lua):
    print('Start mqtt')
    if not m then
        m = mqtt.Client( "esp1", 120, "user", 'passwd')
        m:lwt('esp1/state', "OFF", 0, 1)
        m:on("message", function(conn, topic, dt)
            local top = string.gsub(topic, "/command/","")
            --print('Got now:',top, ":", dt)
            if dt then
                dat.mqtemp = dt
            end
        end)
        m:on("offline", function(con)
         print(' m:on("offline"')
            dofile('setmqtt.lua')
        end)
    else
        m:close()
    end

    local count = 0
    local connecting = function(getmq)
        if wifi.sta.status() == 5 then
            print('Got wifi')
            tmr.stop(getmq)
            tmr.unregister(getmq)
            getmq = nil
            m:connect('192.168.0.103', 1883, 0, 0,
            function(con)
                print("Connected to Broker")
                --m:subscribe("narod/28B1AED5040000A1",0, function(conn)
                --    print("Subscribed.")
                --end)
                m:publish('/state',"ON",0,1)
                count = nil
            end,
            function(con)
             print(' m: error"')
                dofile('setmqtt.lua')
            end)
        else
            print("Wating for WiFi "..count.." times")
            count = count + 1
        end
    end
    tmr.create():alarm(5000, 1, function(t)
        connecting(t)
    end)
     
    баг проявляется в момент когда соединение с роутером есть а с mqtt сервером нет

    upload_2018-8-13_23-39-52.png
     
  14. ИгорьК

    ИгорьК Гуру

    Повторите все то же на iot.eclipse.org.
    Смотрите, у вас программа вылетает без указания на ошибку.
    Это или питание или несовместимость с брокером или баг.

    Система при ошибках программирования всегда пишет в чем дело.
    Я не смог повторить ваш вариант. Модуль всегда писал что ему не нравится.
     
  15. ИгорьК

    ИгорьК Гуру

    А... Вы не сервер дергаете, а брокер.
    Знаете, не могу сказать ничего.
    Я моделировал нормальную ситуацию: нет электричества - нет сети и брокера. Включился роутер - включится и брокер.
    Брокер не может "мерцать" - то есть, то нет.
    Если он упал, то и не поднимется, я так полагаю.
    Завтра будет время, поукладываю свой брокер, посмотрю.

    Повторюсь, падение системы без опознавательных знаков есть ее баг.

    Насколько ситуация значима для вас - вам решать. Nodemcu при падении просто перегружаются, что в 95% случаев не критично.
     
  16. Ilya._.Light

    Ilya._.Light Нуб

    У меня брокер работает на домашнем сервере его я и дергаю, лень лезь в консоль и отключать брокер. Баг конечно не критичен, после перезагрузки контролер начнет в цикле стучатся к брокеру нормально работая. Но допустим захочу я вечерком обновить сервак и тут все устройства начнут бодра рестаритися, особо неприятно если на них завести освещение.
     
  17. ИгорьК

    ИгорьК Гуру

    Показываю. Проверил три раза подряд, все работает прекрасно:



    setglobals.lua:
    Код (Lua):
    MQTT_CLIENT_ID = 'clock'..node.chipid()
    MQTT_LOGIN = 'Login'
    MQTT_PASSWORD = 'Pass'
    MQTT_TOPIC = 'topic_test12341'
    MQTT_BROKER_IP = 'Мой_Сервер'
    MQTT_BROKER_PORT = 1883
    print('myClient', MQTT_CLIENT_ID)
    dat = {}
    killtop = {}
    dofile('setmqttQ.lua')
     
    setmqttQ.lua:
    Код (Lua):
    print('start mqtt heap: '..node.heap())
    if not mqttClient then
        mqttClient = mqtt.Client( MQTT_CLIENT_ID, 60, MQTT_LOGIN, MQTT_PASSWORD)
        mqttClient:lwt(MQTT_CLIENT_ID..'/state', "OFF", 0, 0)
        mqttClient:on("message",
            function(client, topic, data)
                local top = string.gsub(topic, MQTT_TOPIC.."/command/","")
                print('Got now:',top, ":", data)
                if data then
                    table.insert(killtop, {top, data})
                    if not dat.analiz then
                        -- dofile("analize.lua")
                    end
            end
        end)
        mqttClient:on("offline", function(con)
            dat.broker = false
            print('mqttClient: offline')
            dofile('setmqttQ.lua')
        end)
    end

    mqttClient:close()
    print("mqttClient:close")

    local count = 0
    print("set count")
    local connecting = function(getmq)
        if wifi.sta.status() == wifi.STA_GOTIP then
            print('Got wifi')
            tmr.stop(getmq)
            print('tmr.stop(getmq)')
            tmr.unregister(getmq)
            print('tmr.unregister(getmq)')
            getmq = nil
            print('getmq = nil')
            mqttClient:connect(MQTT_BROKER_IP, MQTT_BROKER_PORT, 0, 0,
            function(client)
                print("Connected to Broker")
                -- mqttClient:subscribe(MQTT_TOPIC.."/command/#",0, function(conn)
                -- mqttClient:subscribe("/#",0, function(conn)
                mqttClient:subscribe(MQTT_TOPIC..'/command/#',0, function(conn)
                    print("Subscribed: "..MQTT_TOPIC.."/command/#")
                end)
                mqttClient:publish(MQTT_TOPIC..'/state',"ON",0,0)
                dat.broker = true
                count = nil
            end,
            function(client, reason)
                print("mqtt error: "..reason)
                dofile('setmqttQ.lua')
            end)
        else
            print("Wating for WiFi "..count.." times at heap: "..node.heap())
            count = count + 1
        end
    end
    print("set connecting")
    tmr.create():alarm(5000, 1, function(timer)
        print("tmr.create")
        connecting(timer)
    end)
    Прошивка в приложении.
     

    Вложения:

    Последнее редактирование: 14 авг 2018
  18. Ilya._.Light

    Ilya._.Light Нуб

    Вечером проверю у себя, надо еще попробовать прошивку пере собрать, может в ней косяк
     
  19. Ilya._.Light

    Ilya._.Light Нуб

    Короче так и не удалось понять от куда баг, если через консоль ребуташь сервер то брокер адекватно прекращает сесию и модуль сразу пытается пере подключится, и с успехом это делает. Если просто вы тащить сетевой кабель из сервера то по истечению времени ожидания указного при создании клиента, с большой вероятностью модуль ляжет при попытке пере переключиться. Проблему решил предав управление запуском файла с настройкой mqtt в в цикл main, есть флаг сбрасываемый при потери связи, в main его проверяем. Так все начало работать стабильно при всех сценариях.
    В свое время я отказался от использования ардуиновской среды и за подобных багов вылезавших то тут то там.
     
  20. ИгорьК

    ИгорьК Гуру

    Мне очень высоко на шкаф надо лезть для таких экспериментов.