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

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

  1. ИгорьК

    ИгорьК Победитель модулей

    Водная часть.
    Зачем это нужно - тратить время и напрягать мозги?
    Вы, конечно, уже знаете как программировать Ардуино на его ардуиноЯзыке. Это круто и на это положено немало сил.
    Теперь вопрос - вы понимаете код что написал один из участников этого форума? Даже с подсказкой - этот код для того, чтобы независимо мигать двумя лампочками с разной частотой:

    code002.png
    Если вам здесь все ясно - тратить время на тему не стоит. Уровень вашей подготовки, как Си-умельца, вполне достаточен и вы сможете управлять ESP-8266 через Ардуино IDE.

    Если же вы самодельщик, как я, и написание кода на Си для вас и не работа и не хобби, а средство оживить какое-то домашнее устройство IoT, то, убежден, Lua вам необходим.

    Lua от NodeMCU обладает рядом свойств, которые делают его предпочтительнее C++ для написания небольших (да и больших тоже) программ для автоматизации элементов дома, поскольку ESP-8266 не является контроллером общего назначения.

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

    Вторая особенность ситуации с ESP-8266 на Lua в том, что поняв как это работает, вы сможете программировать и семейство плат Espruino, в том числе Iskra JS - платы на порядок мощнее чем обычная Ардуино.

    Вот, вкратце, две причины, по которым стоит уделить время освоению NodeMCU:
    • событийное программирование;
    • асинхронный код.
    Вещи, для освоения которых на Ардуино Си надо очень много учиться - здесь это делается гораздо проще.

    Шаг первый:
    (код здесь)

    Вот ссылка - там три урока. Изучите и возвращайтесь с заряженной платой: http://www.emc-problem.net/проекты/...-подключить-отладочную-плату-nodemcu-esp8266/

    Шаг второй.

    ===================== Оглавление темы====================
    Шаг первый - здесь. Заряжаем ESP-8266, азы ESPlorer
    Шаг второй - Немного почитать.
    Шаг третий - Blink от Lua.
    Шаг четвертый - асинхронный код - много разных Blink.
    Шаг пятый - глубже: создание функций.
    Шаг шестой - первый модуль.
    Проверка памяти.
    Работа с памятью и модулями.
    Callback + DS18b20.
     
    Последнее редактирование: 11 авг 2017
    obuhanoe, Securbond, b707 и 2 другим нравится это.
  2. koteika

    koteika Гик

    Вот всегда интересно, что заставляет людей писать подобную бретятину:eek::eek::eek:
     
    Пушной звер нравится это.
  3. koteika

    koteika Гик

    Совсем не понятно что хотел сказать. "Или" или "иви" или "изи", в любом случае общение с ним идет тебе не в пользу. Прекращай это, мозг высохнет, станешь овощем деградантом и будешь ни кому не нужен.
     
  4. issaom

    issaom Гик

    Переходите на vbs
    Уникальная среда разработки (нотепад.екзе)
    Никаких объявлений переменных
    Никаких средств отладки
    Нужна только винда
     
  5. issaom

    issaom Гик

    ЖИЛЕЗО + ПИВО = Tхорошо

    ПИВО = Tхорошо - ЖИЛЕЗО

    следовательно чем больше ЖИЛЕЗО тем меньше ПИВО

    Вывод - ЖИЛЕЗО лишнее, совсем!
     
    ИгорьК нравится это.
  6. ИгорьК

    ИгорьК Победитель модулей

    Шаг второй.
    Находим книгу Роберту Иерусалимски "Программирование на языке Lua".
    В этой книге всего 381 страница. А если исключить описание нескольких стандартных библиотек - то 220.
    Вы вообще где-то видели книгу по языку всего из 220 страниц?
    Но и их читать не надо! Потому как объектно-ориентированное программирование в МК вещь не часто встречающаяся. Так что страниц остается 193. Справитесь? Нет?
    Да тоже не важно. Потому как любой язык состоит лишь из двух вещей: управляющих конструкций и всего остального.
    Вот про управляющие конструкции и функции почитать следует - а об остальном поговорим чуть позже.
    Для прочтения - ВСЕГО(!!!) 96 страниц. Остальное подождет.

    Шаг третий.
     
    Последнее редактирование: 3 авг 2017
    obuhanoe нравится это.
  7. Igor68

    Igor68 Гик

  8. ИгорьК

    ИгорьК Победитель модулей

    Не, он для развлечения и душевного отдохновения.
     
    Igor68 нравится это.
  9. Igor68

    Igor68 Гик

    Да... похоже программисты на Си зря написали о отладили этот самый Lua... ну и/или прогрпммисты на Ассемблере.
     
    ИгорьК нравится это.
  10. Igor68

    Igor68 Гик

    Из Юмористической пародии на Л.И.Брежнева (90-е годы по телевидению):
    ...Ну надоже всем нравится... может и мне прочитать

    Почитал сей документ (повторяю почитал, а не прочитал):
    http://yandex.ru/clck/jsredir?from=yandex.ru;search/;web;;&text=&etext=1493._i7z7mO2WJ3u2OczNLOTkiuE6DK59OJXo6jvr-Bt7gLz-XKT3WFwW-u-d_xLD4NDDsY2cOxYex0TBJoYmT3yNpyQIpkCF6-8VTiXxrCLn88VmXa31qX_SRf8gt87_u-hYUapS7LqAIz-xlm8yu3_r7BkyzPPv0YU9R4YkRVq82Y.e71e7fbf1377144125f86c4762f323a35475b1a6&uuid=&state=PEtFfuTeVD5kpHnK9lio9Z86vxGih08mUkvgJJ7jx-F7l28BlYeps94aPwS-Ok65&&cst=AiuY0DBWFJ5Hyx_fyvalFDq1kFMGeLjjUqBGdbB7RRrnpkCu62pN-7BbUD3sOJZUIf5YiuD38NqLO4YAmUjK9Vcyg67Snn7bfN0n0QgX-FOA_F8F_GvYZvymbORF0rkkoFCt8Isd2R_c-OuS1tP123u5fuQIkOM12nKxBLZRX4bCKodZk4Z9xaVotv2dmdb4fLF6yJcKVsc,&data=UlNrNmk5WktYejR0eWJFYk1LdmtxaDdzYVFUamZYcFF1VXA3WVFmTG1vZDNnZjFwcGMzbjJvd1BrRmxDYlhoQkFzaTdDWG9XbzFkVU5hRkVJNzhOYllIZmxxVXl5ODZPYUo5SFhGQUNfdW1heGsydmNCOXdpVng5dGhMZXVfdTQ,&sign=957337982f3fd1efacb150e6ce286f78&keyno=0&b64e=2&ref=orjY4mGPRjk5boDnW0uvlrrd71vZw9kpVBUyA8nmgREuwYRlJ1V0UhSAJc5K6t4YsEirE5dMlvqcIUcmqsrhT6ted_ojjqSrWTgvEtrnhDZd9AFMLAvdNWOpE8yyXU2J5xGFyrQObcW2WKgSHMzn3mn057Xax4zB9A5lh2bOLMBzmkdcA08Vky7eKhSCAYaY9g6b5ZaqvmDGrdWs1ih9gp6GTj8xPsusdAhOiIy0qbGC2hTYGGYMinRQvs1aFMGOX05eNF10bZcYJoxnhy4AU-yx_AxThWAsq60RqiRbhAuAaq5sVU1UbkhRiC1040HTZtsMkRFBDxD_bp1gUDdzFLL-fEUfkZylMZZpZSitC0G1xH9t7ylu5rmxpIWa3YTBwUJn1cBPYrdWaIKYRPFdj9XG2MhId3-W&l10n=ru&cts=1500975885263
    По идее красиво написано, но пока не отказываюсь от привычки C+BASH. И эта связка мне по душе. Сталкивался с тем, что не всегда можно поставить (но это в моём случае для особых устройств) то что хочется. А C+BASH есть практически на всех Linux машинах... даже если C только в режиме кросс компиляции. Прочтите это не относится к малине. Ну например на UC-7112-Lx-Plus (IA240) нет возможности ни Lua ни Python. Но связка C(C++) + Bash реальна. То и использую. То чего не хватает в средствах скриптового Bash добавляю на Си.
     
    Последнее редактирование: 25 июл 2017
  11. Пушной звер

    Пушной звер Оракул

    Вы еще питон предложите учить.
     
  12. ИгорьК

    ИгорьК Победитель модулей

    Шаг третий.
    После прочтения немногих страниц уже можно открыть какую-нибудь дурацкую тему где много буков про Lua и... ничего не понять.
    Все дело в том, что Lua в исполнении NodeMCU - это не Lua, а JavaScript (Node.js) в нотации Lua.
    Ок, услышав эти слова, еще парочка отважных вернулась (сбежала) в Ардуино IDE: там темно и влажно. Но, отдельные остаются.

    Для них. Lua NodeMCU есть:
    • событийно-ориентированный и
    • асинхронный код.
    Сначала это выносит мозг, потому что... Давайте составим простую программу.

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

    Как это будет выглядеть на языке Ардуино?

    Код (C++):
    #define зонт
    #define дождь

    void раскрыли_зонт();

    setup {
        int дождливо = 55;
        unsigned long вечер = 12345678;
    }

    loop {
        if( millis() > вечер) {
            идем гулять;
            if(analogRead(ПинДождя) > дождливо) {
                раскрыли_зонт();
            }
        }
    }

    раскрыли_зонт() {
        //....
    }
    Все привычно и на своих местах. Определили что надо и loop-имся - проверяем условия в цикле.

    На Lua это будет выглядеть иначе: loop там не обнаруживается никогда. Так как же написать/понять программу без loop?

    А мы ее уже написали: наступит (событие) вечер - идем гулять, наступит (событие) дождь - раскроем зонт.

    Все. Именно такова логика событийного и асинхронного кода:
    • определяется событие и готовится реакция на него, после чего ожидается/разрешается событие;
    • вы не думаете (вообще не думаете) о том как согласовать происходящее между собой - асинхронный код сам организует.

    Надо заметить, что начинать простой код на Луа достаточно тяжело, по сравнению с АрдуиноЯзыком - кажется много лишних телодвижений. Однако все меняется местами, когда надо писать что-то сложное: взаимодействие элементов программы организуется само собой, и мозги применяются лишь тогда, когда требуется согласовать доступ разных явлений к одному ресурсу. Но это во всех языках, не так ли?

    Именно как (в какой последовательности) обычный человек мыслит, так и пишется код на Lua.

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

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

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

    Короче, все сделано до вас и за вас. Смотрим сюда - это заранее заготовленные системой реакции на типовые события:

    callback.png

    Как этим пользоваться?

    Начнем блинкать лампочками - разберемся.
    Старт - здесь.
    Рассматриваем таблицу:
    пины.png

    Слева что писать в коде, справа - то что рисуют на картинках в сопроводительной к модулю документации.

    Сделаем такой код:
    Код (Lua):
    do
    pin=1 -- Нога для блинка
    gpio.mode(pin, gpio.OUTPUT) -- Пин будет выходом
    ligth = 1 -- Это будем писать в выход

    function blink()
        -- все просто - пишем в выход
        gpio.write(pin, ligth)
        -- чтобы не плодить светодиодов
        -- дублируем в консоль что получается
        print("Write  to pin "..ligth)
        -- Это то же самое, что тренарный оператор в Сях
        ligth = (ligth == 0) and 1 or 0
    end
    -- вызываем функцию
    blink()
    end
    Пишем код в левом окне Esplorer, весь выделяем, жмем кнопку "Block":
    блинк.png
    После этого ставим курсор на строку blink() и тапаем по кнопке "Line":

    блинк2.png

    Ура! Блинкует!
    ... но вручную. А где событиность и асинхронность? Начнем добавлять. Сначала событие.

    Событие у нас не ахти какое, но все таки - срабатывание таймера. Изготовим оный.
    Таймер - первый в таблице (см. выше) callback(ов), документация по нему здесь.

    Пишем код:
    Код (Lua):
    do
    pin=1 -- Нога для блинка
    gpio.mode(pin, gpio.OUTPUT) -- Пин будет выходом
    ligth = 1 -- Это будем писать в выход

    function blink()
        -- все просто - пишем в выход
        gpio.write(pin, ligth)
        -- чтобы не плодить светодиодов
        -- дублируем в консоль что получается
        print("Writе  to pin "..ligth)
        -- Этото же самое, что тренарный оператор в Сях
        ligth = (ligth == 0) and 1 or 0
    end
    -- вызываем функцию
    blink()

    -- Создаем таймер
    tmrBlink = tmr.create()
    -- Интервал подмигивания
    interval = 5000
    -- как работает таймер, смотрим документацию:
    mode = tmr.ALARM_AUTO
    -- запускаем таймер
    tmrBlink:alarm(interval, mode, blink)
    end
    Выделяем весь код, жмем кнопку "Block" и наблюдаем:
    блинк3.png
    блинк4.png

    Все это можно было записать и по-другому, например не плодить переменные для таймера:
    Код (Text):
    tmrBlink = tmr.create()
    tmrBlink:alarm(5000, tmr.ALARM_AUTO, blink)
    Или еще проще - переменная со ссылкой на таймер нам не нужна - он бухает без надежды на остановку, поэтому:
    Код (Text):
    tmr.create():alarm(5000, tmr.ALARM_AUTO, blink)
    Итак, наш первый блин(к, комом) создан и мы обошлись без loop.
    Кроме того, в режиме реального времени мы правили код и видели его результат без всякой компиляции - это преимущество любого скриптового языка, в Lua все сделано чрезвычайно удобно.

    Мы узнали что такое callback функция. Это функция, которая передается другой функции для исполнения. Обычно это имеет смысл тогда, когда в асинхронном коде нужно организовать цепочку событий: сначала происходит одно, и по результатам его нужно сделать что-то.

    В нашем простом случае с таймером это не слишком очевидно, но если вместо таймера - запрос к веб-странице, тогда все становится на место: сначала получили данные (никто не знает сколько времени на это потребуется), а потом их обработали функцией.

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

    P.S. Все что мы сделали, можно записать очень коротко, но я бы убился объяснять в чем суть. Надеюсь, теперь вы сами разберетесь в этом:

    Код (Lua):
    do
    pin=1
    gpio.mode(pin, gpio.OUTPUT)
    ligth = 1
    tmr.create():alarm(5000, tmr.ALARM_AUTO, function()
        gpio.write(pin, ligth)
        print("Writе  to pin "..ligth)
        ligth = (ligth == 0) and 1 or 0
    end)
    end
    Кстати, как вам без ";" - неуютно?
     
    Последнее редактирование: 3 авг 2017
    obuhanoe и mcureenab нравится это.
  13. ИгорьК

    ИгорьК Победитель модулей

    Шаг четвертый.
    Пора мигать несколькими лампочками.
    Вот здесь то и начинается асинхронность, а мы работаем копипастой и не напрягаем голову:
    Код (Lua):
    do
    pin1=1
    pin2=2
    gpio.mode(pin1, gpio.OUTPUT)
    gpio.mode(pin2, gpio.OUTPUT)
    ligth1 = 1
    ligth2 = 1

    tmr.create():alarm(5000, tmr.ALARM_AUTO, function()
        gpio.write(pin1, ligth1)
        print("Writе  to pin1 "..ligth1)
        ligth1 = (ligth1 == 0) and 1 or 0
    end)

    tmr.create():alarm(3000, tmr.ALARM_AUTO, function()
        gpio.write(pin2, ligth2)
        print("Writе  to pin2 "..ligth2)
        ligth2 = (ligth2 == 0) and 1 or 0
    end)
    end
    Все понятно, одна лампочка мигает через пять секунд, другая - через три:
    блинк5.png

    Вроде бы все нормально, но копипаста - не наш способ.
    Вот что здесь происходит? Много похожих буков. А если надо еще лампочек добавить?

    В Луа есть интересная вещь: функция может не только получать функцию для исполнения, но и сама создавать и возвращать функцию, которую будет исполнять кто-то другой.

    Напишем и выполним код A:
    Код (Lua):
    do
    function makeblink(pin)
        gpio.mode(pin, gpio.OUTPUT)
        local ligth = 1
        return function()
            gpio.write(pin, ligth)
            print("Writе  to "..pin.." "..ligth)
            ligth = (ligth == 0) and 1 or 0
        end
    end

    blink1 = makeblink(1)
    blink2 = makeblink(2)

    tmr.create():alarm(1000, tmr.ALARM_AUTO, blink1)
    tmr.create():alarm(3000, tmr.ALARM_AUTO, blink2)
    end
    А потом код В:
    Код (Lua):
    do
    pin1 = 1
    int1 = 1000

    pin2 = 2
    int2 = 3000

    function makeblink(pin)
        gpio.mode(pin, gpio.OUTPUT)
        local ligth = 1
        return function()
            gpio.write(pin, ligth)
            print("Writе  to "..pin.." "..ligth)
            ligth = (ligth == 0) and 1 or 0
        end
    end

    function maketimer(interval, call)
        tmr.create():alarm(interval, tmr.ALARM_AUTO, call)
    end

    maketimer(int1, makeblink(pin1))
    maketimer(int2, makeblink(pin2))
    end
     
    И в заключение код С:
    Код (Lua):
    do
    pin1 = 1
    int1 = 1000

    pin2 = 2
    int2 = 3000

    function makeblinkandtimer(pin, interval)
        gpio.mode(pin, gpio.OUTPUT)
        local ligth = 1
        function blink()
            gpio.write(pin, ligth)
            print("Writе  to "..pin.." "..ligth)
            ligth = (ligth == 0) and 1 or 0
        end
        function maketimer()
            tmr.create():alarm(interval, tmr.ALARM_AUTO, blink)
        end
        return maketimer()
    end

    makeblinkandtimer(pin1, int1)
    makeblinkandtimer(pin2, int2)
    end
    И начнем разбираться с содеянным...

    Код (Lua):
    -- Фрагмент Кода А

    function makeblink(pin)
        -- получаем номер пина и устанавливаем выход
        gpio.mode(pin, gpio.OUTPUT)
        -- local - переменная ниже будет видна только в пределах
        -- данной функции
        -- однако она а) будет сохранена и б) дудет видна
        -- для той функции, которая ее вызывает
        local ligth = 1
        -- возвращается целая функция
        -- и эта функция будет видеть переменную "light"
        -- всегда.
        -- Это явление называется замыканием
        -- или "upvalue"
        return function()
            gpio.write(pin, ligth)
            print("Writе  to "..pin.." "..ligth)
            ligth = (ligth == 0) and 1 or 0
        end
    end

    -- переменная blink1 теперь ссылается на
    -- функцию, которая оперирует миганием
    -- первой ноги
    blink1 = makeblink(1)

    -- дальше мы уже разбирали
    Код (Lua):
    -- Фрагмент Кода В

    -- Эта функция принимает на вход время и указатель на сallback функцию
    function maketimer(interval, call)
        -- Создает таймер, заряжает его временем и callback и запускает
        tmr.create():alarm(interval, tmr.ALARM_AUTO, call)
    end
    С Кодом С разбираетесь сами - принцип везде один. Код внутри функции makeblinkandtimer создает функцию blink, создает таймер, скармливает ему blink и таймер начинает отсчет.

    Разобрались? Пора сделать следующий шаг.
     
    Последнее редактирование: 3 авг 2017
    obuhanoe и mcureenab нравится это.
  14. ИгорьК

    ИгорьК Победитель модулей

    Шаг пятый.
    Код (Lua):
    pin1 = 1
    int1 = 1000

    pin2 = 2
    int2 = 3000
    ---
    makeblinkandtimer(pin1, int1)
    makeblinkandtimer(pin2, int2)
    Эта часть Кода С (из предыдущего поста) выглядит напряжно. Попробуем исправить ситуацию.

    Создадим таблицу.
    В эту таблицу будем вносить, в свою очередь, другие таблицы.

    Они будут содержать пары: номер пина и интервал для блинка.

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

    Код (Lua):
    do
    pinsintervals = {
        {1, 1000},
        {2, 3000}
    }

    function makeblinkandtimer(pin, interval)
        gpio.mode(pin, gpio.OUTPUT)
        local ligth = 1
        function blink()
            gpio.write(pin, ligth)
            print("Writе  to "..pin.." "..ligth)
            ligth = (ligth == 0) and 1 or 0
        end
        function maketimer()
            tmr.create():alarm(interval, tmr.ALARM_AUTO, blink)
        end
        return maketimer()
    end

    for _, v in pairs(pinsintervals) do
        makeblinkandtimer(v[1], v[2])
    end
    end
    Вы увидели значок "_" - подчеркивания. В Луа так пишут, когда функция обязательно возвращает значение, но оно нам для жизни не нужно - интерпретатор не резервирует переменную для возвращаемого значения.

    in pairs() возвращает два значения и первое нам не нужно.

    Полагаю, увидев этот код ранее, вы бы не смогли понять его логику, теперь, надеюсь, Луа покажется вам не таким страшным.

    Что можно сделать с нашей задачей еще?
    Следующий шаг...
     
    Последнее редактирование: 3 авг 2017
    obuhanoe и mcureenab нравится это.
  15. ИгорьК

    ИгорьК Победитель модулей

    Шаг шестой.
    Упакуем все в модуль и положим на полку - мало ли когда придется блинкать.
    Да-да, создадим библиотеку.

    Вот код с названием blinkmod.lua
    Код (Lua):
    do
    local M = {}
    M.pinsintervals = {}

    function M.makeblinkandtimer(pin, interval)
        gpio.mode(pin, gpio.OUTPUT)
        local ligth = 1
        local function blink()
            gpio.write(pin, ligth)
            print("Writе  to "..pin.." "..ligth)
            ligth = (ligth == 0) and 1 or 0
        end
        local function maketimer()
            tmr.create():alarm(interval, tmr.ALARM_AUTO, blink)
        end
        return maketimer()
    end

    function M.make(t)
        M.pinsintervals = t
        for _, v in pairs(M.pinsintervals) do
            M.makeblinkandtimer(v[1], v[2])
        end
    end
    return M
    end
    Сохраним его в памяти модуля.
    Код создает таблицу М и в ее поля записывает несколько объектов.
    M.pinsintervals - пустая таблица для приема таблицы с ногами и временем (На самом деле это не совсем точно, но при желании разберетесь в чем тут подвох.).
    M.makeblinkandtimer - функция уже нам знакомая.
    M.make - принимает таблицу ноги/время и формирует на нее ссылку в поле M.pinsintervals, после чего начиняет таймеры ногами и временем.

    Работаем с модулем так:
    Код (Lua):
    do
    pinsintervals = {
        {1, 1000},
        {2, 3000}
    }
    bl = require('blinkmod')
    bl.make(pinsintervals)
    end
    блинк7.png
    блинк8.png

    Продолжение.
     
    Последнее редактирование: 11 авг 2017
    mcureenab нравится это.
  16. rkit

    rkit Гуру

    Ну потроллюсь, пожалуй
    Асинхронность. С лупами. Без уродливой каши из продолжений.
    Код (C++):
    #include <Arduino_FreeRTOS.h>
    void loop() {}

    struct BlinkerParams {
      uint16_t durationHigh;
      uint16_t durationLow;
      uint8_t pin;
    };

    void blinker(void *pvParameters) {
      auto params = *(BlinkerParams*)pvParameters;
      pinMode(params.pin, OUTPUT);
      while (1) {
        digitalWrite(params.pin, HIGH);
        vTaskDelay(params.durationHigh / portTICK_PERIOD_MS);
        digitalWrite(params.pin, LOW);
        vTaskDelay(params.durationLow / portTICK_PERIOD_MS);
      }
    }

    void setup() {
      xTaskCreate(blinker, "blinker1", 64, new BlinkerParams{100, 200, 13}, 8, NULL);
      xTaskCreate(blinker, "blinker2", 64, new BlinkerParams{1000, 500, 12}, 8, NULL);
    }
     
     
    SergeiL и ИгорьК нравится это.
  17. ИгорьК

    ИгорьК Победитель модулей

    Спасибо, rkit, за помощь! Ты настоящий Друг! Более крутого троллинга Сей трудно представить!
     
    Последнее редактирование: 27 июл 2017
  18. rkit

    rkit Гуру

    Не понял, каким образом это троллит си.
    Заменить auto на BlinkerParams, и будет чистый 100% работоспособный си.
     
    ИгорьК нравится это.
  19. ИгорьК

    ИгорьК Победитель модулей

    rkit, не теряйте чувства юмора!
    95% читателей не поняли что Вы написали - это и есть чистый троллинг :)

    Ну и напомню, что с использованием библиотеки (не так ли?) мой код выглядит всего лишь как:
    Код (Lua):
    do
    pinsintervals = {
        {1, 1000},
        {2, 3000}
    }
    bl = require('blinkmod')
    bl.make(pinsintervals)
    end
     
  20. SergeiL

    SergeiL Гик

    Ну, какова цена, такова и расплата! :)

    Количество строк исходника, порой не показатель оптимальности ПО.
    Вопрос, в какое количество инструкций процессора они преобразуются, и за какое время выполняются.
    Опять же: латентность, джиттер...

    Учитываем компилятор / интерпретатор, приоритетность в асинхронных процессах.

    Задачи-то бывают разные.

    Я понимаю, что помигать светодиодом – задача тривиальная.

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

    Почему такая категоричность-то ???

    Точка с запятой утомляет? Еще недавно Вы сами комментарии из программы на LUA удаляли, чтобы места в памяти хватило.

    А объявление переменных позволяет выявить ошибки в названиях переменных, еще на этапе компиляции, а не мучиться с отладкой, используя в программе две совершенно разные переменные, отличающиеся ошибкой, в одой букве.


    Вы прекрасно объясняете прелести LUA, но каждый, наверное, сам должен определиться, что ему больше подходит.