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

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

  1. SergeiL

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

    Читаем правила, вставляем код правильно!
     
    NikitOS нравится это.
  2. Valeriy_esp

    Valeriy_esp Нерд

    Почему вы решили, что вы с профессором у меня не в милости, я не знаю. Я про вас
    и про профессора ни чего плохого не писал. Наоборот, вам лично я благодарен, за ваш труд.
    А кто у меня не в милости, так это Atmel, который расслабился почивая на лаврах, и дал себя обойти.
    Да и весь мир кудо-то катится. Когда создавали язык высокого уровня, его создавали так, чтобы операционная
    система понимала простые словарные выражения и переводила их в машинные коды, что бы машина
    могла реализовать желание человека.
    А к чему пришли сейчас? Я должен разложить по полочкам, что и как, в какой последовательности
    должен делать процессор (контроллер), что бы на выходе получить то, что мне нужно. Это о кальбаке.
    К стати в C# там тоже, всякие делегаты и кальбаки. Я считаю, что эти делегаты и кальбаки, должны были
    реализовать системщики.
    Китайцы произвели модуль. Но подобраться к нему не просто. Предлагаете Ардуино. Я его не люблю.
    Объёмный и непонятный. Для меня проще написать код для АVR на ассемблере, чем на ардуино.
    Вспоминаю Sincler, линейное программирование на бейсике или на ассемблере, озу 48кбайт.
    У NodeMCU 256kb и всё равно нужны прерывания и освобождение памяти от переменных. Интересно, а как
    на ассемблере выглядел бы код, когда система переменную под значение не выделяет, а подразумевает
    что значение существует(как то так?).
    Модуль ds18b20m можно загрузить только с 3-го или с 4-го раза. Загрузку и конфигурацию
    операционной системы (nodemcu-firmware) сделали через сайт. не догадались сделать загрузку модулей так же, как мы загружаем
    драйвера на компьютер. Docker? Но у меня Win7, а ему нужен Win10 или Linux. Сплошные препоны. Зато дёшево.
    Прошу прощения за дерзкую критику. С уважением к вам.
     
  3. ИгорьК

    ИгорьК Оракул Модератор

    Тут меня куда как круче во всех грехах обвиняют. Дело не в этом.

    Я делаю на ESP-8266 и Lua все что мне надо.

    Ну вот объясню вам я, что функция unpack в версии 5.1 отсутствует, книга Иерусалимски о версии 5.2 или 5.3, уж не помню точно. И точно я указывал на это (версии) в пункте о книге.

    А что там в моем примере не работает - фиг поймёшь, потому что вы код вставить нормально не научились. (Судя по реакции интерпретатора в коде не хватает завершающего end, но точно не скажешь с таким вашим оформлением).

    И что, мне дальше работать с вами - вы не в себе проблему видите, а во всем остальном.
     
    Последнее редактирование: 9 июл 2020
    SergeiL нравится это.
  4. SergeiL

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

     
    ИгорьК нравится это.
  5. Valeriy_esp

    Valeriy_esp Нерд

    "вы не в себе проблему видите, а во всем остальном" - я почему-то думаю, что если я не могу, то найдётся и ещё много таких как я, которые не смогут разобраться. Получается Lua + ESP-8266 не для "средних" умов.
    О вашем примере:
    print(string.format("%d", data))
    ...
    sum = sum + 1
    я переделал две строчки, код стал выполняться, а смысл (сущность) примера не потерялся.
    Вот и мне хочется сделать: измерить температуру в трёх точках и влажность в двух. Каждый час, эти значения заносить в таблицу и передавать на FTP сервер роутера. К роутеру подключен жесткий диск, на него и писать данные за последние сутки. На компьютере читать файл с FTP и выводить графики.

    А вот интересно, система и библиотеки в ардуино учитывают, что код должен работать асинхронно и с прерываниями? Или же, библиотеки написаны так же как и модуль ds18b20. Не спроста же его исключили из nodemcu-firmware, в то время как OW оставили. В своём примере вы применяете math, это то ли модуль или библиотека?
     
    Последнее редактирование модератором: 16 июл 2020
  6. ИгорьК

    ИгорьК Оракул Модератор

    Я не знаю и не умею отвечать на абстракции.
    По unpack я ответил, по своему "неработающему" коду, который вы так и не привели - не знаю. У меня здесь чуть больше одного сообщения с кодом, чтобы понимать о чем идет речь.
     
  7. ИгорьК

    ИгорьК Оракул Модератор



    Что еще?
     
  8. Valeriy_esp

    Valeriy_esp Нерд

    Вам интересен ваш код? пожалуйста:
    Только меня не это сейчас волнует. Почему я не могу получить температуру с датчика ds18b20. Библиотеку я использую вашу ds18b20m. Когда я подключил её в первый раз, мне удалось считать температуру, но только один раз. Затем ESP ушёл в бесконечную перезагрузку. Тогда у меня был создан коннект по wIFI и сервер HTTP на сокетах. Сейчас я перешил ESP, не создавал коннекта и сервера. Загружены два файла: init.lua и ds18b20m.lua. Запуск произвожу через функцию
    Код (C++):
    do
    temp = {}
    pin = 4
    del = 750
      function myWork()
        print("Got DS18b20: "..#temp)
        table.foreach(temp, print)
        ds = nil
        package.loaded["ds18b20m"]=nil
      end
       ds = require('ds18b20m')
       ds.getTemp(temp, myWork, pin, del )
    end
     
    но удаётся получить только адрес датчика.
    В init.lua у меня одна строчка: print("OK")
    C уважением.
     

    Вложения:

    • Callback.jpg
      Callback.jpg
      Размер файла:
      147,6 КБ
      Просмотров:
      56
  9. ИгорьК

    ИгорьК Оракул Модератор

    Видео я сделал персонально для вас, там все работает. Код один в один как на скриншоте.

    Могу сделать и с датчиком DS18b20. Там тоже все будет работать.

    Да, я приблизительно понимаю почему у вас это не работает. Для точного выяснения причины мне надо плотнее заняться вашими действиями, но, поймите - хочется ли мне это делать после первого же вашего поста? Мы взрослые люди.
     
    Последнее редактирование: 9 июл 2020
  10. swc

    swc Гик

    Где-то прочитал, цитата: - "Что бы вы не делали на ESP - получается очередная метеостанция". Чтобы получилось что-то другое, надо кроме Lua читать матчасть по датчикам, интерфейсам и прочему, что бы понимать, как все взаимодействует. Тогда проблем не будет.
     
  11. ИгорьК

    ИгорьК Оракул Модератор

    ESP идеально под это заточена. Но тезис этот как раз от чувака, который публиковал на Хабре стопятьсотую метеостанцию :)
    С другой стороны, часто контроль ряда параметров температуры, в первую очередь, а иногда и влажности просто критически необходим в частных домах.
     
  12. alp69

    alp69 Форумчанин

    Может светодиодиком с помощью callback'a помигать, да таймеры освоить, прежде чем измерениями заниматься?
     
    NikitOS и SergeiL нравится это.
  13. Goldln

    Goldln Нуб

    Здравствуйте. Приобрел EPS 8266-12E с USB .Прошить и запрограммировать.Что то у меня не получается с ним. Делал по инструкции как на странице 29 написано. Получается так что бинарными файлами я прошиваю. Он все в сети видится.Прошиваю дальше скетчем из сети исчезает. Прописывал в сети скетчем после загрузки. Должен показать IP адрес. Он пишет NUL не пойму. Помогите разобраться с этой проблемой
     
  14. ИгорьК

    ИгорьК Оракул Модератор

    Фотографии, скриншоты, детальное описание ваших действий...
     
  15. Goldln

    Goldln Нуб

    Спасибо что отозвались. Буду дома скину скрины.
     
  16. Cucumber

    Cucumber Нуб

    Добрый день, коллеги!
    Настало мое время задавать вопросы)
    Опять про ds18b20.
    Имеется 8266 с nodemcu 3.0.0.0. Модули в прошивке dht,file,gpio,http,i2c,mqtt,net,node,ow,sntp,tmr,u8g2,uart,wifi.
    Датчик не определяется. Пытаюсь найти его с ow для начала.
    Код (C++):
    ow.setup(4)
    addr = ow.reset_search(4)
    addr = ow.search(4)
    print(addr)
    Результат nil.

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

    Помогите, пожалуйста, найти проблему.
    Спасибо!
     

    Вложения:

  17. ИгорьК

    ИгорьК Оракул Модератор

    Последние изыскания на тему соединения ESP32 с MQTT брокером и его поддержания в плохих условиях.

    Код (Lua):
    do
        if not dat then
            dat = {
                brk = 'test.mosquitto.org',
                port = 1883,
                clnt = 'testerNow',
                alflag = '\n\n\n\t\t\t',
                ip = true
            }
            prt = print
            if file.exists'wifi32Start.lua' then dofile'wifi32Start.lua' end
        end

        local brk = dat.brk; dat.brk = nil
        local port = dat.port; dat.port = nil
        local subscribe, merror, newm, mconnect

        function subscribe(con)
            prt("Connected to "..brk..' as '..dat.clnt)
            dat.broker = true
            con:subscribe(dat.clnt.."/com/#", 0)
            con:publish(dat.clnt..'/state', "ON", 0, 1)
            prt("Subscribed")
        end

        function merror(con, reason)
            prt(dat.alflag, 'MQTT Asked!')
            con, reason, m  = nil, nil, nil
            tmr.create():alarm(15000, tmr.ALARM_AUTO, function(t)
                if not dat.ip then return end
                net.createConnection(net.TCP, 0):dns(brk, function(conn, ip)
                    conn = nil
                    if ip then
                        t:stop(); t:unregister(); t = nil
                        prt('Got Broker IP '..ip..', New connect!')
                        ip = nil
                        mconnect(newm())
                    end
                end)
            end)
            collectgarbage()
        end

        function newm()
            m = mqtt.Client(dat.clnt, 25)
            m:lwt(dat.clnt..'/state', "OFF", 0, 1)
            m:on("offline", function(con)
                con:close()
                dat.broker = false
                prt(dat.alflag, "Broker offline")
                merror(con)
            end)
            m:on("message", function(con, top, dt)
                if not killtop then killtop = {} end
                top = string.match(top, "/(%w+)$")
                prt('Got', top, dt)
                if dt then
                    table.insert(killtop, {top, dt})
                    if not dat.analiz then
                        dofile("mqttanalize.lua")
                    end
                end
            end)
            return m
        end
        function mconnect(con)
            con:connect(brk, port, 0, 0, subscribe)
        end
        merror()
    end

    Без комментариев кода.
    Запускать можно как есть - соединяется с фриварным брокером mosquitto. Единственно, перед применением необходимо завести esp32 в сеть и в каллбэке установить флаг dat.ip.
    Даже если не заведете, ничего страшного.

    Работает приблизительно так:
    upload_2020-9-29_15-27-55.png
     

    Вложения:

    • mqttset.zip
      Размер файла:
      911 байт
      Просмотров:
      31
    Последнее редактирование: 29 сен 2020
  18. ioex

    ioex Нерд

    В дополнении к пунктам 37 и 39 про LFS.
    Как обычно, проект разростается до таких размеров, что сталкиваешься с задачей "впихнуть невпихуемое".

    Итак.
    В настоящее время синтаксически кое-что поменялось.
    По варианту 2:
    Берём отсюда последний luac.cross, кладём в отдельный каталог, в подкаталог in_file кладём свои исходники и, чтобы в образе LFS работал dofile(), туда же кладём _init.lua
    Запускаем:
    luac.cross_x64_float_Lua51.exe -o out_img/LFS.img -f -m 0x40000 -l in_files/*.* > out_img/log.log
    Аплоадим в SPIFFS LFS.img, который будет лежать в out_img
    node.flashreload() пока ещё работает, но его скоро уберут. Привыкаем к
    Код (C++):
    node.LFS.reload('LFS.img')
    Появится сообщение: LFS region updated. Restarting.

    Файл init.lua должен содержать строчку
    Код (C++):
    node.LFS.get('_init')()
    Интересное замечание, скобки () в конце строки, после init'), обязательно должны присутствовать. Иначе файл из LFS не подгружается. Вероятно особенности текущей SDK, хотя упоминания в документации об этом я не нашёл.
    Аналогичным образом запускаем стартовый файл.
    Код (C++):
    node.LFS.get('start_file')()
    посмотреть список файлов в образе можно так
    Код (C++):
    for k,v in pairs(node.LFS.list()) do print(k,v) end
    LFS действительно интересная штука. Если подкрадываешься к лимитам памяти и ничего не трогать, может ещё с горем пополам работать. Но шаг влево шаг вправо, контролер вываливается в кору из-за нехватки и в ребут. С тем же объёмом кода, когда в обычных условиях node.heap() давал 10-12к, сейчас в сухом остатке 37к.
    Но при таком варианте, придётся забыть об удаленном редактировании исходников. Разве что удалённо заливать *.img и релоадить его.
     
    Последнее редактирование: 2 окт 2020
    swc и ИгорьК нравится это.
  19. ioex

    ioex Нерд

    В продолжении темы об LFS, столкнулся ещё с одной проблемой и весь вечер убил на её решение. Может быть кому-нибудь пригодится, сэкономит время и нервы =)
    Написав заметку выше, я подумал
    а почему бы и нет?

    Взяв исходники из заметки 18, загружаю на ESP образ, делаю node.LFS.reload и...ничего не происходит...
    Примечательно, что если грузить *.img через ESPlorer, reload работает как надо.
    Спустя несколько часов ковыряния в коде, случайно обнаружил, что загруженный в SPIFFS через HTTP образ больше исходного на 1 байт.
    Загвоздка в том, что при загрузке бинарного файла через HTTP POST, к файлу приклеивается 1 байт "0D" в самый конец и LFS.reload этот файл не принимает. Откуда он берётся, я так и не понял, но он был совсем не нужен. Решение оказалось достаточно простым.

    В исходниках NodeMCU_LUA_WebServer2.zip (или в его облегченной версии) в файле http.lua надо найти строчку
    Код (C++):
    POST = request:sub(0, tonumber(ContentLength) - tonumber(ContentLengthOF));
    и отминусовать -1 от длинны. Это секция отвечающая за загрузку последнего блока файла.
    Должно получится примерно так:
    Код (C++):
    POST = request:sub(0, tonumber(ContentLength) - tonumber(ContentLengthOF) -1 );
    После этого образ загружается байт в байт и успешно заливается в LFS.
     
    Последнее редактирование: 2 окт 2020
    swc, serg3295 и ИгорьК нравится это.
  20. ИгорьК

    ИгорьК Оракул Модератор

    Хорошая работа, занесу топики в шапку чуть позже.
    Честно говоря, так и не пользуюсь LFS. Загружаю/выгружаю модули, выполняю файлы с передачей им данных и записью результатов в глобальную таблицу.

    До сих пор не упёрся в пределы памяти.
    Хотя исчерпать её несложно, ИМХО, в двух случаях: делать веб на модуле или рисовать картинки на дисплее.

    Старая привычка - тестировать каждый кусок кода на потерю памяти и неувеличение регистра. Ну а если все ок - несложно его и выгрузить.

    Загрузка по по сети тоже как-то не прижалась. Тем не менее, каждое устройство имеет веб-сервер для работы с файлами на устройстве. Вот через него очень очень редко что-то правлю.
     
    swc и ioex нравится это.