Таймеры и многозадачность на Ардуино

    image

    Сегодня мы поговорим о такой актуальной теме, как таймеры и организация многозадачности на Arduino. Поводом для написания этой статьи послужили лекции Олега Артамонова @olartamonov для студентов МИРЭА в рамках IoT Академии Samsung, а точнее, высказывание Олега, цитата (2-я лекция, 1:13:08):
    «Есть, например, задачи на которых можно сломать большинство ардуинщиков, особенно начинающих, попросите их помигать пятью разными светодиодами с разной частотой и периодом и так, чтобы ещё период можно было индивидуально для каждого светодиода изменять...»

    Судя по высказываниям Олега, у него весьма превратное представление об Arduino вообще и об «ардуинщиках» в частности. Мигание пятью светодиодами в означенных им режимах это абсолютно тривиальная задача для Arduino, а для Arduino Mega Server это вообще не задача, а сущее недоразумение — его штатными средствами организуется многозадачность, которая легко управляет сотнями различных сущностей (светодиодов, сервоприводов, шаговых моторов и т. д.) в реальном времени.

    Давайте вместе разберёмся как организовать многозадачность на Arduino, а заодно поможем студентам МИРЭА избавится от навязанных им стереотипов восприятия по отношению к социо-культурному и технологическому феномену нашего времени под названием Arduino.

    Лекции Олега Артамонова


    Нужно отдать должное, сами лекции Олега хороши — в них даётся много полезной и хорошо структурированной информации о микроконтроллерах и я бы рекомендовал всем заинтересованным в этом вопросе с ними ознакомиться. Единственным недостатком этих лекций мне показался неприкрытый техно-снобизм в отношении Arduino, которая выступает в них в роли «мальчика для битья».

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

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

    Не будем далеко ходить за примерами. Вот проект Зимнего сада («Умной теплицы») в котором в реальном времени в многозадачном режиме работают следующие сущности:

    image

    Топология распределённого nRF24 контроллера с огромным числом подключённого и работающего в реальном времени оборудования. Пользователь имеет дело только с «базой», работа nRF24 партнёра полностью прозрачна для него. И, да, это Arduino.

    На «базе»:

    — 7 сервоприводов
    — 9 шаговых моторов
    — 6 реле
    — 3 датчика влажности почвы
    — 2 датчика освещённости
    — Датчик уровня воды
    — Датчик влажности и температуры воздуха

    На nRF24 удалённой части:

    — 12 датчиков влажности почвы
    — 12 реле
    — 3 шаговых мотора
    — 2 датчика освещённости
    — Датчик уровня воды

    Кроме этого, в реальном времени функционирует собственно сама nRF24 связь между двумя распределёнными частями системы и Ethernet интерфейс сервера и серверный движок, обеспечивающий веб-интерфейс пользователя системы.

    Итого, в реальном времени, в многозадачном режиме на 8-битной Меге функционирует как минимум 60 сущностей (и это не считая множества сервисов самой операционной системы AMS, с ними число сущностей приблизится к сотне). Что очевидным образом никак не согласуется с высказыванием о том, что «на Arduino невозможна настоящая многозадачность и мигать даже пятью светодиодами на ней проблематично».

    Пара слов в защиту Arduino


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

    Я много раз говорил и ещё раз повторю, что Arduino в своей софтверной составляющей это, по сути, просто один из возможных уровней абстракции (как и любой другой) со своими достоинствами и недостатками. И пользователю нет абсолютно никакой разницы, что «крутится» внутри его маленького кусочка кремния — «чистая» Arduino, RTOS, RIOT OS, AMS или какая-то другая математическая абстракция представления и управления железными ресурсами контроллера.

    Пользователю важно решение его проблем — чтобы контроллер поливал растения, включал свет, управлял шторами и т. д. И основная проблема не в инструментах, используемых в разработке, а в умении ими пользоваться и, банально, в воображении и инженерном видинии самого разработчика.

    Как это работает?


    Сама по себе многозадачность на микроконтроллерах может быть организована разными способами, в данном случае речь пойдёт о самом простом — процессы по очереди получают управление и добровольно отдают его после использования своего кванта времени. Этот способ, конечно, не лишён очевидных недостатков, но, как говорится, практика — критерий истины и он прекрасно зарекомендовал себя в реальных условиях: он используется как в стандартных дистрибутивах Arduino Mega Server, так и во множестве проектов на AMS Pro. И эти системы работают в режиме 24/7 и имеют подтверждённые аптаймы во многие месяцы беспроблемной работы.

    image

    Это индикация около сотни сущностей распределённой nRF24 системы, управляемых независимо друг от друга в реальном времени. Обратите внимание на два последних индикатора «CPU» — при этом даже на 8-битной Меге загрузка процессора ровна нулю (то есть система полностью свободна).

    Немного о таймерах


    Для организации управления сложными системами недостаточно просто передавать по очереди управление между процессами и наряду с автоматической передачей управления в AMS используются различные виды таймеров: циклические, циклические с заданным количеством повторений (пакетные), одиночные, рандомные, смешанные и т. д. Всё это организовано нативными средствами Arduino и не использует прерывания или прямое программирование таймеров микроконтроллера (но прерывания, конечно же, использоваться системой «по их прямому назначению»).

    Что опять же вступает в прямое противоречие с высказыванием «На 3 светодиода железных таймеров хватит, с дальше у ардуинщиков начнутся проблемы». Не начнутся. Нам доступны любые типы таймеров в любом количестве. И, при желании, мы можем наделать себе ещё сколько угодно новых и сколь угодно экзотических.

    Основной кейс


    Основной кейс при данном типе организации многозадачности — это создавать так называемый «неблокирующий» код, то есть код, который не использует функцию delay(), которая просто приостанавливает выполнение программы на заданное время.

    Реальное время


    Описываемый способ реализации многозадачности можно охарактеризовать как «soft-realtime», типовое время задержки в системе составляет 10 мс (но пиковые задержки могут быть значительно больше и не нормируются). Это накладывает известные ограничения на спектр применения данного решения, но для большинства «бытовых» задач (и не только) он прекрасно подходит, см. пример выше.

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

    Это общее теоретическое описание работы многозадачности в Arduino вообще и в AMS в частности, теперь перейдём к рассмотрению практических примеров.

    Циклические таймеры



    image

    Рассмотрим реализацию самых простых циклических таймеров. Это таймеры (в терминологии AMS «cycles»), которые включаются через определённые, заранее заданные промежутки времени и используются для активации циклических процессов.

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

    Использовать циклические таймеры очень просто: достаточно поместить код, который нужно периодически выполнять, между скобками оператора if. Если нужно использовать другой интервал срабатывания, то просто используем нужную переменную вместо cycle1s. Различных циклов можно сделать сколько угодно — система даже на 8-битной Меге без проблем потянет обслуживание буквально сотен таких таймеров (только, естественно, нужно не забывать чтобы вызываемый код не был блокирующим).

      if (cycle1s) {
        // Код, который необходимо выполнять, например, каждую секунду
      }
    

    Теперь организация работы таймеров. Определение управляющих переменных в главном файле:

    // Cycles
    bool cycle1s  = false;
    bool cycle5s  = false;
    bool cycle20s = false;
    bool cycle30s = false;
    bool cycle1m  = false;
    bool cycle3m  = false;
    bool cycle5m  = false;
    

    Набор интервалов может быть расширен любыми нужными значениями от десятков миллисекунд до суток и более.

    Модуль «Timers»:

    /*
      Module Timers
      part of Arduino Mega Server project
    */
    
    // Cycles
    unsigned long timeSec;
    unsigned long timer1s;
    unsigned long timer5s;
    unsigned long timer20s;
    unsigned long timer30s;
    unsigned long timer1m;
    unsigned long timer3m;
    unsigned long timer5m;
    
    void timersInit() {
      unsigned long uptimeSec = millis() / 1000;
      timeSec  = uptimeSec;
      timer1s  = uptimeSec;  
      timer5s  = uptimeSec; 
      timer20s = uptimeSec;
      timer30s = uptimeSec;
      timer1m  = uptimeSec;
      timer3m  = uptimeSec;
      timer5m  = uptimeSec;
    }
    
    void timersWorks() {
      timeSec = millis() / 1000;
        if (timeSec - timer1s  >=  1)  {
                                        timer1s  = timeSec; cycle1s  = true;
        if (timeSec - timer5s  >=  5)  {timer5s  = timeSec; cycle5s  = true;}
        if (timeSec - timer20s >= 20)  {timer20s = timeSec; cycle20s = true;}
        if (timeSec - timer30s >= 30)  {timer30s = timeSec; cycle30s = true;}
        if (timeSec - timer1m  >= 60)  {timer1m  = timeSec; cycle1m  = true;}
        if (timeSec - timer3m  >= 180) {timer3m  = timeSec; cycle3m  = true;}
        if (timeSec - timer5m  >= 300) {timer5m  = timeSec; cycle5m  = true;}
      }
    }
    
    void eraseCycles() {
      cycle1s  = false;
      cycle5s  = false;
      cycle20s = false;
      cycle30s = false;
      cycle1m  = false;
      cycle3m  = false;
      cycle5m  = false;
    }
    

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

    void loop() {
      timersWorks();
    
      // Код системных процессов
    
      eraseCycles();
    }
    

    Циклические таймеры в виде объектной библиотеки


    Теперь рассмотрим организацию тех же таймеров, но в более правильном объектном виде, оформленном в готовую библиотеку. Назовём её myCycle.

    Заголовочный файл в котором представлены объявления класса, методов и некоторых предопределённых констант:

    /*
      myCycle Library
      part of Arduino Mega Server project
    */
    
    #ifndef _MYCYCLE_H
    #define _MYCYCLE_H
    
    #define MS_500       500
    #define MS_01S      1000
    #define MS_02S      2000
    #define MS_05S      5000
    #define MS_10S     10000
    #define MS_13S     13000
    #define MS_17S     17000
    #define MS_20S     20000
    #define MS_30S     30000
    #define MS_01M     60000
    #define MS_03M    180000
    #define MS_05M    300000
    #define MS_01H   3600000
    #define MS_06H  21600000
    #define MS_12H  43200000
    #define MS_01D  86400000
    
    class myCycle {
      private:
        bool          _go;
        bool          _active;
        unsigned long _start;
        unsigned long _period;
      
      public:
        myCycle(unsigned long per, bool act);
        void reInit(unsigned long per, bool act);
        void reStart();
        bool check();
        bool go();
        void clear();
        
        // active
        bool active();
        void setActive(bool act);
        // period
        unsigned long period();
        void setPeriod(unsigned long per);
    }; // class myCycle
    
    #endif // _MYCYCLE_H
    

    И файл реализации в котором находится код библиотеки:

    /*
      myCycle Library
      part of Arduino Mega Server project
    */
    
    #include "myCycle.h"
    #include <Arduino.h>
    
    myCycle::myCycle(unsigned long per, bool act) {
      _go     = false;
      _active = act;
      _period = per;
      _start  = millis();
    }
    
    // Methods
    
    void myCycle::reInit(unsigned long per, bool act) {
      _go     = false;
      _active = act;
      _period = per;
      _start  = millis();
    }
    
    void myCycle::reStart() {
      _start = millis();
    }
    
    bool myCycle::check() {
      if (millis() - _start >= _period) {
        _start = millis();
        if (_active) {
          _go = true;
        }
      }
      return _go;
    }
    
    bool myCycle::go() {
      return _go;
    }
    
    void myCycle::clear() {
      _go = false;
    }
    
    // Active
    
    bool myCycle::active() {
      return _active;
    }
    
    void myCycle::setActive(bool act) {
      _active = act;
    }
    
    // Period
    
    unsigned long myCycle::period() {
      return _period;
    }
    
    void myCycle::setPeriod(unsigned long per) {
      _period = per;
    }
    

    Использование этого варианта тоже просто и имеет некоторые преимущества перед «функциональным» вариантом: тут можно очень легко объявлять таймеры с нужными интервалами и не нужно заранее создавать множество таймеров «на всякий случай».

    В главном файле:

    Подключаем библиотеку:

    #include "myCycle.h"
    

    Создаём объекты:

    // Cycles
    myCycle cycle500(MS_500, true);
    myCycle cycle2s(MS_02S, true);
    myCycle cycle5s(MS_05S, true);
    

    Добавляем функции обслуживания работы таймеров:

    void timersWorks() {
      cycle500.check();
      cycle2s.check();
      cycle5s.check();
    }
    
    void eraseCycles() {
      cycle500.clear();
      cycle2s.clear();
      cycle5s.clear();
    }
    

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

    void loop() {
      timersWorks();
    
      // Код системных процессов
    
      if (cycle5s.go()) {
        Serial.println(F("cycle5s!"));
      }
    
      eraseCycles();
    }
    

    Библиотека имеет несколько более широкий функционал, чем код, приведённый в первом варианте. Например, она содержит методы активации/дезактивации таймеров, установки и получения текущего значения, рестарта и реинициализации таймеров, что ещё больше расширяет возможности использования их в практических задачах.

    Другие виды таймеров на Arduino



    image

    Чтобы не загромождать статью, я не буду здесь приводить код и разбирать работу всех возможных типов таймеров — все они строятся по одним и тем же принципам. Если эта тема будет интересна, то можно будет написать отдельную статью об этом. Здесь я только дам общее описание таймеров, которые используются в AMS и прекрасно себя зарекомендовали на практике.

    Циклические с заданным количеством повторений (пакетные)


    Это таймеры, которые срабатывают заранее определённое количество раз. Например, вам нужно делать 3 попытки отправки сообщения по беспроводному каналу nRF24. Таймер активируется только 3 раза и соответственное количество раз делаются попытки отправки сообщений.

    Тут же возможны различные расширения функциональности типа активации/дезактивации таймера в зависимости от определённых условий и т. п.

    Одиночные


    Это различные вариации на тему «автозагрузки», когда какое-либо действие выполняется через определённый интервал времени после старта контроллера или какого-либо события.

    Рандомные


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

    Например, у вас есть два распределённых контроллера, которые связаны друг с другом по беспроводному каналу. Если одна система будет посылать свои сообщения другой, согласуясь со срабатыванием обычного таймера, например, раз в 20 секунд, то эти сообщения будут приходить на вторую систему в строго определённой «фазе», которая может попадать в «проблемный» интервал работы цикла второго контроллера, в результате его работа может быть нестабильной. Если в этом случае использовать рандомный таймер, то он «размажет» по времени моменты прихода сообщений от первого контроллера и проблемы удастся избежать.

    Это только абстрактный пример для понимания того, что собой представляют рандомные таймеры. И вы можете ознакомиться с их реализацией — стандартный дистрибутив Arduino Mega Server содержит код такого таймера.

    Смешанные


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

    Нет практически никаких ограничений на количество таймеров и логику работы — их может быть сотни, даже на 8-битном контроллере.

    Межпроцессное взаимодействие


    Межпроцессное взаимодействие, семафоры, почтовые ящики и прочие атрибуты многозадачных систем организуются на Arduino тоже без каких-либо проблем — их можно организовать любым удобным для вас способом — начиная от передачи параметров через статические переменные и заканчивая упаковкой логики в любые классы и объекты, тут нет абсолютно никаких ограничений и проблем.

    Подробное описание межпроцессного взаимодействия выходит за рамки этой статьи, но вы можете скачать себе дистрибутив Arduino Mega Server для любой платформы и самостоятельно ознакомиться с его устройством и работой.

    Заключение


    В общем, можно сказать, что средствами Arduino можно создать любые виды таймеров, запускать любое их количество и использовать любое их сочетание, другими словами, Arduino может удовлетворить любой каприз по таймерному (псевдо) многозадачному управлению сложными микроконтроллерными системами.

    И это не должно быть секретом для студентов МИРЭА, как будущих инженеров микропроцессорных систем, ведь эти принципы можно применять на любой платформе.

    P.S.
    Недавно вышла новая, 0.17 версия Arduino Mega Server для Arduino Mega, Due, 101 и M0, которую вы можете скачать на официальной странице загрузки. Код таймеров, описанный в этой статье, взят из этих дистрибутивов.
    Поделиться публикацией
    Комментарии 291
      +5
      у него весьма превратное представление об Arduino вообще и об «ардуинщиках» в частности

      ну


      Мигание пятью светодиодами
      организуется многозадачность

      После такого — естественно оно будет превратным.

        +2
        Да выкиньте этот весь ардуино-софт. У Атмела простейшая периферия, на каждое устройство из которой приходится несколько управляющих регистров. Их функции расписаны в миллионе русскоязычных руководств вместе со скетчами примерами кода хоть на ассемблере, хоть на С. За один день прочитав руководство по Атмелу, можно лепить любые программы без ардуино-костылей…
          +5
          Ок, а что делать многомиллионной армии «обычных людей» для которых даже уровень Ардуино с трудом постижим?
            +6
            Тем нормально. Тем Ардуино софт.
            Но не
            для студентов МИРЭА, как будущих инженеров микропроцессорных систем
              +3
              В статье речь идёт не о том, что студентов МИРЭА нужно учить Ардуино, а о том, что на Ардуино, на самом деле, можно строить развитые многозадачные системы.
                +1
                Не стоит так делать.
                Пример xakep.ru/2018/04/13/hack-aigo-hdd
                Там человек квалификации совершенно космической (действительно крутой дядя), но додумался для снятия дампа взять ардуино-код.

                И (процитирую статью пару раз)
                3. Подождать заданный промежуток времени, учитывая следующие подводные камни:

                я убил уйму времени, пока не узнал, что, оказывается,
                работает корректно только с задержками, не превышающими 16 383 мкс;
                • delayMicroseconds
                и затем снова убил столько же времени, пока не обнаружил, что delayMicroseconds,
                если ей на вход передать 0, работает совершенно
                неправильно!


                Этот код выполняется по десять раз за одну микросекунду. 0xF1 сюда включен, поскольку был единственным регистром, который менялся при вычислении контрольной суммы. Воз можно, это какая‐то временная переменная,
                используемая арифметико‐логическим устройством. Обрати внимание
                на уродливый хак, которым я перезагружаю Arduino, используя picocom, когда
                Arduino перестает подавать признаки жизни (понятия не имею почему).


                  0
                  Да, вы правы, на Ардуино есть множество мелких, но неприятных проблем и тем, кто плотно с ней работает с ними приходится сталкиваться и по возможности как-то решать. А по поводу ваших ссылок — спасибо, надо будет чуть позже повнимательнее почитать.
                    0
                    А что, есть микроконтроллеры, в которых вообще нет никаких мелких проблем? Пока не встречал
                      +1
                      Я тоже думаю, что проблемы есть везде, но на Ардуино они особенно неприятные и норовят встретиться в самых неожиданных местах :)
                        +1
                        нигде проблемы не бывают приятными и никогда не встречаются в ожидаемых местах. Ардуино тут ничем не особенная. Бывает такая мутная жесть на других мк, что дурина кажется конфеткой
          +1
          Наконец то у ардуины появился вменяемый вэб интерфейс. Это здорово!
            0
            АМС-у как проекту уже больше двух лет и на протяжении всех этих лет в нём присутствует этот интерфейс. :) Кстати, в стандартной поставке присутствуют также честные интерактивные 3D сцены и т. н. «плиточный» интерфейс а ля Windows 10 для любителей.
              0
              Если чуток копнуть, то окажется что всю красоту рисует d3.js или что-то вроде, а роль ардуины сводится к «отдать пару файлов по http». Что как-бы с одной стороны круто, а с другой — укладывается в сотню строк.
                0
                Большинство красивостей укладывается в сотню строк вне зависимости от платформы. Проблема в том, чтобы написать эту сотню строк не сожрав всю память ардуины.
                  +2
                  В АМС «красивости» грузятся с карты памяти объёмом до 32 ГБ, так что там нет практически никаких ограничений.
                  +1
                  Да, это именно так и есть и даже копать не нужно — это видно невооружённым глазом из исходников и файлов на на карте памяти.
              –1
              Позволю себе выразить сомнение в том, что в 2018 году в коде на С++ все еще допустимо использовать #define для определения простых констант, да еще в заголовочном файле, вместо namespace и const.

              Ну и вместо стражей включения стоит использовать #pragma once, учитывая, что компилятор ее поддерживает, а вопрос переносимости вообще не стоит.
                0
                Вы абсолютно правы — код писался с чисто утилитарной точки зрения, чтобы корректно выполнялись требуемые функции и там огромное поле для улучшений и приведения кода к лучшим практикам.
                  0
                  Ха, к сожалению const не всегда применим, и приходиться городить некрасивые #define
                    0
                    Насколько мне известно, если вам нужна просто константа, то у define только одно преимущество — его существование можно проверить через #ifdef. Ну и передефайнить, если вдруг захотелось.
                    Но тут-то зачем?
                    0
                    А задолго до 2018 года, и даже на C без ++, для целей, как в исходниках в статье, использовался enum
                      0
                      Только в С что enum, что define — одна фигня. Все неявные преобразования происходят молча.
                        0
                        Согласен, но все же лучше использовать вещи по их прямому назначению, а здесь прямо просится enum.
                          0
                          Лично я совершенно механически стриггерился на вот эти дефайны
                          Заголовок спойлера
                          #define MS_500       500
                          #define MS_01S      1000
                          #define MS_02S      2000
                          #define MS_05S      5000
                          #define MS_10S     10000
                          #define MS_13S     13000
                          #define MS_17S     17000
                          #define MS_20S     20000
                          #define MS_30S     30000
                          #define MS_01M     60000
                          #define MS_03M    180000
                          #define MS_05M    300000
                          #define MS_01H   3600000
                          #define MS_06H  21600000
                          #define MS_12H  43200000
                          #define MS_01D  86400000


                          Которые, если немножко подумать, вообще ни к селу ни к городу не нужны ни в каком виде. Ардуино уже поддерживает С++11, в котором есть std::chrono и стандартные литералы для единиц времени.

                          Enum, на мой взгляд, тут все равно не просится, ведь никакого перечисления тут нет, это числа, количества миллисекунд. Не будь неявного приведения типа, этот enum пришлось бы каждый раз кастовать к числу (потому что функция, куда эти константы суют, может принимать любое количество миллисекунд, а не только заранее перечисленные здесь).
                            0
                            Да, именно про эти дефайны я и говорил. А дальше, давайте определимся, мы говорим о C или о C++. Если о C, то, как Вы заметили выше «Только в С что enum, что define — одна фигня. Все неявные преобразования происходят молча», если о C++, то можно написать inline функцию, принимающую этот enum, приводящую его к числу, а затем вызывающую одноименную функцию, принимающую число, чтобы каждый раз при вызове не писать reinterpret_cast<>.
                              0
                              Окей, я бы в любом случае переделал бы API. Если есть std::chrono — то пусть функции принимают std::chrono::milliseconds, если chrono нет, то просто сделать несколько функций (или перегрузок), чтобы они принимали только миллисекунды, секунды и миллисекунды, минуты и т.д.

                              Enum, на мой взгляд, должны использоваться, когда все допустимые значения можно заранее перечислить — это ведь перечислимый тип. Тут же константами сделаны только какие-то заранее определенные величины, которые просто автору понравились, но допустимые значения ими не ограничиваются.
                              И если пользователю захочется задать интервал например, в 4 минуты (для которых константы нет), то ему придется руками писать 4*60*1000, что, на мой взгляд, выглядит плохо и непонятно.
                                0
                                Я тоже бы переделал интерфейс, но оставил бы только enum и определил бы для него базовые мат. операции (+,-, *(unsigned)). При этом все константы бы определял как производные от первого значения этого перечислимого типа, которое в этом случае является базовым квантом времени для данного класса таймеров. Это позволило бы в дальнейшем безболезненно изменить этот квант, естественно, отвязавшись от Ардуиновского millis(). При такой реализации серьезно говорить о точных интервалах в единицы мс вряд ли можно, а определившись со всеми задержками можно было бы при финальной оптимизации установить гораздо более крупный квант времени, тем самым сэкономив ресурсы однокристаллки, которых в эмбединге много не бывает. Возможно даже, в итоге удалось бы перейти от длинных чисел к обычным (не забываем, что у нас 8 разрядная однокристаллка).
                                Но все, что выше, я писал применительно к эмбедингу, если бы писал для ПК, то ориентировался бы на std::chrono.
                                  0
                                  Ваш вариант по-прежнему не отвечает на вопрос, что делать, если пользователю нужно не заранее определенное в enum'е значение, а свое. Умножать на базовое значение, видимо?

                                  Ладно, спор явно пошел о вкусах, но лично мне вызов
                                  myCycle cycle(MS_01*2*60*60*1000, true);
                                  кажется менее понятным, чем
                                  myCycle cycle( 2_h, 0_min, 0_sec, 0_msec, true);


                                  Ну и переопределять операторы для enum, так чтобы выходить за пределы этого самого enum'a по-моему фе.
                                    0
                                    А почему в первом случае не написать 2*MS_01H (именование констант сохранено авторское)? И я бы константу 2 часа, которая ведь что то обозначает, определил в отдельном месте, как пользовательскую, но выраженную через системную (константы, определенные в заголовочнике таймера, пусть считаются системными).
                                    В остальном я бы согласился со всеми Вашими рассуждениями, если бы речь шла не об эмбединге, т.к. считаю, что при финальной оптимизации тик таймера с достаточно большой вероятностью увеличится, хотелось бы при этом ограничиться изменением в одном месте.
                                    0
                                    Это позволило бы в дальнейшем безболезненно изменить этот квант, естественно, отвязавшись от Ардуиновского millis()

                                    Это — совершенно лишняя абстракция. Накладные расходы на неё заметны, а понадобится она скорее всего никогда (точнее, к тому времени вы успеете переписать весь код с нуля несколько раз). Пример нормального решения — функции sleep(), usleep(), nanosleep(), у которых кванты, соответственно, секунда, микросекунда, наносекунда — выбирайте нужное, а если сомневаетесь, то используйте последний так как он заведомо покрывает все варианты. Для измерения интервалов меньше наносекунды всё равно потребуется принципиально другой подход (и, вероятно, полностью другая платформа), поэтому встраивать их теоретическую поддержку опять же незачем.

                                      0
                                      Изначально шло обсуждение не функций задержки, а таймеров, выполняющих некоторые действия по времени без блокирования основного (и единственного) потока при ожидании.
                                        0
                                        Обсуждение выше в общем то не про таймеры, а про то, как представить интервал времени. А уж для чего его использовать — дело десятое. (я, если что, не призывал пользоваться этими функциями для таймеров и даже не знаю, есть ли они в ардуине — это был просто пример из другой области по похожей задаче).
                                        Ну и можете считать что таймер — это асинхронная функция задержки.
                                          0
                                          Для блокирующей задержки в однозадачной системе, действительно, безразлично в каких единицах представлять время, лишь бы обеспечить требуемую точность представления — пока процессор висит в этой функции, он ничего полезного не делает. Для неблокирующих задержек излишне малая единица кванта времени приводит к непроизводительному расходу ресурсов — чаще надо дергать прерывание, может потребоваться большая разрядность операций. Кстати, для блокирующих задержек, в случае, если на время задержки надо экономить потребление — то же.
                                            0
                                            Это потому что вы почему-то приравняли «единицу измерения» и необходимую точность интервала. Если нужно выбирать точность — ставим её вторым аргументом (просто числом, любым желаемым, безо всяких ограничивающих enum-ов), или какой-нить глобальной настройкой. Зашивать её в апи ни к чему. А если она даже зашита в железе — никто не мешает делать задержку в наносекундах с точностью +- 1 мс.
                                              0
                                              Вы не можете установить точность меньше(в смысле — точнее) кванта времени, используемого для отсчета интервала. А этот квант, по возможности, надо делать бОльшим с целью экономии ресурсов. Впрочем, это касается только решений, на основе описанного в статье.
                      +1

                      Чтобы не хотел сказать автор, но данная статья подтверждает слова лектора о том, что для реализации многозадачности нужно быть немного больше, чем простым "ардуинщиком" — по крайней мере знать, что такое таймеры и уметь их применять. Вот если бы вообще без таймеров — вот это был бы уровень для ардуино.

                        –1
                        Честно, не очень понял ваш посыл и в своё оправдание могу сказать только то, что АМС работает корректно на десятке платформ от Меги до ESP32 и скачан с сайта более 20 000 раз.
                          0

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

                            0
                            С этим никто не спорит — технических решений может быть огромное количество. Я, со своей стороны, хотел бы чтобы вы ещё раз посмотрели на схему и описание контроллера из статьи и прикинули бы какой там уровень сложности и какой уровень понимания нужен для того, чтобы это всё работало как часы с типовыми задержками 10 мс — тогда сомнения в том, что автор имеет представление о переполнении таймеров отпадёт сам собой (по крайней мере должен отпасть).
                              0

                              Я ничего не говорю об авторе. Я говорю об ардуинщиках, которые прочтут статью и начнут программировать многозадачность по тому принципу, что вы описали.
                              Насчет уровня сложности и понимания — ну хотя бы необходимо понимание того, что любой код любого таймера должен будет выполняться за время, меньшее, чем период самого меньшего таймера в системе. Иначе вы пропускаете циклы со всеми вытекающими.
                              Конечно, если период самого меньшего таймера сделать в 1с, особых проблем не будет, но вот с 10мс все будет уже не так радостно… printf "Здесь был дядя Вася" на 9600 битах уже не укладывается в этот интервал. А как измерять время выполнения кода, ардуинщики не знают и вы не рассказали...

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

                                При всех его (очевидных) недостатках — это рабочее и прекрасно работающее на практике решение, о чём не нужно забывать при его обсуждении.

                                Ну и конечно все будут только приветствовать статью, где автор представит описание своего варианта решения проблемы, подкреплённое работающим публичным проектом с несколькими десятками тысяч строк кода.
                        +1
                        Я много раз говорил и ещё раз повторю, что Arduino в своей софтверной составляющей это, по сути, просто один из возможных уровней абстракции (как и любой другой) со своими достоинствами и недостатками.
                        Вы уверены, что такой уровень абстракции действительно необходим?
                        Файл eeprom/EEPROM.h из библиотеки Ардуино:
                        class EEPROMClass
                        {
                          public:
                            uint8_t read(int);
                            void write(int, uint8_t);
                        };
                        
                        extern EEPROMClass EEPROM;
                        

                        Файл eeprom/EEPROM.cpp из библиотеки Ардуино:
                        uint8_t EEPROMClass::read(int address)
                        {
                        	return eeprom_read_byte((unsigned char *) address);
                        }
                        
                        void EEPROMClass::write(int address, uint8_t value)
                        {
                        	eeprom_write_byte((unsigned char *) address, value);
                        }
                        
                        EEPROMClass EEPROM;
                        

                        Зачем было нужно вводить этот класс, это же не Java, а C++?
                        А как Вам дерганье дискретным выходом и проверка состоя дискретного входа в виде нижеприведенного кода?
                        Файл wiring_digital.c из библиотеки Ардуино:
                        void digitalWrite(uint8_t pin, uint8_t val)
                        {
                        	uint8_t timer = digitalPinToTimer(pin);
                        	uint8_t bit = digitalPinToBitMask(pin);
                        	uint8_t port = digitalPinToPort(pin);
                        	volatile uint8_t *out;
                        
                        	if (port == NOT_A_PIN) return;
                        
                        	// If the pin that support PWM output, we need to turn it off
                        	// before doing a digital write.
                        	if (timer != NOT_ON_TIMER) turnOffPWM(timer);
                        
                        	out = portOutputRegister(port);
                        
                        	uint8_t oldSREG = SREG;
                        	cli();
                        
                        	if (val == LOW) {
                        		*out &= ~bit;
                        	} else {
                        		*out |= bit;
                        	}
                        
                        	SREG = oldSREG;
                        }
                        
                        int digitalRead(uint8_t pin)
                        {
                        	uint8_t timer = digitalPinToTimer(pin);
                        	uint8_t bit = digitalPinToBitMask(pin);
                        	uint8_t port = digitalPinToPort(pin);
                        
                        	if (port == NOT_A_PIN) return LOW;
                        
                        	// If the pin that support PWM output, we need to turn it off
                        	// before getting a digital reading.
                        	if (timer != NOT_ON_TIMER) turnOffPWM(timer);
                        
                        	if (*portInputRegister(port) & bit) return HIGH;
                        	return LOW;
                        }
                        

                          0
                          Вот, честно, не считал количество строк кода в дистрибутиве АМС, наверное это суммарно не одна сотня тысяч, а уж на аудит десятка библиотек, используемых в проекте, никаких сил не хватит — для этого нужно создавать специальный отдел. И конечно библиотеки содержат не всегда идеальный код — в этом нет никаких сомнений.
                            0
                            Вот, честно, не считал количество строк кода в дистрибутиве АМС, наверное это суммарно не одна сотня тысяч
                            Вот результаты sloccount (файлы *.ino переименованы в *.cpp):
                            ~/tmp/ams_017-1/ams/Arduino$ sloccount .
                            Creating filelist for ams_nrf24_controller
                            Creating filelist for arduino_mega_server
                            Creating filelist for libraries
                            Categorizing files.
                            Finding a working MD5 command....
                            Found a working MD5 command.
                            Computing results.
                            
                            
                            SLOC    Directory       SLOC-by-Language (Sorted)
                            10899   libraries       cpp=8772,ansic=1992,python=118,sh=17
                            3641    arduino_mega_server cpp=3641
                            1116    ams_nrf24_controller cpp=1116
                            
                            
                            Totals grouped by language (dominant language first):
                            cpp:          13529 (86.41%)
                            ansic:         1992 (12.72%)
                            python:         118 (0.75%)
                            sh:              17 (0.11%)
                            
                            
                            
                            
                            Total Physical Source Lines of Code (SLOC)                = 15,656
                            Development Effort Estimate, Person-Years (Person-Months) = 3.59 (43.11)
                             (Basic COCOMO model, Person-Months = 2.4 * (KSLOC**1.05))
                            Schedule Estimate, Years (Months)                         = 0.87 (10.45)
                             (Basic COCOMO model, Months = 2.5 * (person-months**0.38))
                            Estimated Average Number of Developers (Effort/Schedule)  = 4.13
                            Total Estimated Cost to Develop                           = $ 485,352
                             (average salary = $56,286/year, overhead = 2.40).
                            SLOCCount, Copyright (C) 2001-2004 David A. Wheeler
                            SLOCCount is Open Source Software/Free Software, licensed under the GNU GPL.
                            SLOCCount comes with ABSOLUTELY NO WARRANTY, and you are welcome to
                            redistribute it under certain conditions as specified by the GNU GPL license;
                            see the documentation for details.
                            Please credit this data as "generated using David A. Wheeler's 'SLOCCount'."

                            Как видите, сотнями тысяч здесь и не пахнет, а Вашего кода — всего около 5000 эффективных строк.
                            а уж на аудит десятка библиотек, используемых в проекте, никаких сил не хватит — для этого нужно создавать специальный отдел
                            Бросить взгляд на чужие исходники, прежде чем тащить их в свой проект — никак нельзя считать проведением полноценного аудита, но это делать просто необходимо, особенно в эмбединге, где ресурсы железа на вес золота.
                              0
                              Затрудняюсь оценить ваш метод подсчёта и что понимается под «эффективными строками», я имел в виду количество строк кода во всех файлах системы. Но сразу бросается в глаза, что при подсчёте вы проигнорировали (если я правильно понял) весь JavaScript и Processing код, содержащийся в htm и pde файлах (в разных папках).

                              Так делать нельзя — АМС это распределённая система контроллер-браузер и обе части системы равноценны и представляют собой одно целое. Если посчитаете все строки кода в проекте — то все скажут вам спасибо, по крайней мере будем знать сколько их (и желательно считать не «эффективное» значение, а реальное).

                              Что касается библиотек, то в идеальном мире так и нужно сделать, а ещё лучше написать свои собственные библиотеки, но в реальном мире на это банально не хватает ресурсов.
                                0
                                Затрудняюсь оценить ваш метод подсчёта и что понимается под «эффективными строками»
                                Это вовсе не «мой» метод, а довольно распространенный метод подсчета метрик кода sloc. JavaScript и Processing код утилита sloccount не обрабатывает, поэтому они и не учтены.
                                Если посчитаете все строки кода в проекте — то все скажут вам спасибо, по крайней мере будем знать сколько их (и желательно считать не «эффективное» значение, а реальное).
                                Извольте, если Вы считаете, что это имеет смысл:
                                ~/tmp/ams_017-2/ams/Arduino/ams_nrf24_controller$ wc -l *
                                ..............
                                 1637 итого
                                ~/tmp/ams_017-2/ams/Arduino/arduino_mega_server$ wc -l *
                                ......................
                                  5153 итого
                                ~/tmp/ams_017-2/ams/Processing/arduino_serial_commander$ wc -l *
                                ..................................
                                  18304 итого
                                ~/tmp/ams_017-2/sd$ wc -l *
                                ....................................
                                  21842 итого
                                
                                а ещё лучше написать свои собственные библиотеки
                                А вот это не факт, т.к. некоторые вещи, например криптографию, не стоит браться писать, не являясь профессионалом в данной области, а, во вторых, как Вы справедливо подметили — «на это банально не хватает ресурсов»
                                  0
                                  Serge78rus, я ничего не имею против вашего желания подсчитать количество строк в проекте, но если уж это делать, то нельзя игнорировать JavaScript, Processing и CSS код, ведь это (навскидку) две трети кода.
                                    0
                                    Вы первым заговорили о «сотнях тысяч строк», что крайне мало было похоже на правду, это и сподвигло меня загрузить Ваш проект и прогнать его через sloccount. После этого, уже по Вашему пожеланию, я провел подсчет строк во всех файлах проекта, не разбирая типа файлов, но уже с помощью wc, который, не разбирая содержимого, считает все подряд, будь это строка хоть из единственного символа перевода строки.
                                    Считать ли css программным кодом — вопрос дискуссионный. Я, например считаю, что html — это не код, а контент, а css — разметка, вот JavaScript, безусловно, программный код. Но ведь изначально речь шла о программировании микроконтроллера, а html, css и JavaScript исполняются в браузере, поэтому я их и не учитывал.
                                      0
                                      Мне как-то приходила мысль посчитать количество строк кода в проекте, но простого и корректного способа я не нашёл, а вручную всё это пересчитывать я посчитал бессмысленной тратой времени, тем более, что интерес был чисто теоретическим, практического смысла в знании числа строк кода я не нашёл.
                                0
                                Что ещё нужно учитывать при подсчёте строк кода АМС: я думаю имеет смысл включить в подсчёт и файлы CSS, поскольку это тоже код, который требует усилий по написанию и поддержке.

                                Также нужно учитывать следующий момент. Codestyle AMS исповедует немного нестандартный подход, а именно, табличное форматирование и упаковку кода, поэтому многие его фрагменты, если их привести к стандартному виду, станут занимать на порядок большее количество строк.
                              0

                              Можно спросить, что вас не устраивает в этом классе?

                                0
                                Это лишняя и даже вредная сущность. Вредная — потому, что урезает функционал оригинального API из gcc, для которого выполняет роль обертки.
                                Оригинальное API из gcc для AVR (файл include/avr/eeprom.h):
                                uint8_t eeprom_read_byte (const uint8_t *__p) __ATTR_PURE__;
                                uint16_t eeprom_read_word (const uint16_t *__p) __ATTR_PURE__;
                                uint32_t eeprom_read_dword (const uint32_t *__p) __ATTR_PURE__;
                                float eeprom_read_float (const float *__p) __ATTR_PURE__;
                                void eeprom_read_block (void *__dst, const void *__src, size_t __n);
                                void eeprom_write_byte (uint8_t *__p, uint8_t __value);
                                void eeprom_write_word (uint16_t *__p, uint16_t __value);
                                void eeprom_write_dword (uint32_t *__p, uint32_t __value);
                                void eeprom_write_float (float *__p, float __value);
                                void eeprom_write_block (const void *__src, void *__dst, size_t __n);
                                void eeprom_update_byte (uint8_t *__p, uint8_t __value);
                                void eeprom_update_word (uint16_t *__p, uint16_t __value);
                                void eeprom_update_dword (uint32_t *__p, uint32_t __value);
                                void eeprom_update_float (float *__p, float __value);
                                void eeprom_update_block (const void *__src, void *__dst, size_t __n);
                                
                                Как говорится: почувствуйте разницу. Обратите внимание, что есть готовые функции работы с целыми блоками данных, а Ардуинщик будет реализовывать их циклами с побитными операциями.
                                  0

                                  Но ведь на то в C++ и предуманы классы чтобы от них абстрагироваться.
                                  А конкретный класс EEPROM можно расширить и даже сделать его шаблонным для поддержки разнообразных типов данных. Более того, от него можно унаследоваться и использовать какие-то свои (типы).

                                    0

                                    *прИдумали. Пардон.

                                      0
                                      Если Вам действительно нужен класс (а почему не несколько функций? что Вы собираетесь хранить в полях этого класса?), то наследование от данного класса Вам почти ничего не дает, по сравнению с написанием класса без предков — всего две однострочные функции-обертки. К тому же эти две функции даже не удосужились сделать ни inline, ни static (они же не зависят от полей класса, которых просто нет)
                                      0
                                      есть готовые функции работы с целыми блоками данных


                                      Если доступ к блоку, к примеру, организован через цикл внутри реализации eeprom_read_block — это будет сильно отличается от цикла с ардуиновским read()?
                                        0
                                        Использование непосредственно функций libc будет точно не хуже, если Вам важно, будет ли лучше и насколько — ковыряйте исходники libc, но там ассемблер.
                                          0
                                          Цикл на ассемблере внутри libc, конечно же, быстрее, чем цикл на C++. Только на доступных размерах eeprom это вряд ли хоть для кого-то критично.
                                        0

                                        Кстати, а зачем Ардуинщику реализовывать "это" через циклы и побитовые операции? Разве без них не обойтись?

                                          0
                                          Извините, описАлся. Естественно, я имел ввиду побайтовые.
                                    +1
                                    С помощью чего нарисована схема «Умной теплицы»?
                                    0
                                    Простой планировщик пишется быстро, что софт, что хард риалтайм, со сном и без, даже если не устроят имеющиеся модели. Мне понравились статьи на тему авторов dzavalishin, lain8dono, LifeV и ababo — что хочешь выбирай, ассемблер, С, С++, Раст, и всё работает на микроконтроллёре…
                                      0
                                      Спасибо, почитаем.
                                      +3
                                      Эх, господа мои хорошие, не нужно хаять Ардуино и ардуинщиков; все зависит от области применения и user experience, а уж конечным юзерам абсолютно пофиг, что там внутри embedded ранится — сверхоптимизированный и абсолютно правильный C++ код, или поделка на «старомодном» С, или упаси Боже, на Бэйсике ;) И не стоит улыбаться при упоминании Бейсика — мне лично довелось писать код программно-аппаратной системы на пресловутом Basic Stamp. Хотя тамошний Бейсик — это, скорее, бейсикоподобный макроассемблер, но в сравнении с Ардуино это просто земля и небо. Но, что самое любопытное, все работает годами (уже, практически, десятилетие!), и не где нибудь, а, например, в обсерваториях на Аресибо, являя собой пример передовых американских технологий (с учётом того, что бОльшая часть там работает на микрокомпьютерах 60-70 годов — вот уж где старье, так старье). И работает так, что больше (или лучше, или оптимизирование) никому не нужно — простой, дубовый микроконтроллер с программой на «васике» тупо делает свое дело годами.

                                      P.S. Если выгорит одна штука (тьфу-тьфу!..), так и быть, запощу на хабре статейку «Как заработать $1M на ардуино». Ну, а не выгорит — не запощу :D
                                        0
                                        Именно такую точку зрения я высказал в статье — если телескоп корректно выполняет свои функции, то не имеет абсолютно никакого значения, что там крутится внутри его контроллера. А со статьёй как заработать миллион долларов на Ардуино не затягивайте — мы уже устали ждать пока кто-нибудь поделится столь важной информацией :)
                                          0
                                          Ну, для начала нужно сначала все-таки заработать (хотя шансы весьма неплохи). А отвечал я не вам (вас то я вполне поддерживаю!), а снобам-комментаторам.
                                        +1

                                        А что при переполнении таймера millis()? Раз в 49 суток пропускаем 1 тик высокоуровневых таймеров?
                                        Где-то читал, в ПО какого-то то самолёта обнаружили аналогичную проблему; при uptime 49 суток то ли зависал, то ли перезагружался один из контроллеров. Спасает то, что так долго самолёт не летает.

                                          0
                                          А вот это уже относится ко второй части марлезонского балета. Обратите внимание на методы reStart() и reInit() объектной библиотеки.
                                            0
                                            Вычитание 2 беззнаковых целых никуда не делось. Все равно на 49 сутки
                                            bool myCycle::check() {
                                              if (millis() - _start >= _period) {

                                            сработает не так как хочется.
                                            millis() < _start — по идее, таймер остановится.
                                              0
                                              Конечно остановится, но для решения этой проблемы и предназначены вышеуказанные методы. Сам механизм корректной отработки перехода через «0» для всех «шестерёнок» системы — это тема отдельной статьи.
                                                0
                                                reStart() и reInit() нужно вызвать в правильный момент. Иначе интервал тика окажется где-то между Т и 2Т.
                                                  0
                                                  Совершенно верно.
                                                    0
                                                    Ждать продолжения?
                                          0
                                          Ошибся веткой (del)
                                            +1
                                            По моему Олег был прав… То, что решается в 5 строк человеческими методами (sysTick + 1 счетчик), превратилось в неадекватную портянку на этой вашей ардуине.
                                              –2
                                              Реализацию произвольного числа софтовых таймеров в 5 строках в студию!
                                                +2
                                                В том и дело, что вы упоролись. Какие софтовые таймеры? Мы не в 90-х годах, а в 2018-м. У кортексов есть sysTick уже, который тикает, например, раз в 1 мс и достаточно добавить простой счетчик. У тех же атмег есть аппаратный таймер, который можно так же настроить на отсчет некого интервала и дальше простейший счетчик.

                                                Вы кстати являетесь ярким доказательством губительности ардуины — изобретаете ненужное и кривое софтверное решение вместо использования аппаратных средств. Я даже не хочу говорить о точности софтверных таймеров, вернее о ее отсутствии.
                                                  –2
                                                  Аппаратных таймеров в ардуине 3. В STM32, наверное, их бесконечно много. Как вы собираетесь, к примеру, мигать 10 светодиодами с разной частотой без использования костылей типа софтового таймера? В 5 строк, по возможности ;)
                                                    +1
                                                    Да вы чтоооо? О ужас! Никак нельзя. Беда беда… Бедненькие ардуинщики.

                                                    Для особо талантливых: запускаем таймер, например, с периодом 1 мс -> в прерывании по переполнению инкрементируем переменную time -> досчитал счетик до 10 помигали LED1 -> досчитал до 20 помигали LED1 и LED2. Таким образом получили 2 светодиода мигающих, один с периодом 10 мс (100 Гц), другой с периодом 20 мс (50 Гц).
                                                    Надеюсь как с машстабировать до 5 светодиодов расписывать не надо? Да и проверка на кратность для 5 светодиодов прекрасно влезает в 5 строк, не так ли?
                                                      –3
                                                      Некратных друг другу частот не бывает, это прекрасно.
                                                      19, 47, 67 мс.
                                                      В 5 строк. ;)
                                                        +1
                                                        Вы глупый или тролить пытаетесь? И 19, и 47 и 67 кратны периоду таймера в 1 мс. Если хотели показаться умным, то написали бы что ли типа: 33 мкс, 1,79 мс, 51 мс. Тут хотя бы интереснее было бы, но все же так же просто — уменьшаем период таймера до 1 мкс и все тоже самое получаем. Правда с трудом представляю кому потребоваться может мигалка на сотню кГц.
                                                          0
                                                          Жаль, я так и не добился примера с хорошим и правильным кодом в 5 строк.
                                                          Вот та простыня для ардуины достаточно легко масштабируется на любое разумное количество софтовых таймеров. Да, где необходима точность — так делать не нужно.
                                                          Чем ваш вариант (которого вы так и не показали) лучше?
                                                            0
                                                            Что вам показывать? Вы не в состоянии представить строчку кода?
                                                            if (time%LED1period == 0) {LED1(ON);}

                                                            Данное решение как минимум компактное и реализовано аппаратно без непонятных портянок.
                                                              0
                                                              Этот код в произвольный момент времени включит светодиод. Если LED1(ON) это то о чем я подумал.
                                                              Ладно, пусть это очипятка.
                                                              Простыня из статьи делает совсем другое. Там каждый таймер можно запустить не тогда, когда значение счетчика нацело делится на Х, а когда нужно.
                                                              В простыне из математики — только вычитание.
                                                              У вас — деление (хз, во что развернет его компилятор).
                                                              Походу, у вас от ардуиновского С++ просто подгорает ;)
                                                                0
                                                                С чего вы взяли что произвольно то? Это обычный многоканальный таймер. Вообще ваша позиция забавна: «Я ничего не понял, но оно работать не будет».
                                                                При чем тут плюсы — загадка. Написать портянку говнокода можно на чем угодно, хоть на асме, он от этого таковым быть не перестанет.
                                                                  0
                                                                  С чего вы взяли что произвольно то?


                                                                  Можете запустить свой таймер, например, синхронно с нажатием кнопки?
                                                                  Сможете, конечно, но это будет уже не так красиво.

                                                                  Вообще ваша позиция забавна: «Я ничего не понял, но оно работать не будет».

                                                                  Тоже мне бином ньютона. Будет работать, не переживайте.
                                                                  Спрогнозировать, сколько тактов займет сравнение
                                                                  time%LED1period == 0
                                                                  сможете? Каюсь, не читал я даташитов, но что-то мне подсказывает, что деления с остатком ATMEGA не умеет. Мне кажется, что гонять цикл с делением внутри только для проверки на 0 — это очень, пардон, попахивает говнокодом.
                                                                    0
                                                                    Можете запустить свой таймер, например, синхронно с нажатием кнопки?
                                                                    Сможете, конечно, но это будет уже не так красиво.

                                                                    Внешние прерывание (EXTI) завести как триггер для таймера. Некрофилы на древних атмегах могут таки выставить флаг и синхронизироваться по нему.
                                                                    попахивает говнокодом

                                                                    И это я слышу от любителя «ардуинского С++» обернуть все в структуры… Ладно, если бы в коде все обернули в inline функции, тогда можно было бы подискутировать о точном высчитывание тактов и прочем…

                                                                    Если вам не нравится деление с остатком, то можно и иначе реализовать. Я в качестве примера привел лишь совсем очевидное решение.
                                                                      0
                                                                      Если вам не нравится..


                                                                      Не то чтобы не нравилось… Еще раз намекаю: короткий и какбы очевидный код — не всегда хороший. Длинный код — не обязательно плохой. Бывают случаи, когда классы — это хорошо. Бывают — когда неважно.

                                                                      … то можно и иначе реализовать

                                                                      Конечно. Только если захочется сделать тот же функционал, что и в простыне, только без классов — получится такая же простыня, или чуть больше, но на гордом С.
                                                                      +2
                                                                      Можете запустить свой таймер, например, синхронно с нажатием кнопки?
                                                                      Сможете, конечно, но это будет уже не так красиво.


                                                                      удивительно, насколько такие элементарные вещи могут казаться некоторым сложными ))

                                                                      слышали про такую страшую вещь как прерывания?
                                                                      вот на прерывании по фронту на пине это легко реализуется (давайте теперь поспорим 5 строк мне на это понадобится или 11, это критически важно))
                                                                        0
                                                                        Какая религия запрещает прерывания в Arduino?

                                                                        Да, если использовать приведенную в статье простыню — это будет в 1 строчку. Вызвать reStart().
                                                                          +1
                                                                          какая религия? Ардуинизм, наверное? )
                                                                          Почему автору проще организовать многозадачность, чем инициировать прерывания таймера?
                                                                          Тут вам и «1 строчка» — многозадачность сожрёт все ресурсы небольшого контроллера в один присест. Как раз на одну строчку и останется))
                                                                            0
                                                                            Многозадачность — тяжелые куски кода выполняются какбы одновременно.
                                                                            Прерывания — маленькие куски кода выполняются синхронно с внешним, по отношению к коду, действием.
                                                                            Много логики в прерывания лучше не пихать. Автору было проще сделать то, что он сделал.

                                                                            многозадачность сожрёт все ресурсы небольшого контроллера в один присест

                                                                            Почему это? У автора статьи вся логика на вычитании и сравнении. Чтобы сожрать все ресурсы этой математикой — таймеров нужно нагенерить… Сколько влезет в в RAM.
                                                                              +2
                                                                              Многозадачность — тяжелые куски кода выполняются какбы одновременно.
                                                                              Прерывания — маленькие куски кода выполняются синхронно с внешним, по отношению к коду, действием.


                                                                              многозадачность и прерывания различаются по количеству выполняемого кода в самую последнюю очередь. По кол-ву кода это всё равно что тёплое и мягкое сравнивать )

                                                                              У автора статьи вся логика на вычитании и сравнении. Чтобы сожрать все ресурсы этой математикой — таймеров нужно нагенерить…


                                                                              для мелкого контроллера многозадачность это прежде всего либа, которая займёт 70-80% флеша.
                                                                              А потом ещё всякие мелочи, такие как время реакции на эту вашу кнопку на 4мгц, допустим, тактового.
                                                                              0
                                                                              Тут вам и «1 строчка» — многозадачность сожрёт все ресурсы


                                                                              Не хочу вторгаться в вашу благородную дискуссию, но вы статью читали? Там в подписи к скриншоту dash-панели специально указывается, что при управлении сотней «сущностей» в виде актуаторов, моторов и прочего загрузка контроллера «0», то есть меньше одного процента.
                                                                                0
                                                                                )) удивительно, правда, учитывая что это просто поливалка для фикуса?
                                                                                А вот поуправляйте этими сущностями в контроллере CNC или в коптере, например. Вот тогда реальные проценты и увидите.
                                                                                  0
                                                                                  для мелкого контроллера многозадачность это прежде всего либа, которая займёт 70-80% флеша.
                                                                                  А потом ещё всякие мелочи, такие как время реакции на эту вашу кнопку на 4мгц, допустим, тактового.


                                                                                  Мне кажется вы упускаете из виду один принципиальный момент, а именно: речь идёт о готовом проверенном решении и рассуждать на тему почему это не будет работать бессмысленно — это уже (прекрасно) работает

                                                                                  учитывая что это просто поливалка для фикуса?


                                                                                  Называя «поливалкой для фикуса» распределённый nRF24 контроллер с сотней управляемых сущностей, собственным сервером и полноценным управляющим сайтом и работающим при этом на 8-битной Меге — вы немного лукавите — это как бы не совсем «поливалка для фикуса».
                                                                                    0
                                                                                    речь идёт о готовом проверенном решении и рассуждать на тему почему это не будет работать бессмысленно — это уже (прекрасно) работает


                                                                                    неправда. Речь идёт о «превратном отношении к Ардуино» )) Как реализована чья-то конкретная поливалка мало кому интересно.

                                                                                    Называя «поливалкой для фикуса» распределённый nRF24 контроллер с сотней управляемых сущностей, собственным сервером и полноценным управляющим сайтом и работающим при этом на 8-битной Меге — вы немного лукавите — это как бы не совсем «поливалка для фикуса».


                                                                                    речь о загрузке проца исполнительными программами с дьюти циклом много меньше процента(полив освещение и тп). Отсыл пакета через nRF24 тоже совсем не требует гигифлопса.
                                                                                    Всё это крайне некритичная ко времени выполнения история.
                                                                                    Это именно поливалка для фикуса.
                                                                                      0
                                                                                      неправда. Речь идёт о «превратном отношении к Ардуино» )) Как реализована чья-то конкретная поливалка мало кому интересно.


                                                                                      Вот этот пассаж совсем не понял
                                                                                        0
                                                                                        Судя по высказываниям Олега, у него весьма превратное представление об Arduino вообще и об «ардуинщиках» в частности. Мигание пятью светодиодами в означенных им режимах это абсолютно тривиальная задача для Arduino, а для Arduino Mega Server это вообще не задача, а сущее недоразумение — его штатными средствами организуется многозадачность, которая легко управляет сотнями различных сущностей (светодиодов, сервоприводов, шаговых моторов и т. д.) в реальном времени.

                                                                                        Давайте вместе разберёмся как организовать многозадачность на Arduino, а заодно поможем студентам МИРЭА избавится от навязанных им стереотипов восприятия по отношению к социо-культурному и технологическому феномену нашего времени под названием Arduino.

                                                                                        (с)ТС
                                                                                    0
                                                                                    А вот поуправляйте этими сущностями в контроллере CNC или в коптере, например.


                                                                                    Мне вот кажется, что контроллер коптера с 100500 канальной поливалкой для фикуса имеет очень мало общего. 100500 таймеров в коптере не нужны. Быстродействующий PID регулятор для управления поливом не нужен. Разный функционал — разные решения. Ваш кэп ;)
                                                                                      0
                                                                                      вообще-то спор не о поливалке, а о стиле программирования, порождённом Ардуино(во многом другом очень правильной и полезной вещью)

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


                                                                                        Стиль как стиль. Позволяет не упарываться слишком глубоко в потроха периферии без необходимости. Но ни читать документацию, ни смотреть (и менять) исходники ардуины ведь не запрещено? ;)
                                                                                        ЗЫ. Таймер для PWM (миллисекунды) и таймер для полива (десятки секунд) — разные же…
                                                                                          0
                                                                                          Да ничего он не позволяет, вообще-то.
                                                                                          В мегу8 под «многозадачностью» просто уже не влезет ни одна серьёзная программа ))
                                                                                          Я уже не говорю про тини какую-нибудь, в неё же и многозадачнось не влезет даже, как светодиодами мигать прикажете? )))
                                                                                            0
                                                                                            Да ничего он не позволяет, вообще-то.


                                                                                            Истинное Мнение Хрен Оспоришь ;)

                                                                                            В мегу8 под «многозадачностью» просто уже не влезет ни одна серьёзная программа


                                                                                            Одна влезла ;)

                                                                                            Я уже не говорю про тини какую-нибудь

                                                                                            robocraft.ru/blog/arduino/3423.html
                                                                                            Для задачи типа ногодрыга даже attiny настолько избыточна, что arduino туда помещается вместе с дрыгалкой.
                                                                                              0
                                                                                              Для задачи типа ногодрыга даже attiny настолько избыточна, что arduino туда помещается вместе с дрыгалкой.


                                                                                              ардуино помещается?
                                                                                              гхм… а вы уверены что понимаете о чём говорите? ))
                                                                                                0
                                                                                                Пардон, ссылку привел, но сам не читал. :( Не о том она.
                                                                                                Ну, не помещается. Нельзя просто взять Arduino IDE и залить скетч в AtTiny 13.
                                                                                                В AtMega8 помещается. И этот контроллер тоже для большинства применений избыточен.
                                                                                                  0
                                                                                                  Всё-таки видимо не очень понимаете )
                                                                                                  Никакое ардуино никуда не помещается. Ардуино это просто надстройка над winavr, который в свою очередь содержит в основе GCC. И скетч тоже никуда не заливается. На основе него получается нормальный с-код, который компилируется в стандартный бинарник, который теоретически может быть неотличим от сгенерированного прямо из GCC.
                                                                                                  Проблема в том, что Ардуино, скрывая от пользователя железо и приучая его к дурному стилю программирования, генерит для GCC кучу бессмысленной пузырчатки, забивающей флеш и замедляющей исполнение в разы.

                                                                                                  О каком большинстве применений вы говорите — тоже не очень понятно. О большинстве мигалок светодиодом и поливальных систем? Применение МК сильно шире вообще-то, и для большинства применений у м8 тупо не хватит ног, не говоря уже обо всём остальном )
                                                                                                    0
                                                                                                    Под фразой «ардуино помещается» прошу понимать «помещается его бутлоадер и его бессмысленная пузырчатка достаточно жирная библиотека».
                                                                            0
                                                                            time%LED1period == 0
                                                                            сможете?


                                                                            if (time==LED1period) {...}
                                                                            Кратко, лаконично, без делений и умножений.
                                                                              0

                                                                              Кратко, лаконично, но я бы по своей воле никогда бы так не делал. Если время при каждой проверке увеличивается на 1 — ок, условие сработает. Если где-то в коде delay(), можно пропустить момент срабатывания. Зачем своими руками себе же расставлять грабли?

                                                                                0
                                                                                Тогда и деление по модулю не сработает
                                                                0
                                                                Вы не полностью оценили «прикол», iig писал о мигании 10 диодами в 5 строк кода.
                                                                  +1
                                                                  Да я оценил его попытки смешно пошутить, но мне кажется для этого нужен талант. Жаль шутка на уровне Камеди.
                                                                  Про 5 светодиодов и 5 строк я таки конкретно писал, как собственно и про масштабируемость. Вроде как про данное количество мигалок говорил Олег. Попытка «шутить» про 10 светодиодов — это скорее попытка переключить тему, а то собственную глупость обнаружил, надо же как-то выкрутиться.
                                                                  0
                                                                  Можно чуть экономичнее (и так и делают): тикать прерыванием каждую миллисекунду не надо, достаточно при очередном срабатывании таймера посмотреть, через сколько следующее событие, и поставить срабатывание на этот момент.

                                                                  Если следующее событие дальше, чем переполнение таймера — ставим срабатывание на обнуление таймера, по нему снова пересчитываем. Ну а аппаратный таймер выбираем уже исходя из нужной точности, поведении во сне и т.п. — обычный таймер, LPTIMER, RTC…
                                                          +3
                                                          Многозадачность для независимого мигания светодиодами?
                                                          И после этого жаловаться на превратное отношение?
                                                            +2
                                                            Статья полностью подтверждает правоту Артамонова)
                                                            +3
                                                            Понимаю, почему может раздражать некоторых гуру существование Ардуино.
                                                            Не будучи электронщиком я лет 10 назад заинтересовался AVRками. Тогда, чтобы запустить шаговый двигатель пришлось попотеть (AVR studio, assemler, ЛУТ) — в это есть свои плюсы. Но теперь с Ардуиной, тот же ШД, термопары, ИК-темометры на работе я припахиваю к своей экспериментальной установке за смешные деньги в 15 минут.
                                                            А курящие в коридоре электронщики, заглядывают в комнату, смотрят на Ардуино и тоскливо спрашивают: «Может вам на установку сделать автоматизацию?» (За немалые деньги)
                                                            А ведь на Ардуино всё хорошо работает и я доволен!
                                                              +1
                                                              Если хорошо «пораскинуть мозгом», то становится очевидным, что Ардуино совершило настоящее чудо из чудес — приобщила к программированию микроконтроллеров и техническому творчеству миллионы людей. Вдумайтесь: до появления Ардуино это было просто немыслимо. Уже за одно это создателям Ардуино нужно поставить памятник при жизни.

                                                              А как будут организованы таймеры — по циклам, прерываниям и аппаратным таймерам — это чисто технический вопрос и я бы не стал так близко воспринимать его к сердцу :)
                                                                +2
                                                                Ардуино совершило настоящее чудо из чудес — приобщила к программированию микроконтроллеров и техническому творчеству миллионы людей.
                                                                Здесь надо все же разделять железную и софтверную компоненты. Что касается железа, то с Вами трудно не согласиться. А вот что касается софта — то имеются две стороны медали. С одной стороны — просто замечательно, что можно помигать светодиодом совершив всего «пару кликов мышки» и сделать это можно не имея вообще никаких познаний в программировании. С другой стороны — многие из этих вновь приобщенных людей так и остаются работать в этой обособленной среде разработки, даже перейдя от мигания светодиодом до вполне серьезных проектов, вроде Вашего AMS. Здесь люди пытались делать замечания про качество Вашего кода, причем, высказано отнюдь не все, Ваше агрессивное «работает, и нет никому дела, как это написано» отбивает желание комментировать. Вот это, как раз, и вызывает раздражение опытных разработчиков по отношению к «ардуинщикам». А такой подход во многом вызван именно замкнутостью среды разработки, что приводит и к замкнутости разработчиков в своем «чудном маленьком мирке Ардуино», тем самым отдаляя их от всего остального сообщества программистов, занимающихся серьезной разработкой под микроконтроллеры. А учиться, судя по Вашему коду, Вам еще есть много чему.
                                                                  +1
                                                                  Вы пишите, что «многие из этих вновь приобщенных людей так и остаются работать в этой обособленной среде разработки», но Ардуино даёт им хотя бы шанс, а без Ардуино у этих людей не будет ни одного шанса, ибо:

                                                                  если вы попытаетесь дать своему 10-летнему ребёнку даташит на STM32, то на этом его знакомство с волшебным миром микроконтроллеров будет закончено и скорее всего на всю жизнь. А если вместо даташита на STM32 вы дадите ему Ардуино, то со временем он может перейти и к STM32.
                                                                    0
                                                                    Что касается ребенка — согласен, но дальше, в процессе его становления как разработчика, очень важно вовремя спрыгнуть на полноценную среду разработки, а мы видим, что люди так и остаются в Ардуино, пишут не программы, а «скетчи», пишут на языке, который абсолютно не знают (а C++ довольно сложен для понимания, если не ограничиваться верхами) и т.д., что и порождает образ «ардуинщика». Даташит, хоть на AVR, хоть на STM, все равно, рано или поздно, прочитать досконально изучить придется.
                                                                    Кстати, на STM тоже можно начать работать не читая даташит, а ограничившись знанием HAL, если код инициализации сгенерировать с помощью CubeMX. Плюс этого подхода в том, что за Вас генерируется только структура проекта с инициализацией, при этом больше ничего не навязывая.
                                                                      +1
                                                                      Кстати, это интересный вопрос. А вы никогда не задумывались почему они так и остаются на Ардуино? Я думаю, что люди делятся на «обычных» (большая часть) и технарей (меньшая).

                                                                      Эти две категории по разному смотрят на мир. Если технарей-гиков просто «колбасит не по децки» если мы мигаем через таймер, а не запускаем процесс в какой-нибудь RTOS, но «нормальным людям» это до лампочки — им важно чтобы свет просто включался когда им надо.

                                                                      Так вот, моя версия: Ардуино позволяет «обычным людям» решать свои насущные проблемы. И им просто не нужно никуда переходить. И им абсолютно фиолетово насколько хорош STM32.
                                                                        0
                                                                        Я думаю, что люди делятся на «обычных» (большая часть) и технарей (меньшая).
                                                                        Я думаю, что большинство из тех, кого заинтересовали контроллеры, все же относятся к технарям. Вашу классификацию лучше переиначить на профессиональных разработчиков и любителей, не особо собирающихся совершенствоваться.
                                                                        Если технарей-гиков просто «колбасит не по децки» если мы мигаем через таймер, а не запускаем процесс в какой-нибудь RTOS, но «нормальным людям» это до лампочки — им важно чтобы свет просто включался когда им надо.
                                                                        Меня как раз еще больше бы колбасило, если для мигания диодом использовать отдельную задачу RTOS, для этого, на худой конец, есть корутины.
                                                                        И им абсолютно фиолетово насколько хорош STM32.
                                                                        Да что вы уперлись в противостояние AVR и STM, это разные архитектуры, но их различия никак не влияет на подход к разработке. Я, например, и на AVR, и на STM, пишу в одном и том же Eclipse, используя всего лишь разные плагины.
                                                                          0
                                                                          А меня бы не «колбасило» если всё работает нормально. Если бы нашлось лучшее решение, то я бы просто его применил — это вообще технические моменты, а не повод для эмоций.

                                                                          STM32 это просто фигура речи, я тут не вкладывал какого-то особого смысла.
                                                                            0
                                                                            А меня бы не «колбасило» если всё работает нормально. Если бы нашлось лучшее решение, то я бы просто его применил
                                                                            В двух соседних фразах Вы сами себе противоречите. Вы уж определитесь — будете применять любое работающее решение, или попробуете найти лучшее.
                                                                              0
                                                                              Объясняю. Тут чуть выше пытались подсчитать количество строк кода в проекте, толком это не получилось, но судя по всему цифра будет в районе многих десятков тысяч. И мест для улучшения как чисто формально-технических, так и концептуальных там просто немерено.

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

                                                                              Надеюсь теперь вам стало понятно.
                                                                                0
                                                                                Объясняю. Тут чуть выше пытались подсчитать количество строк кода в проекте, толком это не получилось, но судя по всему цифра будет в районе многих десятков тысяч. И мест для улучшения как чисто формально-технических, так и концептуальных там просто немерено.
                                                                                То, что «сотни тысяч строк» в Вашем представлении превратились в десятки — это уже хорошо, хоть чуть-чуть, но поближе к истине. Напомню, что применительно к эмбедингу, который мы здесь обсуждаем, в Вашем проекте именно Вашего кода чуть меньше 5000 строк, что не так уж и много. Если у Вас возникают проблемы с улучшением такого объема кода, то это говорит или о серьезных проблемах с архитектурой проекта, или о Вашей неготовности, как программиста, работать со сколько-нибудь серьезными проектами. Если первое — то проект надо переписывать, и чем раньше, тем лучше — меньше будет работы в корзину. И в любом случае, «как завещал великий Ленин — учиться, учиться и учиться».
                                                                                Надеюсь теперь вам стало понятно.
                                                                                Извините, но мне все понятно стало еще в середине обсуждения. Я продолжал дискуссию лишь из надежды на то, что еще один «ардуинщик», возможно, станет программистом. Но, увы, не в этот раз…
                                                                                  0
                                                                                  Странные вы какие-то делаете выводы. Мы все (я по крайней мере) постоянно учусь и это абсолютно естественный процесс — у кого-то он идёт быстрее, у кого-то медленнее, но я тут останавливаться совершенно точно не собираюсь.

                                                                                  Что касается подсчёта строк, то как сама затея, на мой взгляд имеющая мало смысла, так и ваша методика, игнорирующая весь JavaScript, Processing (а также спорный CSS код), то есть две трети всего кода тоже, мягко говоря, весьма странны.

                                                                                  Также большие сомнения у меня вызывают ссылки на «эффективный» код и приведённые вами примеры подсчёта непонятно чего из «~/tmp/» директории.

                                                                                  Если вы уже так хотите посчитать количество строк в проекте, то сделайте это корректным способом и огласите методику подсчёта или просто не стоит поднимать эту тему.
                                                                                    0
                                                                                    Странные вы какие-то делаете выводы. Мы все (я по крайней мере) постоянно учусь и это абсолютно естественный процесс — у кого-то он идёт быстрее, у кого-то медленнее, но я тут останавливаться совершенно точно не собираюсь.
                                                                                    Это очень хорошие и правильные слова, но им противоречит Ваша реакция на критику.
                                                                                    Что касается подсчёта строк, то как сама затея, на мой взгляд имеющая мало смысла, так и ваша методика, игнорирующая весь JavaScript, Processing (а также спорный CSS код), то есть две трети всего кода тоже, мягко говоря, весьма странны.
                                                                                    В вашей статье изначально речь шла об эмбединге, поэтому его и обсуждаем. Веб-программирование — очень далекая от эмбединга тема, они очень мало пересекаются, и вряд ли стоит это все мешать в кучу. Я прекрасно понимаю, что Вы в своем проекте ответственны и за то, и за то, но это все равно не позволяет подходить к этим разным областям одинаковым образом. За остальными разъяснениями отсылаю Вас к ветке выше, где уже все было сказано.
                                                                                    Также большие сомнения у меня вызывают ссылки на «эффективный» код и приведённые вами примеры подсчёта непонятно чего из «~/tmp/» директории.
                                                                                    Что такое sloc — я приводил ссылку. По поводу ~/tmp/ — а куда по Вашему я должен был распаковать архив, скачанный с Вашего сайта, для обработки?
                                                                                    Если вы уже так хотите посчитать количество строк в проекте, то сделайте это корректным способом и огласите методику подсчёта или просто не стоит поднимать эту тему.
                                                                                    повторно отсылаю Вас к ветке выше
                                                                            +1
                                                                            Вы конечно правы — если человек разработчик систем на МК, то должен и может. Однако дело не всегда обстоит так.
                                                                            Для примера поясню мою ситуацию — основная работа физика, писание формул, прикладное программирование, измерения, ведение инженерных проектов. Если честно, просто нет времени глубоко копатьcя в микроконтроллерах. Обычная задача — быстро и дешево получить результат любым способом. Измерил, совпало с расчётами — Супер и слава б… гу!
                                                                            Когда же нужно делать полноценную систему, призываю спецов-разработчиков — это их хлеб.
                                                                              +1
                                                                              Простая и разумная позиция. Смог — сделал сам на Ардуино (заодно прокачал свой уровень). Что-то сложное — заказал разработку профессионалам.
                                                                                0
                                                                                Вы тоже готовы опубликовать свое кое как сделанное решение какой-либо проблемы, а потом в штыки воспринимать любую справедливую критику? Надеюсь, что нет, в противном случае непонятны мотивы, подвигнувшие на публикацию.
                                                                                  0
                                                                                  Простите, не смог уловить смысл вашего послания
                                                                                  0
                                                                                  С этой точки зрения Вы, конечно, правы. Я бы не стал публиковать «необдуманный» материал.
                                                                          +1
                                                                          если вы попытаетесь дать своему 10-летнему ребёнку даташит на STM32, то на этом его знакомство с волшебным миром микроконтроллеров будет закончено и скорее всего на всю жизнь


                                                                          Вы когда-нибудь в жизни такую штуку, как «операционная система», вообще видели?..
                                                                        0
                                                                        Ардуино — дань возникшей за последние 10-15 лет ситуации, когда программисты, привыкшие свободно оперировать высокоуровневыми «сущностями», но не понимающие, как работает элементарная железяка, стали составлять большинство. Для них придумали игрушку, чтобы можно было, оставаясь в привычной парадигме, порулить какими-то реальными объектами. Она прикольная и социально-полезная, не спорю. А игрушка это потому, что профессионалами-эмбеддерами круг задач, решаемых на ардуине, отработан 20 и более лет назад. Современные же применения для встроенных МК — это те же коптеры, дроны, системы автовождения с анализом изображений от нескольких камер в реальном времени, прыгучие собаки-роботы с их сложной динамикой, распознание банкнот со скоростью десятки в секунду…
                                                                          +1
                                                                          скажем так, для студентов «будущих промышленых железячников» — ардуину можно, а может даже и нужно охаять, публично заклеймить и предать анафеме.
                                                                          Однако с другой стороны, для проектов, которые «профессионалами-эмбеддерами отработаны 20 и более лет назад» — почему бы наоборот не порекомендовать ардуину?
                                                                          Для игрушек, для старта школьникам, для теплиц и бассейнов садоводам и дачникам.
                                                                          Неужели нельзя без снобизма «или только как святые отцы завещали или никак»?

                                                                          PS: грубо говоря, я понимаю, что выпускнику «факультета мостостроения» негоже строить курятник или сортир без расчетов и сопромата, но это же не значит, теперь каждый дачник тоже должен его знать и чтоб нини самопала.
                                                                            0
                                                                            Современные же применения для встроенных МК — это те же коптеры, дроны, системы автовождения с анализом изображений от нескольких камер в реальном времени, прыгучие собаки-роботы с их сложной динамикой, распознание банкнот со скоростью десятки в секунду…

                                                                            Вообще-то ключевое слово в этом всем — "встроенные". Это означает, что такую систему поставил и забыл — то есть ты ее не видишь, не слышишь, не имеешь к ней доступ, когда захочется и она не требует никакого обслуживания — ни периодического, ни ремонта, ни апгрейдов.


                                                                            И это, как ни странно, очень важное понятие, которое трудно обьяснить программисту — что цикл разработки такой железки заканчивается не тогда, когда оно начало моргать лампочками и крутить моторчиками по команде от кнопки, что для десктопного программиста означает "уже продакшн, если что-то зависнет, или заработает неправильно, пользователь перезагрузит", а только тогда, когда такая железяка будет готова к тому, что будет работать в режиме 24/7/365 вообще без какой либо необходимости вмешательства пользователя или разработчика и при всевозможных внешних условиях, включая пропадания и появления питания, изменения температуры и других внешних условий и в том числе неадекватной реакции пользователей, которые об этой железяке ничего не знают.

                                                                        +1
                                                                        На всякий случай, классический туториал про таймеры на AVR: Newbie's Guide to AVR Timers
                                                                          0
                                                                          Спасибо, полезная информация.
                                                                          0

                                                                          Эмммм… Разве эта статья имеет отношение к Ардуино?


                                                                          Что я понял из прочитанного и лекций Олега.


                                                                          Олег говорит, что Ардуино — устаревшее железо и не слишком удобная экосистема. Ардуинщик! Если хочешь двигаться дальше — изучай это и это.


                                                                          Автор статьи говорит: а я на Мега таки забабахал платформу и давай, ардуинщики, велкам в неё.


                                                                          Разве я неверно описал ситуацию?

                                                                            0
                                                                            Олег говорит всё правильно и в статье я это отметил и порекомендовал всем заинтересованным в вопросе ознакомиться с его лекциями.

                                                                            Но.

                                                                            Наряду с 99% абсолютно правильной информации Олег позволяет себе говорить вещи абсолютно не соответствующие действительности. Проблема в том, что Олег произносит эти вещи не в курилке среди своих собратьев по разуму, а с трибуны технического университета и на головы несчастных студентов.

                                                                            На протяжении всех лекций Ардуино у него выступает в роли «мальчика для битья». То у Олега ардуинщики не смогут помигать пятью светодиодами, то «подход с бесконечным циклом не работает на сложной программе» то ещё куча высказываний подобного рода.

                                                                            На самом деле подход с бесконечным циклом прекрасно работает на сложной программе и в этом каждый может убедиться, скачав дистрибутив АМС для любой из десятка платформ от Mega 2560 до ESP32.
                                                                              0
                                                                              подход с бесконечным циклом не работает на сложной программе


                                                                              Насколько я помню, любая GUI программа под Windows — это бесконечный цикл обработки сообщений.
                                                                              Если бы существовал Единственно Правильный и Универсальный способ написания программ — все бы пользовались только им, писали правильные программы, и никто не писал неправильные.
                                                                                0
                                                                                Ёлки-палки дык и я о том же. Тем более на одноядерном контроллере — этот цикл так или иначе присутствует в системе — вопрос только на каком уровне и какая абстракция торчит наружу.
                                                                                  0
                                                                                  Насколько я помню, любая GUI программа под Windows — это бесконечный цикл обработки сообщений.
                                                                                  Позвольте поправить: не любая программа, а основной поток выполнения любой программы. Но на этот поток нельзя навесить ни ресурсоемкие вычисления, ни обработчики событий, требующих быстрой (насколько это позволяет диспетчер) реакции. Для этих целей приходится запускать отдельные потоки.
                                                                                  +1
                                                                                  На самом деле подход с бесконечным циклом прекрасно работает на сложной программе и в этом каждый может убедиться, скачав дистрибутив АМС для любой из десятка платформ от Mega 2560 до ESP32


                                                                                  Скажите, а цель этих ваших мучений — она какая?

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

                                                                                  Зачем?
                                                                                    0
                                                                                    Олег, мне странно слышать этот вопрос, с тем же успехом я могу спросить зачем вы мучаете свои проекты.
                                                                                      0
                                                                                      Во-первых, я их не мучаю, я на них деньги зарабатываю. Во-вторых, выбор эффективного инструментария для реализации этих проектов — один из ключевых вопросов в нашей работе.

                                                                                      А зачем вы упорно пытаетесь что-то делать на инструментарии, который устарел десятилетия тому назад, понять довольно трудно.
                                                                                        +1
                                                                                        Это не устаревший инструментарий — Ардуино это платформа, которой пользуются миллионы людей и проект написанный на Ардуино имеет шанс быть понятым и используемым множеством людей в DIY, в отличии от RTOS и чистого C++. Другими словами — это платформа DIY.

                                                                                        И разумеется ничто не мешает мне сделать следующий проект на столь милой вашему сердцу RIOT OS — интересы у меня очень обширные.
                                                                                          0
                                                                                          Ардуино это платформа, которой пользуются миллионы людей и проект написанный на Ардуино имеет шанс быть понятым и используемым множеством людей в DIY, в отличии от RTOS и чистого C++.

                                                                                          А что, это как-то противоречит тезису «она устарела»?
                                                                                            +1
                                                                                            Автомат Калашникова устарел. Но до сих пор работает, и заявленные функции выполняет.
                                                                                              0
                                                                                              Ну да. Выполняет. Если продолжать аналогию, к нему можно даже прикрутить ленточную подачу патронов, с костылями и внешним движком для этого, но лучше все-таки взять современный автомат. И уж точно не стоит учить такому людей.
                                                                                                0
                                                                                                «Устарел» — это не «существует более N лет», а «превзойдён более новыми решениями».

                                                                                                Так вот, с тем, чтобы превзойти автомат Калашникова по сумме показателей, проблемы есть уже не первое десятилетие, хотя Минобороны очень хочет.

                                                                                                А с тем, чтобы превзойти ардуину по всем показателям разом, проблемы нет вообще никакой.
                                                                                                  +1
                                                                                                  В вашей системе координат АК-74М уже давно превзойден.
                                                                                                  Абакан, AR-15, да галил тот же. Почему-то правда здесь сейчас прозвучит «а ты забивал в приемник арки грязный магазин? Да талибы из неё и 60 патронов не расстреляют, сломают, а вот АК работает всегда везде и в любых руках»
                                                                                                  Так вот, превзойти ардуину по распространенности и скорости ПРОТОТИПИРОВАНИЯ решений неподготовленным человеком пока что не получается ровно также как в вашей аналогии с АК
                                                                                      0

                                                                                      "скачав дистрибутив АМС для любой из десятка платформ от Mega 2560 до ESP32."
                                                                                      Но это не Ардуино! Это Ваша ОС(?) на том или ином железе.
                                                                                      А дальше выбор пользователя — доверять вашей системе или той, что двигает Олег.
                                                                                      И ту и другую надо изучать, тратить время, ресурсы.
                                                                                      Олег ратует за STM32, вы — ряд другого железа, в том числе и 32bit МК среди него.
                                                                                      Поэтому, ИМХО, эти заметки к Ардуино отношения не имеют. Они о (условном) "соревновании" Riot OS на STM32 И AMS на том, куда Вы его портировали.
                                                                                      И, в некоторой степени, это "прикрытие" AMS лейблом Ардуино.

                                                                                        +1
                                                                                        Я ратую не за STM32, а за современные средства разработки.

                                                                                        Чтобы не приходилось по принципу «Ах, как это у нас нет абстрагированных от железа таймеров? Я вот сейчас возьму и за неделю докажу обратное!» в муках рожать то, что все остальные люди получают тупо из коробки, готовое к использованию и существенно более высокого качества.
                                                                                    0
                                                                                    в статье особо жестоко передёргиваются факты.
                                                                                    «первый» автор был ближе к истине, когда рассказывал на лекции будущим инженерам про отсутствие многозадачности на андрунно, т.к. с точки зрения этого самого инженера и с точки зрения потенциальных задач — её там нет. сказки про управление сотней «сущностей» и красивые картинки это очень хорошо, но ровно до момента уточнения, что скрывается за понятием «сущность» и каково время отклика/обмена.
                                                                                    если Mega Server управляет 100 клапанами или светодиодами — откуда будет нагрузка на ядро? опрос кнопки или включение реле это единичные команды, они физически не могут воссоздать любую ощутимую «нагрузку». почему хоть это и является истинной причиной и основой работы — никак не упомянуто в статье?
                                                                                    не упомянуто, что «управление шаговым двигателем» — это тупая выдача пачки импульсов dir и step на отдельный контроллер.
                                                                                    не упомянуто, что «датчики влажности» — это тупые каналы ацп. они физически всегда работают сами по себе, параллельно контроллеру, и уж конечно будет достаточно скорости опроса 1sps/s. где нагрузка для контроллера с частотой 16МГц?
                                                                                    не упомянуто, что «сервоприводы» — это тупые сервы с отдельным контроллером, которым для управления достаточно софтового шим на 50 Гц. это сложнее первых вариантов, но не может быть ощутимо в масштабах скорости работы контроллера.
                                                                                    не упомянуто, что любые оставшиеся виды датчиков и исполнительных механизмов для ардуйни — по сути вариации вышеперечисленного. и конечно же, такая «нагрузка» не может «грузить» RTOS даже на 8-битном камне.
                                                                                    ардрунно это крайне удобный инструмент, и для автоматизации и для обучения и для прототипирования. низкий порог вхождения, масса готовых модулей (дешёвых!). наличие большого количества готовых поделок, в т.ч. опенсорс, откуда можно заимствовать работающие решения. но если оспаривать того автора и впустую не набрасывать кал на вентилятор — нужно привести аргументы на уровне того самого автора. студентов инженеров не учат проектировать поливалки для цветов.
                                                                                      0
                                                                                      Вы написали очень много букв, я скажу короче. Олег заявил, что у ардуинщиков будут проблемы с тем, чтобы помигать пятью светодиодами. Я утверждаю, что это снобистское и не соответствующее действительности заявление.
                                                                                        0
                                                                                        я написал многобукв про конкретные пункты и конкретные моменты, которые заведомо или случайно «не раскрыты» в статье. я не смотрел указанные лекции, и очень возможно что автор упоротый фанбой кортексов и плисов, большой хейтер ардуин, но с точки зрения подачи материала а также целевой аудитории — лучше соврать про проблемы с пятью светодиодами будущему инженеру на профильном семинаре, чем соврать про несуществующие псевдоспособности девайса на «уважаемом техническом ресурсе».
                                                                                          0
                                                                                          Ну, во первых, прежде чем комментировать в духе «книгу я не читал, но осуждаю», желательно всё же ознакомиться с первоисточниками в виде лекций и одного из дистрибутивов АМС. Без этого ваши комментарии имеют очень небольшую ценность.

                                                                                          И, во вторых, лучше вообще не врать, особенно когда ты выступаешь с кафедры университета и программируешь поведение (на основе внушаемых стереотипов) десятков (а учитывая распространение лекций через интернет) тысяч людей.
                                                                                            +2
                                                                                            специально прослушал половину той лекции и конкретно упомянутый отрезок. подача материала отличная. перегибы в сторону анрдрунно — это просто личный бзик автора. возможно начинал с неё, перерос и теперь такой стиль «преподавания». возможно негативный опыт применения, возможно немного раздутое ЧСВ — это неважно. и конкретно в той цитате он был абсолютно прав и честен, если просто дополнить высказывание словами «помигать на частоте 50-100 кГц» — это разом ставит крест на всех «доводах» в статье, просто моментально.
                                                                                            ещё раз — инженеров не учат дизайнить поливалки с дискретностью управления в одну секунду. никакой многозадачности и многопоточности с точки зрения «обычных» для инженерных применений у ардуины нет, неважно насколько тридэ она рисует на экране погодной станции. ну и лекцию он читал не на DIY митапе где собрались самоделкины с смузи.
                                                                                              0
                                                                                              перегибы в сторону анрдрунно — это просто личный бзик автора

                                                                                              Именно об этом я и говорю. Именно перегибы, именно «бзик» и именно «личный». И до этого никому не было бы дела, если бы лектор не транслировал этот бзик с кафедры технологического университета.

                                                                                              А про сами лекции никто ничего не говорит — они отличные.
                                                                                            0
                                                                                            с точки зрения подачи материала а также целевой аудитории — лучше соврать про проблемы с пятью светодиодами будущему инженеру на профильном семинаре


                                                                                            Немножко соврать..
                                                                                            Наверное, врачу тоже допустимо немножко соврать, и назначить то, за что у него в аптеке откат больше…


                                                                                            Зачем будущему инженеру по микроконтроллерах разбираться в тонкостях старинной демо-платы на старинном контроллере, вот что непонятно.
                                                                                            Почему будущему инженеру любого другого профиля иметь возможность быстро решить свою задачу с помощью недорогой и широко распространенной демо-платы — зашквар?
                                                                                              +1
                                                                                              Почему будущему инженеру любого другого профиля иметь возможность быстро решить свою задачу с помощью недорогой и широко распространенной демо-платы — зашквар?


                                                                                              А почему бы будущему инженеру не уметь решать свои задачи современными средствами?

                                                                                              Откуда вот это «деды на турбопаскале под дос писали — и мы будем»?
                                                                                            +1

                                                                                            Я думаю основная проблема в том, что Ардуино открыло двери в мир эмбеддерства сравнительно большой аудитории программистов и не-программистов, которые мало понимают, чем управление GUI отличается от управления поливом или ШИМ мотором. В прошлом начинающий эмбеддер должен был изучить немало соответствующей литературы и одно только изучение микроконтроллерной периферии и последовательных интерфейсов наталкивало на правильные мысли в стиле "Хмм, а скорость-то тут ограничена" или "А как обеспечить приемлемое время реакции на такое событие, если мне параллельно надо и то и это делать?"


                                                                                            Так как эмбеддерсто, в принципе, опасная штука — одно дело, если такой горе-айтишник сделает свой полив на ардуино, который пропустит свой таймер и зальет теплицу невзначай — ну ладно, случилось один раз, бывает, ущерб небольшой. Но ведь они ж лезут дальше — в умный дом, управляя электричеством, скоро автопилоты на ардуино запустят. И ардуинщики будут доказывать, что софт-реалтайм ничем не хуже обычного… А то, что защитный автомат на ардуино вдруг не сработал вовремя и спалил мотор — ну то такое, либы кривые. Или руки?


                                                                                            По-моему, именно на это хотел намекнуть Олег, заявляя, что со светодиодами будут проблемы. Если хочешь заниматься эмбеддерством серьезно, управляя сложной и зачастую очень дорогой периферией (в десятки и сотни раз дороже самого Ардуино) — Ардуино подход — неправильный. Он дает ложную уверенность, что все просто, когда на самом деле нет. И расплата наступит, только позже.

                                                                                              0
                                                                                              В прошлом начинающий эмбеддер должен был изучить немало соответствующей литературы


                                                                                              Раньше программист должен был знать по именам все регистры в своем процессоре. И машинные коды основных команд. И таблицу прерываний. А сейчас поустанавливают своих фреймворков и жаваскриптов…
                                                                                              ;)

                                                                                              Знание напамять всех управляющих регистров таймера никак не гарантирует, что, например, локальная проблема 2000 не будет организована каким нибудь другим способом.
                                                                                                0
                                                                                                На мой взгляд, посыл lingvo был в том, что порог вхождения был выше. И этот самый порог отсеивал тех, кто не в состоянии был осилить, например, регистры. Как и закон Ома, собственно.
                                                                                                  0

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


                                                                                                  • О, а давайте помигаем пятью различными светодиодами с различными периодами...
                                                                                                  • Берем ардуино, таймеры, пять строк кода и вуаля — мигает!
                                                                                                  • А теперь заменим светодиоды на моторчики от квадрокоптера…
                                                                                                  • … Ой (подбирая отрезанные пальцы), я, кажется, забыл вам рассказать: это софтверная многозадачность с ее очевидными недостатками...

                                                                                                  Сорри за возможно неудачный пример, но то что такого сценария еще не произошло — это чистая случайность. Смысл в том, что начинать изучать эмбеддерство надо немного с другого ракурса… И с Ардуино и без...

                                                                                                  +1
                                                                                                  Я вообще хотел — и сказал — существенно более простую вещь.

                                                                                                  В среде программирования Arduino из коробки тех же нормальных таймеров нет. Это как бы факт, и для 2018 года нашей эры это немного позор.

                                                                                                  И большинство ардуинщиков о том, как эти таймеры сделать — и часто о том, что их вообще можно сделать — не имеют никакого понятия, а меньшинство радостно производит вот такие порождения сна разума, как в этой статье, «а что такого, что у меня весь проект в одном цикле крутится, ну у меня там по-любому задержки обычно не больше десятка миллисекунд».

                                                                                                  Операционные системы, в том числе на микроконтроллерах, в том числе предоставляющие программисту прямо из коробки массу нужны и полезных сервисов, в том числе таймеры, шедулер и IPC, человечество изобрело, мягко говоря, не вчера — и только ардуинщики (что блестяще демонстрирует здесь ТС, подтверждая мои слова) продолжают считать, что весь остальной мир по-прежнему на ассемблере в регистрах ковыряется, чтобы hello world запустить.
                                                                                              +2
                                                                                              Тут уже и без меня всё сказали, но раз меня поминают всуе…

                                                                                              1) Родных средств многозадачности в среде Arduino нет, хотя вообще-то в 2018 году неплохо было бы их иметь (и даже несколько раньше тоже можно было бы). Вообще среда Arduino темпами своего развития напоминает известную картинку про сравнение модельного ряда BMW и Жигулей — за десять лет в ней случилось примерно ничего.

                                                                                              2) Сделать многозадачность руками можно на чём угодно, хоть на ATTiny; на старших атмегах можно и ОСРВ нормальную запустить. Остаётся только вопрос — зачем это делать, и ответ на него можно выразить другой картинкой, про буханку хлеба и троллейбус (и ваша статья в целом этому увлекательному процессу модернизации буханки и посвящена). Ни экономического, ни технического смысла использовать AVR — а тем более, Ардуину — в абсолютном большинстве проектов нет.
                                                                                                0
                                                                                                (посмотрев код) Причём реализация таймеров у вас примерно такого же уровня, что и троллейбус из буханки.

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

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

                                                                                                  Дело в том, что вы высказываете своё пренебрежительное отношение этой технологии, не в кулуарах и не в личной беседе, а с трибуны технического университета, тем самым формируя такое же предвзятое отношение к Ардуино и у студентов.

                                                                                                  Это не значит, что студенты университета должны учиться на Ардуино, но и обвинять Ардуино во всех смертных грехах по делу и без дела тоже не стоит, тем более, что вы выступаете в роли безусловного авторитета для ваших слушателей.
                                                                                                    +1
                                                                                                    Так вы же каждым словом своего поста подтверждаете всё, сказанное мной про ардуину.

                                                                                                    В то время, как в 2018 году любой разработчик на любой нормальной платформе (RIOT, mbed, ChibiOS, FreeRTOS, Contiki...) просто из коробки получает полноценные таймеры с кучей возможностей, вы потратили уйму времени и сил, только чтобы написать кособокое примитивное их подобие.
                                                                                                      –2
                                                                                                      Олег, вы в курсе, что «ардуино» на данный момент это целая индустрия с миллионами людей находящимися в этой сфере и тысячами потрясающих проектов, а так же это обучающая платформа, которая приобщает к микроконтроллерам и техническому творчеству огромное количество людей всех возрастов и профессий?

                                                                                                      Откуда такой снобизм и пренебрежение?
                                                                                                        0
                                                                                                        Во-первых, я так понял, по сути вопроса возражений больше нет.

                                                                                                        Во-вторых, поясните, почему меня должен волновать объём этой индустрии, причём волновать настолько, чтобы я начинал замалчивать её крупные недостатки? Я вроде как сотрудником Arduino AG не являюсь.
                                                                                                          –1
                                                                                                          Вас не волновать, а хотя бы смутно тревожить должен не объём индустрии, а понимание количества людей вовлечённых в эту сферу и той пользы которую Ардуино им приносит.

                                                                                                          И речь идёт не о том, что вы должны что-то замалчивать, а о том, что вы высказываете несправедливые и предвзятые суждения об этой технологии, взять хотя бы вашу цитату из второй лекции, вынесенную в начало статьи о том, что на Ардуино затруднительно мигать пятью светодиодами в независимом режиме — это просто не соответствует действительности — на Ардуино нет никаких проблем с подобным миганием.
                                                                                                            0
                                                                                                            Мы вроде бы уже установили, что суждения мои справедливы и непредвзяты.

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

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

                                                                                                              Где это мы установили?
                                                                                                                +1
                                                                                                                Ну вот же. Нажмите Ctrl-Home.

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

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

                                                                                                                Потому что в том же RIOT мигание светодиодом по таймеру выглядит так:

                                                                                                                #include "xtimer.h"
                                                                                                                xtimer_t timer;

                                                                                                                static void led_toggle(void *arg) {
                                                                                                                gpio_toggle(LED1_GPIO);
                                                                                                                xtimer_set(&timer, LED1_DELAY_US);
                                                                                                                }

                                                                                                                int main() {
                                                                                                                xtimer_init();
                                                                                                                timer.callback = led_toggle;
                                                                                                                xtimer_set(&timer, LED1_DELAY_US);
                                                                                                                }


                                                                                                                И всё. И никакого заката солнца вручную. Никаких «ненормируемых пиковых задержек». Никакого бесконечного цикла.

                                                                                                                А теперь просто представьте, что задача немного усложнилась — и контроллер между переключениями светодиодов должен спать.

                                                                                                                Сколько времени вам на имплементацию этого потребуется?

                                                                                                                Мне примерно секунд тридцать.

                                                                                                                P.S. Кстати, сколько конкретно отсылок к даташиту на STM32 вы видите в приведённом выше коде?
                                                                                                                  0
                                                                                                                  Ну вот же. Нажмите Ctrl-Home.

                                                                                                                  Олег вы передёргиваете, ничего справедливого и не предвзятого по отношению к Ардуино в ваших лекциях нет.

                                                                                                                  Потому что в том же RIOT мигание светодиодом по таймеру выглядит так:

                                                                                                                  Какая религия запрещает на Ардуино обернуть любые таймеры в любую обёртку и использовать мигание светодиодом вообще в одну строку?
                                                                                                                    0
                                                                                                                    Да никакая. Если вам очень хочется закатывать солнце вручную и делать троллейбусы из хлеба — кто ж вам запретит?

                                                                                                                    Просто не надо рассказывать, что это легко и приятно, а вот те, у кого солнце само каждый день за горизонт садится, вот они-то как раз и мучаются.
                                                                                                                      0
                                                                                                                      Это забавно, а о таком прогрессивном явлении, как библиотеки вы слышали?

                                                                                                                      Объясняю как это делается: один раз пишется (простенькая) библиотека, а затем в любой момент в код вставляется одна строка. И да, это на Ардуино тоже работает.
                                                                                                                        0
                                                                                                                        И почему же, если не секрет, вместо десяти страниц текста и этой вашей троллейбусно-булочной самодеятельности вы не сразили меня сразу аргументом с названием этой конкретной библиотеки, вне всякого сомнения, популярной, распространённой и наверняка даже входящей в стандартную поставку?
                                                                                                                          +1
                                                                                                                          Олег, давайте договоримся: когда вы продемонстрируете проект на RIOT OS в котором на 8-битном контроллере с 8-ю КБ памяти в реальном времени функционируют:

                                                                                                                          — Веб-сервер
                                                                                                                          — Сайтовый движок
                                                                                                                          — 8 сайтов, каждый со своим функционалом, дизайном и топологией
                                                                                                                          — С поддержкой честных интерактивных 3D-сцен
                                                                                                                          — Power Monitor-ом на 14 каналов и сетевым осциллографом
                                                                                                                          — Поддержкой nRF24 связи с датчиками и второй распределённой частью
                                                                                                                          — 60-ю датчиками и актуаторами
                                                                                                                          — Dash-панелью работающей в реальном времени
                                                                                                                          — И прочими возможностями, описанными в статье

                                                                                                                          То, обещаю, в тот же день я вам предоставлю эту библиотеку.