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

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

  1. ИгорьК

    ИгорьК Гуру

    45. ESP32. Текущие заметки.
    Речь о некоторых особенностях реализации NodeMCU Lua, выявляющихся по мере работы с ним.

    Заводим один раз в сеть отдельным файлом wifi32.lua:

    Код (Lua):
    dat = {}
    wifi.start()
    wifi.mode(wifi.STATION, true)
    wifi.sta.on("disconnected", function(ev, info)
      print("Lost WiFi!")
      dat.wifi = false
      dat.ip = nil
    end)
    wifi.sta.on("got_ip", function(ev, info)
      dat.wifi = true
      dat.ip = info.ip
      print("NodeMCU Got IP:", info.ip)
    end)
    --time.settimezone('EST-3')
    --time.initntp()

    local scfg = {}
    scfg.auto = true
    scfg.save = true
    scfg.ssid = 'Точка Доступа'
    scfg.pwd = 'Супер Пароль'
    wifi.sta.config(scfg, true)
    wifi.sta.connect()
    end
    Потом init.lua выглядит приблизительно так:
    Код (Lua):
    dat = {}
    wifi.start()
    wifi.sta.on("disconnected", function(ev, info)
        print("Lost WiFi!")
        dat.wifi = nil
        dat.ip = nil
    end)
    wifi.sta.on("got_ip", function(ev, info)
        dat.wifi = true
        dat.ip = info.ip
        print("NodeMCU Got IP:", info.ip)
    end)

    local runfile = "setglobals.lua"
    print("Try Run ", runfile)
    tmr.create():alarm(5000, 0, function()
        if runfile and file.exists(runfile) then
            dofile(runfile)
        else
            print("No runfile! Stop Now!")
        end
    end)
    --------------------------------------------------------------------

    Модуль не любит больших анонимных функций, особенно внутри таймера, может уходить в Гуру Медитэйшн Еррор с выдачей многоинформации но без объяснения причин. Код, что отлично работал на ESP-8266, отказывается работать.

    --------------------------------------------------------------------

    Все локальные переменные внутри локальных функций, а особенно upvalue должны быть отправлены в nil, иначе при следующем вызове функции можно получить странные данные (отправка на nil не возбраняется и в ESP-8266)

    --------------------------------------------------------------------

    Если при установке ног функцией gpio.config() указать несуществующие ноги - модуль падает с выдачей ошибки, но без обозначения причин. Проявляется при невнимательной копипасте кода от ESP-8266.

    --------------------------------------------------------------------

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

    --------------------------------------------------------------------
    Как залить прошивку

    В архиве - прошивка. Шить программой:

    [​IMG]

    [​IMG]

    =============================================
    При очередном обновлении для сборки прошивки вылезает ошибка в каком-то файле. Выход - удалять папку modemcu-firmware-esp32 и все устанавливать по-новому.

    При сборке прошивки система попросит установить недостающие файлы python. Установка через pip сложности не представляет, кроме пакета piparsing
    Его устанавливать так. Несколько раз выполнить команду:

    Код (Bash):
    /usr/bin/python -m  pip uninstall -y pyparsing
    После чего:

    Код (Bash):
    sudo apt-get install python-pyparsing
    15.09.2020. Скомпилировал с помощью Docker в т.ч. с Bluetooth.
    upload_2020-9-16_9-7-51.png
     

    Вложения:

    Последнее редактирование: 16 сен 2020
    naz, NikitOS и swc нравится это.
  2. Ferdinand

    Ferdinand Нерд

    Прошу прощения, но малость не понятен принцип работы... Ну очень долго разбирался, но от нубских вопросов не обойтись, уж простите...
    т.е.
    if seqPointer == 33 then - это количество шагов за один оборот ?
    seqPointer = 1 - а это один оборот ?
    steps = steps +1 - ?

    На кнопку мне нужно посылать функцию dispatch с жестко заданными параметрами?
    Предполагается, что будет использоваться web-кнопка web-сервера, не могу понять как она будет работать с переменными.
     
  3. ИгорьК

    ИгорьК Гуру

    В массиве команд sequence 32 элемента, они передаются на пины за раз по 4 штуки. Как выходим за пределы - возвращаемся к первому элементу.

    Это "указатель" на передаваемый элемент массива(байт) на текущую ногу.

    Друже, вы не обижайтесь, но здесь не концерт по заявкам, я здесь немного пишу про программирование, а не решаю проблемы. Если вы прошли все что здесь написано, то вы сможете писать код. Нет - ну я не виноват.

    HD44780 I2C Lua driver
    https://github.com/devgiants/esp8266_hd44780_i2c
     
    Последнее редактирование: 25 сен 2019
  4. Nikomas

    Nikomas Нерд

    Вопрос к вам как к специалисту. Хочу сделать солнечный трекер для своих батарей. За основу беру ваши куски кода из этой темы. Но я хочу трекер с обратной связью на основе диска с кодом Грея чтобы система постоянно знала об угле панелей по 2м осям. От акселерометров решил отказаться ибо это инкрементные данные, а не абсолюсные.
    2019-09-16_122255.jpg
    Подскажите, как можно сравнивать эти данные. Ведь если взять двоичный код и код Грея, то они значительно отличаются. Например:
    0 = 000 - 000
    1 = 001 - 001
    2 = 010 - 011
    3 = 011 - 010

    И если lua знает только двоичные данные, то надо делать некий конвертер.

    Для чего все это: например по какой-то причине (ветер, снег и пр.) панели повернулись независимо от контроллера. Контроллер при включении опрашивает оптопары и видит, что панели находтяся в пол.5 вместо пол.3. Значит надо открывать совсем другую реле, REV например, а не FW.
     
  5. ИгорьК

    ИгорьК Гуру

    Давайте вы задачу сформулируете так, чтобы уборщица смогла понять, тогда и я пойму. Ну просто учитывайте, что не весь мир знает о коде Грея, а думает о нем и того меньше :)
     
  6. Nikomas

    Nikomas Нерд

    Согласен.

    Алгоритм работы трекера:
    - включаемся по таймеру и опрашиваем датчик освещенности. Если солнце есть, след. пункт, если нет - спать.
    - считывая оптопары получаем код некий код
    - сравниваем его и принимаем решение какое реле открывать. REV или FW
    - во время работы считываем оптопары. При достижении необходимого кода - выключаем реле и спать до след. включения.

    Например, при очередном включении (надо перехать в позицию 7 = 0100 Grey) и опросив оптопары контроллер понимает что находится в позиции 9 = 1101Grey. Значит надо открыть реле REV что ехать не вперед, а назад. Но если контроллер, не умеет работать с кодом Грея, то при включении, напомню что мы в поз.9 вместо 7, по бинарному коду мы находимся в поз. 13. Нам надо ехать в 0100, а это поз.4 по бинарному коду.

    Dec - Bin - Gray
    0 - 0000 - 0000
    1 - 0001 - 0001
    2 - 0010 - 0011
    3 - 0011 - 0010
    4 - 0100 - 0110
    5 - 0101 - 0111
    6 - 0110 - 0101
    7 - 0111 - 0100
    8 - 1000 - 1100
    9 - 1001 - 1101
    10 - 1010 - 1111
    11 - 1011 - 1110
    12 - 1100 - 1010
    13 - 1101 - 1011
    14 - 1110 - 1001
    15 - 1111 - 1000

    Как видите это совершенно разные сравнения. Может зашить коды Грея в таблицу затем переводить в десятичные числа и уже десятичные сравнивать?
     
  7. ИгорьК

    ИгорьК Гуру

    Делаем таблицу, где номера элементов соответствуют десятичному коду, а значения - приведенному коду Грея, или еще проще - таблицы из 8 элементов 0/1.

    Перебираем таблички-значения и определяем положение и куда двигаться.
     
  8. Nikomas

    Nikomas Нерд

    а сравнивать это можно?
     
  9. ИгорьК

    ИгорьК Гуру

    Из 8 элементов. Из 4!
     
    Последнее редактирование: 26 сен 2019
  10. ИгорьК

    ИгорьК Гуру

    Сравнивать надо не таблички, а их ключи.
     
  11. ИгорьК

    ИгорьК Гуру

    Я сейчас на смартфоне, так что код показать не могу.
     
  12. ИгорьК

    ИгорьК Гуру

    В вашей таблице - первые десятичные числа есть ключи. Их и надо сравнивать.
     
  13. Nikomas

    Nikomas Нерд

    Буду благодарен.
     
  14. alp69

    alp69 Форумчанин

    А код Грея то зачем? Зачем все так усложнять? Или у Вас контроллер поворотного устройства выдает такие значения?
     
  15. ИгорьК

    ИгорьК Гуру

    upload_2019-9-26_14-39-29.png

    А дальше приблизительно так:

    Код (Lua):
    do
    -- Ноги для чтения с оптопар
    pins = {4,5,6,7}
    -- Установка режима ног
    for i = 1, #pins do
        gpio.mode(pins[1], gpio.INPUT)
    end
    -- Значение кода Грея для каждой позиции
    graytab = {0, 1, 3, 2, 6, 7, 4, 12, 13, 15, 14, 10, 11, 9, 8}
    -- Мультипликатор значения каждой ноги
    multtab = {1,2,4,8}

    -- Позиция трекера
    local graypos = 0
    local realpos = 0
    -- Читаем ноги и сразу превращаем в значение из таблицы Грея
    for i=1, 4 do
        graypos =  graypos + gpio.read(pins[i]) * multtab[i]
    end
    print("position: "..graypos)

    -- Перебираем значения (v) в таблице Грея для поиска подходящего ключа (k)
    for k, v in ipairs(graytab) do
        -- Нашли соответствие
        if v == graypos then
            -- Запоминаем ключ
            realpos = k
        end
    end
    print('Gray = '..graypos..' and Real = '..realpos)

    end
    Итого:
    Код (Lua):
    do
    local pins = {4,5,6,7}
    for i = 1, #pins do gpio.mode(pins[i], gpio.INPUT) end
    local graytab = {0, 1, 3, 2, 6, 7, 4, 12, 13, 15, 14, 10, 11, 9, 8}
    local multtab = {1,2,4,8}
    local graypos, realpos = 0, 0
    for i=1, 4 do graypos =  graypos + (gpio.read(pins[i]) * multtab[i]) end
    for k, v in ipairs(graytab) do
        if v == graypos then realpos = k end
    end
    print('Gray = '..graypos..' and Real = '..realpos)
    end
     
    Последнее редактирование: 26 сен 2019
  16. swc

    swc Гик

    Дался Вам тот код Грея. Используйте способ управления телескопом. Берете китайские настенные/настольные часы, на стрелки приклеиваете магниты, под деления часов приклеиваете герконы.
    Будете знать угол поворота (и устранять отклонения) с точностью до 5 угловых минут. Хотя на практике достаточно и часа.
    То есть, управление по азимуту решается легко.
    По углу места - управляете по таблице, в которой прописаны угловые координаты солнца в конкретный час в конкретный день для данной широты.
    Плюс - точная подстройка по наибольшей эффективности для данной освещенности.
    Еще одно извращение - удаляете стрелки и на часовую ось приклеиваете энкодер от струйного принтера с оптопарой. Вместе с регулятором получите следящую систему с погрешностью в несколько угловых секунд.
     
    ИгорьК нравится это.
  17. Nikomas

    Nikomas Нерд

    с теми же условиями отлично справляется и код оптический диск энкодера. ИК светодиоды не прихотливы к погодным условиям. ИК приемники должны работать вплоть до –25С...+85С. Есть опаска что конденсат на ИК-приемниках может помешать позиционированию. Но надо в контролер зашить возможность выдавать ошибку если не сработает ни один приемник.

    Спасибо большое. Есть уже от чего отталкиваться. А если мне понадобятся, например, 10-15 ног для входов оптопар и кнопок, есть ли какие-нибудь расширители для ESP8266 как для Arduino?
     
  18. ИгорьК

    ИгорьК Гуру

    Любые расширители предназначены для работы с МК. Вопрос лишь в умении их применять. Лучше подобрать что-то с шиной i2c. Я не делал ничего подобного, поэтому точно не скажу.
    Можно подобрать что-то на JavaScript - у Espruino есть платы с оченьмногоног.
     
  19. Nikomas

    Nikomas Нерд



    Надо заказывать ибо портов реально маловато.
     
  20. alp69

    alp69 Форумчанин

    Название видео:
    Все глаза проглядел. Но в каком месте там Lua - так и не понял. Правда смотрел без звука. Что я пропустил?:confused: