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

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

  1. ИгорьК

    ИгорьК Гуру

    Нет, вот это:
    Код (C++):
    print(b10001100+b11110001)
     
  2. serg3295

    serg3295 Гуру

    Это да. Но есть решение, предложенное Иерузалимски.
    Код (C++):
    function b (s)
      return tonumber(string.gsub(s, "_", ""), 2)
    end

    print(b'1001_0001' + b'10')
    print(b'10010001' + b'10')

    print(tonumber(0x93))
     
     
    ИгорьК нравится это.
  3. ИгорьК

    ИгорьК Гуру

    Никогда не встречал. Пытаюсь понять как это работает. Все просто :)
     
    Последнее редактирование: 5 мар 2023
    serg3295 нравится это.
  4. obuhanoe

    obuhanoe Гик

    Игорь, подскажите - Вами написанная библиотека имеет точность до 0,5С (9 бит)?
    Встречаю в нескольких источниках - что точность у датчика можно установить до 12 бит соответственно и точность можно увеличить.
    Или я не правильно понимаю про биты?

    Спасибо.
     
  5. ИгорьК

    ИгорьК Гуру

    Навскидку - 12 бит. Помню, что задержку установлена по умолчанию 750мс, а это как раз для 12 бит.

    Короче, библиотека никак не устанавливает точность, а работает по умолчанию. По умолчанию и есть 12 бит, а иное - нужно устанавливать. Так помнится. Почитайте документацию, где-то есть даже русский перевод.

    upload_2023-3-31_12-31-31.png
     
    Последнее редактирование: 31 мар 2023
    obuhanoe нравится это.
  6. obuhanoe

    obuhanoe Гик

    Понял, что это максимальное точность.

    Спасибо.
     
  7. ИгорьК

    ИгорьК Гуру

    Итак, если dev-esp32-idf5-testing не компилируется на виртуальной машине и в ошибках прямо не выдает причину, то оная находится в одном из файлов папки build/log и гласит, что "компиляция не заточена под процессор pentium2, и нечего мне совать эту хрень."
    Бороться с этим можно прямо указав процессор в настройках виртуальной машины, если она такое позволяет.
     
    Последнее редактирование: 11 апр 2023
    serg3295 нравится это.
  8. za9c

    za9c Нуб

    помогите! esp8266
    ошибка: cannot open init.lua
    влил простенький код в init.lua
    local mytimer = tmr.create()
    mytimer:register(5000, tmr.ALARM_AUTO, function (t) print("expired"); end)
    mytimer:start()
    кнопкой reload => он его видит

    сниппетом
    if file.open("init.lua") == nil then
    print("init.lua deleted or renamed")
    else
    print("Running")
    file.close("init.lua")
    -- the actual application is stored in 'application.lua'
    -- dofile("application.lua")
    end

    не видит => "init.lua deleted or renamed"
    нажимаю вручную Save to esp => работает норм до выключения!
    купил 5 модулей и у всех одна и таже лабуда

    bild такой
    NodeMCU 3.0.0.0 built on nodemcu-build.com provided by frightanic.com
    branch: release
    commit: f25dc56d3c6213b8ac7ce46d1293466137746eae
    release:
    release DTS: 202112300746
    SSL: false
    build type: float
    LFS: 0x0 bytes total capacity
    modules: file,gpio,net,node,tmr,uart,wifi
    build 2023-04-13 13:37 powered by Lua 5.1.4 on SDK 3.0.1-dev(fce080e)
     
  9. serg3295

    serg3295 Гуру

    Проверил ваш код. Он нормально выполняется как из сниппета, так и при запуске. Правда, проверял на прошивке с Lua 5.3, но не думаю, что здесь это важно.
    Проверьте, нет ли в имени файла init.lua русской буквы а. Или других недопустимых знаков.
     
    ИгорьК и za9c нравится это.
  10. za9c

    za9c Нуб

    ctrl+c "init.lua" из вашего поста и ctrl+v в название файла! и о чудо => заработало! переименовываю с клавиатуры и не работает => хотя точно на аглицком! Это какое-то чудо! Спасибо ВАМ!
     
  11. obuhanoe

    obuhanoe Гик

    Доброго всем дня.
    Понадобилось мне в домашних условиях организовать включение подсветки для рассады в двух комнатах.
    Заявлялись у меня старенькие ESP8266 mini - изменение графика включения/выключения иногда нужно менять в зависимости от возраста рассады.
    Городить скачивание графика из интернета не охота было (хотя на даче именно так и работает) - решил на каждой ESP8266 создать "Маленький сервер", при заходе на который будет только элемент textarea и кнопка Сохранить.
    Удобно зашел по IP забил данные графика (чтобы вычленить данные у меня начинается на W={, а заканчивает на } - каждый может себе любые значения придумать), жмякаешь кнопку сохранить и данные сразу в eSP.
    И кстати из любой точки мира также можно зайти в web-сервер ESP - если у Вас роутер кинетик, KeenDNS и прямые руки))))))

    На ESP32 реализовано немного по другому: из-за idf 4.4 вместо file.open => io.open и так далее, а также почему то не получилось через page.lua сделать, а пришлось код web-сервера хранить в переменной в server.lua в одну строку.

    page.lua
    Код (HTML5):

    <!DOCTYPE HTML>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Set Graph</title>
    </head>
    <body>
      <p align="center">График:</p>
      <form action="/set_graph.php">
      <p align="center"><textarea name="text_graph" cols="40" rows="5">$graph</textarea></p>
      <p align="center"><input type="submit" value="Сохранить"></p>
      </form>
    </body>
    </html>
     
    server.lua
    Код (Lua):

    do
       srv = net.createServer(net.TCP)

       function receiver(sck, data)
         -- переменная для хранения данных из файла
         local graph = nil

         -- читаем из файла scheduler.lua
         if not string.match(data, "favicon.ico") and not string.match(data, "set_graph.php") then
           if file.open("scheduler.lua", "r") then -- idf 3.3
            repeat
               local line = file.readline()
               if line then
                 graph = (graph or "W={") .. line
               end
             until line == nil
             graph = graph .. '}'
             file.close()
           end
         end
       
         -- сохраняем в файл scheduler.lua
         if string.match(data, "GET /set_graph.php") then
         -- преобразование спец.символов
         local data_tmp = string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(data, "%%7B", "{") , "%%3D", "="), "%%7D", "}"), "%%3B", ";"), "%%2C", ","), "%%3A", ":"), "%%0D", "_"), "%%0A", "")
          local start_pos, end_pos = string.find(data_tmp, "W={"), string.find(data_tmp, "}")
          graph = data_tmp:sub(start_pos+3, end_pos-1)

          graph = string.gsub(graph, "_", "\r\n")
         
          local fr = file.open("scheduler.lua", "w") -- idf 3.3
          if fr then
              -- пишем в файл график работы
              fr:write(graph)
              fr:close()
           else
              print("FILE_ERROR")
           end
         end
       
         local function closec()
           sck:close()
           conn = nil
      collectgarbage()
         end
       
         local function send()
           if file.open("page.lua", "r") then
            repeat
               local line = file.readline()
               if line then
                 if graph ~= nil then
                  line = string.gsub(line, "$(%w+)", graph)
                 end
                 sck:send(line)
               end
             until line == nil
             file.close()
           else
            sck:close()
           end
         end
       
         sck:on("sent", closec)
         send()
       end

       srv:listen(80, function(conn)
        conn:on("receive", receiver)
       end)

    end
     
     
    serg3295 и ИгорьК нравится это.
  12. 8bitai

    8bitai Нерд

    Всем доброго времени!
    Неуверен что сюда можно писать своё такое свидетельство своего почтения всем присутствующим, прошу простить больше не буду.:)
    Очень счастлив что нашел амперку, как-то на слух она попадалась, но почему-то не уточнял где и что это.
    Очень согласен со всеми словами автора темы в начале - на редкость приятен луа и такой стиль программирования в особенности для обычного любителя какой кроме ассемблера в мплабе или аврстудио ничего не кодил.
    С радостью бы не менял старых привычек и с еспами, но как сказал автор времени над вход через такую дверь уйдёт уйма при том что нужно не так много.
    Сходу вопрос про лфс
    До недавних пор был ненужен так как всё минимальное что реализовывалось всегда и без него отлично работало и потому не особо глубоко интересовался, так как ещё и думал что возможности этого приятного сока ЕСП8266 ограничены оперативкой..
    С момента знакомства с эспой остановился на билдах собственных прошивок из исходников НОДМЦУ дабы опционально выбирать нужное и исключать не нужное.
    Так вот прочитав вот это видимо не слишком внимательно и собрав прошивку с опцией #define LUA_FLASH_STORE 0x20000 в user_config.h получил вроде бы искомое вот это upload_2023-5-12_21-12-9.png
    И тут меня посетило грустное "и чё" - всех чайников :)
    Куда бы я мог быстро ткнуться?,
    чтоб узнать как наилучшим простым а главное динамическим способом заливать модифицировать и перезаливать лфс образы в создавшуюся область.
    Очень понравилась соседняя тема "Расширение для vs code" какую собираюсь внимательно курить, для того чтоб попытаться уйти от есплорера и в особенности если она поможет удобно работать с лфс..
     

    Вложения:

    ИгорьК нравится это.
  13. serg3295

    serg3295 Гуру

    На странице 56 этой темы обсуждается как заливать образ LFS в Esp через командную строку с помощью различных программ.
    Сейчас добавился вариант загрузки с помощью расширения VS Code.
    Создание образа lfs.img осуществляется утилитой luac.cross. Если вы собираете прошивку самостоятельно, то эта утилита появляется у вас в результате сборки.
    Необходимо учитывать, что luac.cross должен соответствовать параметрам сгенерированной прошивки, в частности:
    • архитектура esp 8266 | 32
    • версия Lua 5.1 | 5.3
    • тип int | float
     
    8bitai и ИгорьК нравится это.
  14. 8bitai

    8bitai Нерд

    Ещё один вопрос про LFS в принципе
    Я так и не понял - для динамической перезаписи из кода программы пользователя эта область доступна или нет?
    к примеру подобным образом?
    Код (Text):
    print("Updating mcfg!")
    file.remove("mcfg.lua")
    file.open("mcfg.lua","w+")
    temp="ntpius="..ntpius..""
    file.writeline(temp)
    temp="PTs="..PTs..""
    file.writeline(temp)
    temp="Wds="..Wds..""
    file.writeline(temp)
    temp="wifist= \""..wifist.."\""
    file.writeline(temp)
    temp="DDhour= \""..DDhour.."\""
    file.writeline(temp)
    temp="DDmin= \""..DDmin.."\""
    file.writeline(temp)
    temp="DSlp= \""..DSlp.."\""
    file.writeline(temp)
    temp="LPWday="..LPWday..""
    file.writeline(temp)
    file.close()
    dofile('flags.lua')
     
    Последнее редактирование: 14 май 2023
  15. ИгорьК

    ИгорьК Гуру

    А что мешает попробовать и рассказать о результатах? Ну просто сызмальства грузить других своими мыслями когда под рукой плата - не есть верно.
     
  16. 8bitai

    8bitai Нерд

    Может кто-то подсказать почему перестал работать такой код с переходом на nodemcu-firmware 3.x.x?
    Код (C++):
    s=net.createServer(net.TCP)
    s:listen(23,function(c)
       con_std = c
       function s_output(str)
          if(con_std~=nil)
             then
             con_std:send(" \r")
             con_std:send(str)
          end
       end
       node.output(s_output, 0)
       c:on("receive",function(c,l)
        node.input(l)
       end)
       c:on("disconnection",function(c)
          con_std = nil
          node.output(nil)
       end)
       print(("Connected to Node_T124 build 310321. (%d mem free, %s)\n\r"):format(node.heap(), wifi.sta.getip()))
    end)
    ругается что ожидал строку но получает таблицу
     
  17. ИгорьК

    ИгорьК Гуру

    Видимо в какой-то функции изменено количество или порядок аргументов.
     
  18. serg3295

    serg3295 Гуру

    Потому что в callback output параметром является pipe object.
    Если вы задумали запустить демон telnet, то используйте в качестве отправной точки пример из репозитория nodemcu.
    Или вот файл с моими комментариями.
    Код (Javascript):
    -- A telnet server  T. Ellison,  June 2019

    local M = {}
    local modname = ...
    ---@param socket socket
    local function telnet_session(socket)
      local node = node
      local stdout  ---@type pipeObj

      ---@param opipe pipeObj
      ---@return boolean
      local function output_CB(opipe) -- upval: socket
        stdout = opipe
        local rec = opipe:read(1400)
        if rec and #rec > 0 then socket:send(rec) end
        return false -- don't repost as the on:sent will do self
      end

      --- Sends data to remote peer
      ---@param skt socket
      local function onsent_CB(skt) -- upval: stdout
        local rec = stdout:read(1400)
        if rec and #rec > 0 then skt:send(rec) end
      end

      local function disconnect_CB(skt) -- upval: socket, stdout
        node.output()
        ---@diagnostic disable-next-line: cast-local-type
        socket, stdout = nil, nil -- set upvals to nil to allow GC
      end

      node.output(output_CB, 0)
      socket:on("receive", function(_, rec) node.input(rec) end)
      socket:on("sent", onsent_CB)
      socket:on("disconnection", disconnect_CB)
      print(("Welcome to NodeMCU world (%d mem free, %s)"):format(node.heap(), wifi.sta.getip()))
    end

    ---@param self table
    ---@param ssid? string
    ---@param pwd? string
    ---@param port number
    function M.open(self, ssid, pwd, port)
      local tmr, wifi, uwrite = tmr, wifi, uart.write
      if ssid then
        wifi.setmode(wifi.STATION, false)
        wifi.sta.config { ssid = ssid, pwd = pwd, save = false }
      end
      local t = tmr.create()
      t:alarm(500, tmr.ALARM_AUTO, function()
        if (wifi.sta.status() == wifi.STA_GOTIP) then
          t:unregister()
          t = nil ---@diagnostic disable-line: cast-local-type
          print(("Telnet server started (%d mem free, %s)"):format(node.heap(), wifi.sta.getip()))
          M.svr = net.createServer(180)
          M.svr:listen(port or 23, telnet_session)
        else
          uwrite(0, ".")
        end
      end)
    end

    function M.close(self)
      if self.svr then self.svr:close() end
      package.loaded[modname] = nil
      modname = nil
    end

    return M

    И предложение, не относящееся к вопросу.
    Если вы используете расширение LuaLS, то в него включен форматтер кода. Его можно вызвать через контекстное меню, или комбинацией клавиш Ctrl+Shift+I
     
    8bitai и ИгорьК нравится это.
  19. ИгорьК

    ИгорьК Гуру

    В противном случае - Ctrl+Alt+F
     
    serg3295 нравится это.
  20. serg3295

    serg3295 Гуру

    А, ну да....
    В Windows и Linux разные комбинации клавиш. И не только в этом случае.
     
    ИгорьК нравится это.