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

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

  1. swc

    swc Нерд

    Никто не работал с nRF24L01 на Lua?
     
  2. ИгорьК

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

    Трэш. Два модуля о 2.4 Ггц в одном флаконе.

    Применяйте НС-12 в связке с ESP-8266, это, ИМХО, надежнее.
     
    Последнее редактирование: 9 окт 2019
  3. swc

    swc Нерд

    Согласен. Но уже заказал nRF24L01. Попробовать.
     
  4. ИгорьК

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

    Тему по этому модулю видели? Он сам по себе не подарок.

    Настоятельно рекомендую НС-12 - просто и надёжно
     
  5. ИгорьК

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

    Вот еще, спросите у @DetSimen - он тоже какие-то хорошие модули применяет. Эти - ну зело не рекомендую.
     
  6. DetSimen

    DetSimen Спамовредитель Модератор

    мои не на Lua. Но как беспроводные удлиннители Serial - великолепны, по крайней мере мне понравились больше чем NRF. Кабутто два (три, четыре) контроллера железно соединены проводами по Serial длинной до 50м, только проводов нету. :)
    Искать по словам JDY-40. (Правда, оне тоже 2.4 ГГц).

    Можеш, поизучать тут http://arduinolab.pw/index.php/2019/05/15/radiomoduli-jdy-40-2-4g-s-uart-interfejsom/
     
    Последнее редактирование: 9 окт 2019
    ИгорьК нравится это.
  7. ИгорьК

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

    UART он на любом языке УАРТ.
     
  8. swc

    swc Нерд

    Спасибо за наводку. Именно то, что мне нужно. Заказал.
     
    DetSimen нравится это.
  9. ИгорьК

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

    46. FRAM FM24CL64B.
    Купил это здесь, спасибо @ostrov за наводку, ибо вообще раньше не слышал об этой замечательной вещи.
    Накидал модуль, проще не куда.

    Даташит.
    Протокол i2c. По умолчанию, адрес микросхемы 0x50, три ноги выделено для установки адресов, итого можно собрать блок из 8 штук.
    Максимальный адрес ячейки в одной МС - 0x1FFF = 8191.

    Модуль настолько прост, что аж не удобно выкладывать, но может, кому потребуется и сбережет немного времени.
    _fram.lua:
    Код (Lua):
    local M = {}
    M.dev_addr = 0x50
    M.id  = 0
    M.sda = 5
    M.scl = 6
    M.init = function(id, sda, scl, speed, dev_addr)
        M.id = id or M.id
        M.sda = sda or M.sda
        M.scl = scl or M.scl
        M.speed = speed or 400000
        M.dev_addr = dev_addr or M.dev_addr
        print('id, sda, scl, speed, address:', M.id, M.sda, M.scl, M.speed, M.dev_addr)
        i2c.setup(M.id, M.sda, M.scl, M.speed)
    end

    function M.read(addr, len)
        local dt
        local reg_msb = bit.rshift(addr, 8)
        local reg_lsb = bit.band(addr, 0xFF)
        len = len or 1
        i2c.start(M.id)
        i2c.address(M.id, M.dev_addr, 0)
        i2c.write(M.id, reg_msb, reg_lsb)
        i2c.stop(M.id)
        i2c.start(M.id)
        i2c.address(M.id, M.dev_addr, 1)
        dt = i2c.read(M.id, len)
        i2c.stop(M.id)
        return dt
    end

    function M.write(addr, data)
        local dt
        local reg_msb = bit.rshift(addr, 8)
        local reg_lsb = bit.band(addr, 0xFF)
        i2c.start(M.id)
        i2c.address(M.id, M.dev_addr, 0)
        i2c.write(M.id, reg_msb, reg_lsb)
        dt = i2c.write(M.id, data)
        i2c.stop(M.id)
        return dt
    end
    return M
    Применять.
    Спецификация i2c в Lua позволяет работать с тремя видами данных - число (одно!), строка и таблица.
    Все что пишется в микросхему превращается в единичный байт типа "строка". Следовательно, при извлечении чисел(!) из микросхемы каждый раз следует преобразовывать результат через string.byte(результат). Строки читаются и пишутся в микросхему без преобразования.

    _framSample.lua:
    Код (Lua):
    -- FM24CL64B
    do
    fram = require("_fram")
    fram.init()

    local addr = 0x1045
    local addr1 = 0x1020
    local addr3 = 0x0020
    local count
    local str = "Big data!"
    local tb = {1,2,3,4,5,6,7,8,9,0}

    count = fram.write(addr, 123)
    print(count, " bytes written from Number")

    count = fram.write(addr1, str)
    print(count, " bytes written from String")

    print(fram.write(addr3, tb), " bytes written from Table")

    print('Read number:', string.byte(fram.read(addr)))
    print('Read string: ', fram.read(addr1, #str))

    local res = fram.read(addr3, #tb)
    print('Read table:')
    for i = 1, #res do print(string.byte(res, i,i)) end
    end
    upload_2019-10-10_12-46-50.png

    Ясный пень, если вам мало 8191 ячеек и вы будете увеличивать количество микросхем в связке, этот модуль надо будет дорабатывать.
     
    Последнее редактирование: 10 окт 2019
  10. naz

    naz Нерд

    Повторил проект IoT ч.3.3- все нормально, остаток памяти 17 кбайт. Попытался добавить дисплейчик Nextion, добавил
    Код (C++):
    uart.on("data",1,
        function(dt) ...
    но Uart захлебнулся, в терминале работать невозможно на скорости 9600. Кто- нибудь пробовал?
     
  11. ИгорьК

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

    Ну вообще то этот проект создан для примера как занасиловать ESP-8266 по самое небалуй... На Некстион он не рассчитан.

    Но, попробуем, что за симптомы точнее и что за код вы добавили.
     
  12. naz

    naz Нерд

    Проект:
    Код (C++):
    NodeMCU custom build by frightanic.com
        branch: master
        commit: 11592951b90707cdcb6d751876170bf4da82850d
        SSL: false
        modules: adc,bit,dht,file,gpio,mqtt,net,node,ow,rtcfifo,rtcmem,rtctime,sntp,tmr,uart,wifi
    build created on 2019-01-30 13:13
    powered by Lua 5.1.4 on SDK 2.2.1(6ab97e9)
    _ds18b20.lua    : 1577 bytes
    analize.lua     : 1918 bytes
    dht.lua         : 429 bytes
    getsun.lua      : 1332 bytes
    init.lua        : 313 bytes
    lightnow.lua    : 1071 bytes
    main.lua        : 773 bytes
    makepubl.lua    : 319 bytes
    pubnow.lua      : 1221 bytes
    scedset.lua     : 1307 bytes
    setglobals.lua  : 849 bytes
    setmqtt.lua     : 1657 bytes
    temper.lua      : 848 bytes
    uart.lua        : 844 bytes
    ----------------------------
    Total file(s)   : 14
    Total size      : 14458 bytes

     
    Добавил в проект uart.lua
    Код (C++):
    uart.setup(0,9600,8,uart.PARITY_NONE,uart.STOPBITS_1,1)
    lt = false
    str = ""
    count = 0

    uart.on("data",1,
        function(dt)
        if lt then
            if dt == "\255" then
                count = count + 1
                if count == 3 then -
                    count = 0
                    if str == "bt1:ON" then
                       dat.heat = "ON"
                       print "dat.heat is ON"
                    else
                       if str == "bt1:OFF" then
                         dat.heat = "OFF"
                         print "dat.heat is OFF"
                       end
                    end
                    str = ""
                    lt = false
                end
            else
                str = str..dt
                if #str > 20 then str = ""; count = 0 end
            end
        end

        if str == "" and dt == "\112" then
            lt = true
        end
    end, 0)
    1. Исходное состояние, модуль uart.lua отключен. Все работает:
    Код (C++):
    =node.heap()
    27648
    >

    Sun:    7    16    18    5
    no 1    getsun.lua    true
    no 2    lightnow.lua    true
    no 3    scedset.lua    true
    no 4    temper.lua    true
    Now 26.94
    Pol is OFF!
    DHT temperature:27.2; humidity:30.7
    no 5    dht.lua    true
    naz74ru/heap  16656 0
    no 6    makepubl.lua    true
    naz74ru/pol  OFF 0
    naz74ru/tdht  27.2 0
    naz74ru/hum  30.7 0
    naz74ru/auto  ON 0
    naz74ru/siren  OFF 0
    naz74ru/heat  OFF 0
    naz74ru/arm  OFF 0
    naz74ru/light  OFF 0
    naz74ru/target  18 0
    naz74ru/t022A  26.81 0
    naz74ru/t0262  26.94 0
    Published!
     
    2. Вношу изменения: в файл setglobals.lua добавил dofile('uart.lua'), в файл analize.lua добавил пересылку данных в uart
    Код (C++):
               ...
               elseif top == "target" then
                target = tonumber(dt) or 75
                if target == 75 then
                    print('Got Wrong Target!')
                else
                    if target < 5 then
                        dat.target = 5
                    elseif target > 30 then
                        dat.target = 30
                    else
                        dat.target = target
                    end
                    --dat.auto = 'OFF'
                end
                --print('Set Target temp as '..dat.target)
                uart.write(0,'t0.txt='..'\"'..dt..'\"'..'\255\255\255')
                -- dofile("savedata.lua")
                ....
    Рестарт. Сыпется мусор, далее скорость снижает до 9600
    Код (C++):
    no 1    getsun.lua    true
    T02:16:30+00:00","sunset":"2019-10-11T13:05
    13    05    02    16
    Set:    18    5    7    16
    no 2    lightnow.lua    true
    no 3    scedset.lua    true
    no 4    temper.lua    true
    Now 27.06
    Pol is OFF!
    DHT temperature:27.4; humidity:28.1
    no 5    dht.lua    true
    naz74ru/heap  15464 0
    no 6    makepubl.lua    true
    naz74ru/pol  OFF 0
    naz74ru/tdht  27.4 0
    naz74ru/hum  28.1 0
    naz74ru/auto  ON 0
    naz74ru/siren  OFF 0
    naz74ru/heat  OFF 0
    naz74ru/arm  OFF 0
    naz74ru/light  OFF 0
    naz74ru/target  18 0
    naz74ru/t022A  26.88 0
    naz74ru/t0262  27.06 0
    Published!
     
    Внешне штатно.. но связь с модулем утеряна. На любую команду получаю недовольство
    Код (C++):
    Waiting answer from ESP - Timeout reached. Command aborted.
    И это понятно..как мне видится: пока услужливый uart.lua скурпулезно рассматривает каждый пришедший байт, остальные подождут..
    Надеюсь, коллективный разум во главе с нашим командующим поможет добавить вишенку Nextion к этому замечательному проекту
     
    Последнее редактирование: 11 окт 2019
  13. ИгорьК

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

    Так писать код для UART нельзя. Он должен только принять данные и выкинуть их вовне для обработки. Все размышления и действия над полученным - вне callback UARTa.
     
    Последнее редактирование: 11 окт 2019
    naz нравится это.
  14. ИгорьК

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

    Таки уарт, если вы не назначили на других ногах, - по нему идет общение с компьютером. Следовательно, вы убили это общение снижением скорости и добавлением на эти же ноги дисплея.
    Это работать не будет в принципе.

    Уарт будет работать с Некстион если отключить компьютер от модуля.

    На прошивке старой версии 1.5.Х можно добавить второй УАРТ на ноги 7и8, на прошивках 2.Х.Х второго полноценного УАРТ нет.

    Поэтому я перехожу на ESP32 - там второй УАРТ на 16 и 17 ногах.

    Что касается предыдущего совета, то он остаётся в силе - в callback UART "on" только прием данных, передача их в upvalue и вызов функции обработчика этих данных.
     
    Последнее редактирование: 11 окт 2019
  15. naz

    naz Нерд

    Понятно. Буду двигаться в сторону разгрузки uart.on
     
  16. ИгорьК

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

    naz нравится это.
  17. Sergku

    Sergku Нуб

    Приветствую всех. Кратенько.. Достал я nodemcu 12-e из загажника, после длительного забвения, и тут понеслась. Собрал в облаке прошивку, на дефолтных значениях:
    Код (Text):
    NodeMCU 3.0.0.0 built on nodemcu-build.com provided by frightanic.com
        branch: master
        commit: 310faf7fcc9130a296f7f17021d48c6d717f5fb6
        release: 3.0-master_20190907
        release DTS: 201909070945
        SSL: false
        build type: integer
        LFS: 0x0
        modules: file,gpio,net,node,tmr,uart,wifi
    build 2019-10-13 10:03 powered by Lua 5.1.4 on SDK 3.0.1-dev(fce080e)
    lua: cannot open init.lua
     
    кстати, завелась без прошивки esp_init_data_default.bin по адресу 0x3FC000 (правда при ресете такую дичь выводит Џr‚’’NмlЂlЊђcм2N~2"Џ"„ђnаЋnмo~BЋѓdЏЂЏlтnnѕ)
    написал диодную моргалку:
    Код (C++):
    ledPin = 4
    cnt = 0
    isOnLed = 0

    gpio.mode(ledPin, gpio.OUTPUT)

    tmr.create():alarm(1000, tmr.ALARM_AUTO, function()
            gpio.write(ledPin, isOnLed)
            isOnLed = (isOnLed == 0) and 1 or 0
            print("Power is: "..isOnLed)
            cnt = cnt + 1
            if cnt > 10 then
                print("Timer is stop")
                --tmr:stop()
            end
    end)
    и тут меня накрыло - я теперь не могу его (таймер) остановить. раньше останавливал по tmr.stop(0), Но сейчас нумерации таймеров нет. Вариант только такой остается?

    Код (C++):
    local mytimer = tmr.create()
    mytimer:register(5000, tmr.ALARM_SINGLE, function (t) print("expired"); t:unregister() end)
    mytimer:start()
     
  18. Sergku

    Sergku Нуб

    Сам спросил, сам же и отвечу :) в колбек функцию добавили параметр - созданный объект таймера, тока в доках тишина об этом, почти...
    Код (C++):
    ledPin = 4
    cnt = 0
    isOnLed = 0

    gpio.mode(ledPin, gpio.OUTPUT)

    tmr.create():alarm(1000, tmr.ALARM_AUTO, function(t)
            gpio.write(ledPin, isOnLed)
            isOnLed = (isOnLed == 0) and 1 or 0
            print("Power is: "..isOnLed)
            cnt = cnt + 1
            if cnt > 10 then
                print("Timer is stop")
                t:stop()
            end
    end)