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

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

  1. Mitrandir

    Mitrandir Гуру

    Игорь думаю имеет в виду рекурсивно таймер запускать.

    Предположим у нас бесконечный стек. Если сделаем так:
    Код (C++):
    function f()
    print("dummy ");
      f();
    end

    f();
    То такая рекурсия всеравно положит вайфай
     
  2. parovoZZ

    parovoZZ Гуру

    периодически из нее вылезать. Не знаю как там lua устроена, а в нормальных языках организовывается callback функциями.
     
  3. ИгорьК

    ИгорьК Гуру

    Иерусалимски утверждает, что в Lua на рекурсии с памятью проблем нет.

    upload_2018-9-7_15-28-12.png

    Ясный перец, что NodeMCU Lua делает не Иерусалимски, поэтому проверил лично и доложил в посте (что это не так!).
    А если хитрая улыбка намекает, что я не слышал про стек и его переполнение - то это зря ;)
     
    Последнее редактирование: 7 сен 2018
    Mitrandir нравится это.
  4. ИгорьК

    ИгорьК Гуру

    Я же показал, что работает. И работает даже с таймером на 1 мс.

    Не положит. Положит, к сожалению, память.
     
  5. ИгорьК

    ИгорьК Гуру

    А чей-то вы все в теме про Lua собрались? :)
     
  6. Mitrandir

    Mitrandir Гуру

    Т.е в луа есть механизм, который позволит функционалу вайфая вклиниться между вызовами функций?
     
  7. ИгорьК

    ИгорьК Гуру

    Да. Однозначно.
     
  8. ИгорьК

    ИгорьК Гуру

    upload_2018-9-7_15-50-43.png
     
    Последнее редактирование: 7 сен 2018
  9. parovoZZ

    parovoZZ Гуру

    канеш. Но это не в луа, а в SDK, который использует LUA. Скорее всего, что интерпретатор писан на FreeRTOS, поэтому хотим - не хотим, а потоки разделяются вне нашей программы.
     
  10. parovoZZ

    parovoZZ Гуру

    Школота в школе к партам прилипла.
     
  11. ИгорьК

    ИгорьК Гуру

    Похоже, не угадал. Там по ссылочке смотри.

    "If you need to customize init data then first download the Espressif SDK 2.2.0 and extract esp_init_data_default.bin. Then flash that file just like you'd flash the firmware. The correct address for the init data depends on the capacity of the flash chip."
     
  12. SergeiL

    SergeiL Оракул Модератор

    Да нет. Это мое, личное, просто я, как-то к рекурсии, с опаской отношусь.

    Я же почти все на Си пишу. А что может быть более страшным с программой написанной на Си, где вроде все продумал, буфера нужного размера, указатели правильно настроены.
    Все должно правильно работать, а тут стек на кучу наехал, и все сломалось. И хрен вычислишь.:(
     
  13. ИгорьК

    ИгорьК Гуру

    Ой, а это что?
     
  14. ИгорьК

    ИгорьК Гуру

    33. MQTT: То ли баг, то ли ...
    Друзья, в соответствующем топике о скелете программы был файл установки связи с MQTT брокером.
    Вот его кусочек:
    upload_2018-9-13_10-53-16.png

    То есть, в callback функцию, вызываемую по провалу связи с брокером, передается две переменные: ссылка на соединение mqtt и причина бардака в нем.

    Особого смысла в распечатке причины неустановления связи с брокером в рабочем устройстве нет (это вообще цифра), и как-то само-собой и без злого умысла у меня эта часть кода превратилась в такую:
    Код (Lua):
    function(con)
        dofile('setmqtt.lua')
    end)
    И оно, собственно, вполне работало. Однако, иногда-иногда, совсем не часто, при потере интернета и его восстановлении устройство перезагружалось.
    Об этом писал здесь один из гостей. Я ошибку отловить не мог.

    В общем, суть вот в чем. Если в аргументах забыта переменная reason, то при потере wifi и восстановлении связи (при условии что wifi есть, а брокера - нет) этот модуль вызывает ошибку с перезагрузкой. В оповещении пишет, что
    upload_2018-9-13_11-9-39.png

    не закрыт какой-то вызов if в самом начале файла.
    Замечу, что ошибки такого рода выявляются еще в процессе загрузки скрипта в модуль, поэтому пришлось поломать голову: все if в скрипте безусловно закрыты.

    Lua не требует иметь в аргументах функции столько переменных, сколько пытается "воткнуть" ей вызывающий. Вот что пишет Иерусалимски:

    upload_2018-9-13_11-44-0.png

    Поэтому, здесь потеря переменной reason не является ошибкой программирования. Скорее - это особенность текущей реализации оболочки.

    Возможно, в темах есть скрипты, где такая потеря произошла. Полагаю, во всех случаях это ведет к перезагрузке модуля при (1) восстановлении wifi и (2) отсутствии в этот момент брокера, что не слишком влияет на работу устройств и плохо диагностируется.

    Думаю, знать и понимать эту ситуацию следует.

    А что делать? Не забывать reason и все работает!
     
    Последнее редактирование: 13 сен 2018
  15. ИгорьК

    ИгорьК Гуру

    34. Чуть-чуть про DS18b20.

    У NodeMCU есть модуль ds18b20. Честно говоря, я им не пользовался, поскольку выдает он странное количество информации и не в той последовательности, что, обычно, нужна.

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

    Код (Lua):
    -- Прошивка - float
    local ow_pin = 4 -- Нога датичка
    ds18b20.setup(ow_pin)
    temper = {} -- Таблица для сбора температуры

    -- Минимально, для одного датчика:
    ds18b20.read(
    function(_,_,_,temp)
        temper.ds18b20 = string.format("%.1f",temp)
        print(temper.ds18b20)
    end,{})

    -- Для многих датчиков минимально
    ds18b20.read(
    function(ind,_,_,temp)
        temper[ind] = string.format("%.1f",temp)
        print(temper[ind])
    end,{})
    -- Для многих датчиков с адресом
    ds18b20.read(
    function(_,rom,_,temp)
        rom = 'ds'..string.format("%02X%02X%02X%02X%02X%02X%02X%02X",string.match(rom,"(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(%d+)"))
        temper[rom] = string.format("%.1f",temp)
        print(temper[rom])
    end,{})
     
    Mitrandir нравится это.
  16. Mitrandir

    Mitrandir Гуру

    Он опенсорс? Форкнуть и оттюнинговать
     
  17. ИгорьК

    ИгорьК Гуру

    Ой, ё...
    Вот решение выше, и все.
     
  18. ИгорьК

    ИгорьК Гуру

    Самое фиговое в этом модуле от NodeMCU, что он вызывает Callback для каждого датчика на шине, а не по получению всех данных от всех датчиков.
    Это есть ну очень фигово. Поэтому мне мой милее - он исполняет функцию обратного вызова после всех датчиков.
    Для одного датчика все не принципиально.

    Но память... Иногда она важнее.
     
  19. Quartz1912

    Quartz1912 Нуб

    Доброго дня.
    stdin:19: attempt to call field 'create' (a nil value)
    вот так вот...подскажите, как решить данную проблемке
    код из примера.
     
  20. ИгорьК

    ИгорьК Гуру

    О чем речь.