Pull to refresh

Comments 292

у него весьма превратное представление об Arduino вообще и об «ардуинщиках» в частности

ну


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

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

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

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

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


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


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

Ну и вместо стражей включения стоит использовать #pragma once, учитывая, что компилятор ее поддерживает, а вопрос переносимости вообще не стоит.
Вы абсолютно правы — код писался с чисто утилитарной точки зрения, чтобы корректно выполнялись требуемые функции и там огромное поле для улучшений и приведения кода к лучшим практикам.
Ха, к сожалению const не всегда применим, и приходиться городить некрасивые #define
Насколько мне известно, если вам нужна просто константа, то у define только одно преимущество — его существование можно проверить через #ifdef. Ну и передефайнить, если вдруг захотелось.
Но тут-то зачем?
А задолго до 2018 года, и даже на C без ++, для целей, как в исходниках в статье, использовался enum
Только в С что enum, что define — одна фигня. Все неявные преобразования происходят молча.
Согласен, но все же лучше использовать вещи по их прямому назначению, а здесь прямо просится enum.
Лично я совершенно механически стриггерился на вот эти дефайны
Заголовок спойлера
#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 пришлось бы каждый раз кастовать к числу (потому что функция, куда эти константы суют, может принимать любое количество миллисекунд, а не только заранее перечисленные здесь).
Да, именно про эти дефайны я и говорил. А дальше, давайте определимся, мы говорим о C или о C++. Если о C, то, как Вы заметили выше «Только в С что enum, что define — одна фигня. Все неявные преобразования происходят молча», если о C++, то можно написать inline функцию, принимающую этот enum, приводящую его к числу, а затем вызывающую одноименную функцию, принимающую число, чтобы каждый раз при вызове не писать reinterpret_cast<>.
Окей, я бы в любом случае переделал бы API. Если есть std::chrono — то пусть функции принимают std::chrono::milliseconds, если chrono нет, то просто сделать несколько функций (или перегрузок), чтобы они принимали только миллисекунды, секунды и миллисекунды, минуты и т.д.

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

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


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

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

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

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

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

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

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

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

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

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

Ну и конечно все будут только приветствовать статью, где автор представит описание своего варианта решения проблемы, подкреплённое работающим публичным проектом с несколькими десятками тысяч строк кода.
Я много раз говорил и ещё раз повторю, что 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;
}

Вот, честно, не считал количество строк кода в дистрибутиве АМС, наверное это суммарно не одна сотня тысяч, а уж на аудит десятка библиотек, используемых в проекте, никаких сил не хватит — для этого нужно создавать специальный отдел. И конечно библиотеки содержат не всегда идеальный код — в этом нет никаких сомнений.
Вот, честно, не считал количество строк кода в дистрибутиве АМС, наверное это суммарно не одна сотня тысяч
Вот результаты 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 эффективных строк.
а уж на аудит десятка библиотек, используемых в проекте, никаких сил не хватит — для этого нужно создавать специальный отдел
Бросить взгляд на чужие исходники, прежде чем тащить их в свой проект — никак нельзя считать проведением полноценного аудита, но это делать просто необходимо, особенно в эмбединге, где ресурсы железа на вес золота.
Затрудняюсь оценить ваш метод подсчёта и что понимается под «эффективными строками», я имел в виду количество строк кода во всех файлах системы. Но сразу бросается в глаза, что при подсчёте вы проигнорировали (если я правильно понял) весь JavaScript и Processing код, содержащийся в htm и pde файлах (в разных папках).

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

Что касается библиотек, то в идеальном мире так и нужно сделать, а ещё лучше написать свои собственные библиотеки, но в реальном мире на это банально не хватает ресурсов.
Затрудняюсь оценить ваш метод подсчёта и что понимается под «эффективными строками»
Это вовсе не «мой» метод, а довольно распространенный метод подсчета метрик кода 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 итого
а ещё лучше написать свои собственные библиотеки
А вот это не факт, т.к. некоторые вещи, например криптографию, не стоит браться писать, не являясь профессионалом в данной области, а, во вторых, как Вы справедливо подметили — «на это банально не хватает ресурсов»
Serge78rus, я ничего не имею против вашего желания подсчитать количество строк в проекте, но если уж это делать, то нельзя игнорировать JavaScript, Processing и CSS код, ведь это (навскидку) две трети кода.
Вы первым заговорили о «сотнях тысяч строк», что крайне мало было похоже на правду, это и сподвигло меня загрузить Ваш проект и прогнать его через sloccount. После этого, уже по Вашему пожеланию, я провел подсчет строк во всех файлах проекта, не разбирая типа файлов, но уже с помощью wc, который, не разбирая содержимого, считает все подряд, будь это строка хоть из единственного символа перевода строки.
Считать ли css программным кодом — вопрос дискуссионный. Я, например считаю, что html — это не код, а контент, а css — разметка, вот JavaScript, безусловно, программный код. Но ведь изначально речь шла о программировании микроконтроллера, а html, css и JavaScript исполняются в браузере, поэтому я их и не учитывал.
Мне как-то приходила мысль посчитать количество строк кода в проекте, но простого и корректного способа я не нашёл, а вручную всё это пересчитывать я посчитал бессмысленной тратой времени, тем более, что интерес был чисто теоретическим, практического смысла в знании числа строк кода я не нашёл.
Что ещё нужно учитывать при подсчёте строк кода АМС: я думаю имеет смысл включить в подсчёт и файлы CSS, поскольку это тоже код, который требует усилий по написанию и поддержке.

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

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

Это лишняя и даже вредная сущность. Вредная — потому, что урезает функционал оригинального 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);
Как говорится: почувствуйте разницу. Обратите внимание, что есть готовые функции работы с целыми блоками данных, а Ардуинщик будет реализовывать их циклами с побитными операциями.

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

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


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

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

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

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

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

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

сработает не так как хочется.
millis() < _start — по идее, таймер остановится.
Конечно остановится, но для решения этой проблемы и предназначены вышеуказанные методы. Сам механизм корректной отработки перехода через «0» для всех «шестерёнок» системы — это тема отдельной статьи.
reStart() и reInit() нужно вызвать в правильный момент. Иначе интервал тика окажется где-то между Т и 2Т.
UFO just landed and posted this here
Реализацию произвольного числа софтовых таймеров в 5 строках в студию!
UFO just landed and posted this here
Аппаратных таймеров в ардуине 3. В STM32, наверное, их бесконечно много. Как вы собираетесь, к примеру, мигать 10 светодиодами с разной частотой без использования костылей типа софтового таймера? В 5 строк, по возможности ;)
UFO just landed and posted this here
Некратных друг другу частот не бывает, это прекрасно.
19, 47, 67 мс.
В 5 строк. ;)
UFO just landed and posted this here
Жаль, я так и не добился примера с хорошим и правильным кодом в 5 строк.
Вот та простыня для ардуины достаточно легко масштабируется на любое разумное количество софтовых таймеров. Да, где необходима точность — так делать не нужно.
Чем ваш вариант (которого вы так и не показали) лучше?
UFO just landed and posted this here
Этот код в произвольный момент времени включит светодиод. Если LED1(ON) это то о чем я подумал.
Ладно, пусть это очипятка.
Простыня из статьи делает совсем другое. Там каждый таймер можно запустить не тогда, когда значение счетчика нацело делится на Х, а когда нужно.
В простыне из математики — только вычитание.
У вас — деление (хз, во что развернет его компилятор).
Походу, у вас от ардуиновского С++ просто подгорает ;)
UFO just landed and posted this here
С чего вы взяли что произвольно то?


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

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

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


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

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

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


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

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

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

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

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


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

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


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


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


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

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


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


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

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


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


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

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

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


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

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


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


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

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


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

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

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


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

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


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

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

Тогда и деление по модулю не сработает
Вы не полностью оценили «прикол», iig писал о мигании 10 диодами в 5 строк кода.
UFO just landed and posted this here
Можно чуть экономичнее (и так и делают): тикать прерыванием каждую миллисекунду не надо, достаточно при очередном срабатывании таймера посмотреть, через сколько следующее событие, и поставить срабатывание на этот момент.

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

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

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

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

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

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

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

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

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

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

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


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

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

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


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

Спасибо, полезная информация.

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


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


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


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


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

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

Но.

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

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

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


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


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

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

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

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

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

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

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

А с тем, чтобы превзойти ардуину по всем показателям разом, проблемы нет вообще никакой.
UFO just landed and posted this here

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

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

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

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

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

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


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


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


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

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

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


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


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

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


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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Где это мы установили?
Ну вот же. Нажмите 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 вы видите в приведённом выше коде?
Ну вот же. Нажмите Ctrl-Home.

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

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

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

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

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

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

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

P.S. Если не секрет, а зачем это всё делать на 8-битном контроллере с 8 КБ памяти, кроме как из желания очистить душу страданиями?

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

Олег, вы это серьёзно? Написание такой библиотеки это детская задачка для начинающего ардуинщика.

А вот аналога описанного мной функционала или хотя бы чего-то похожего, сделанного на RIOT OS мы от вас никогда не дождёмся (даже в теории).
Написание такой библиотеки это детская задачка для начинающего ардуинщика


И при этом готовой библиотеки, в которой она бы решалась, нет. Всё чудесатее и чудесатее.

Может быть, это потому, что вы немножко путаете? Детская задача — это написание того, чем вы с уважаемой публикой поделились. Ну, где «требует специальной оптимизации кода под конкретную задачу» и прочая бессмысленная порнография.

А написание нормальной подсистемы таймеров — задача несколько более серьёзная. Вы к ней пока даже не приступали.

А вот аналога описанного мной функционала или хотя бы чего-то похожего, сделанного на RIOT OS мы от вас никогда не дождёмся (даже в теории).


Было бы удивительно ожидать иного — на кой чёрт мне это делать?
Break!

Ок, подведу итог встречи под девизом «Нео сражается с Морфиусом» :)

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

Победила дружба! (Я думаю продолжать нет смысла)

Я так думаю, если "нормальной" системы таймеров в понимании одного участника нет, может, именно такая система никому не нужна. Что ненормального в предложенном троллейбусе, который за час пишется? А если не упаковываться оформлять как класс (не нужно если N таймеров, достаточно 2) — ещё быстрее.
Магия STM32 выглядит прельстиво, но без документации это просто колдунство. Какая точность у этого решения, будет ли оно с чем-то конфликтовать… Если тупо скопировать тот код — чем это лучше подхода "ардуинщика", налабавшего свой велосипед из delay()?

Не порите чушь, ей больно.

Ровно тем же путём вы можете придти к выводу, что отладчик никому не нужен, прерывания никому не нужны, разделение проекта на файлы исходников и заголовочные никому не нужно, лучшая скорость UART — это 9600 бит/с, энергосбережение никому не нужно, etc.

Что ненормального в предложенном троллейбусе, который за час пишется?


Вы издеваетесь, что ли?

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

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

Олег, очень не хочется затевать очередной холивар, потому, что к единому мнению мы не придём, замечу только:

1. никто не говорит, что предложенное решение идеально и лучше других — но это рабочее и проверенное решение на платформе Ардуино.

2. ТТХ этого решения достаточно для решения 95% практических задач «простых людей», там, где требуется жёсткое реальное время никто не предлагает использовать его.

3. Ардуино — это не ущербная и не устаревшая платформа, а ПО ФАКТУ (нравится нам это или нет) инструмент, используемый миллионами людей. И игнорирование этого факта это ничто иное, как узколобый снобизм.

Судя по вашим высказываниям у вас особые проблемы с пониманием пункта 3
Послушайте, предложенное вами решение — это изобретённый вами велосипед, причём с деревянными квадратными колёсами.

Человечество же давно уже серийно производит велосипеды, у которых колёса круглые, с металлическими спицами, надувной камерой и покрышками с красивым рисунком.

То, что на вашей любимой платформе таких велосипедов не бывает, поэтому миллионы людей с грохотом переваливаются на поделках типа вашей, ни разу не говорит в её пользу.
Конечно! Полностью согласен с тем, что это не говорит в её пользу. И я нигде не утверждал, что это передовое техническое решение. Это всего лишь реально работающее решение «здесь и сейчас».

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


А почему вы так упорно не хотите вместо уродливых костылей «здесь и сейчас» использовать нормальные решения?

в том числе и обучающая платформа


Вот это-то и страшно — что вы ещё и обучать кого-то там хотите на примере кода качества «я сделяль».

Это принципиально Ардуино-based проект


Да хотя бы и в вашей ардуино нормальное решение вам сделать какая религия мешает? У вас же даже все средства для этого есть.

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

К тому же, это не отвечает на вопрос, почему нельзя сразу использовать нормальные решения, которые человечество придумало, когда вашего проекта даже в мечтах ещё не было.
Олег, здесь есть два различных аспекта: внутренняя кухня («шестерёнки») системы и её рабочий функционал. Вы в своём рассмотрении всё внимание уделяете «шестерёнкам», забывая о том, что несмотря на их текущее несовершенство, сама система прекрасно и стабильно функционирует, что подтверждено более 20 000 скачиваний дистрибутивов для десятка платформ от Меги до ESP32 и подтверждёнными аптаймами во многие месяцы беспроблемной работы во многих DIY проектах.
Дендрофекальные технологии вообще часто оправдывают тем, что ну а люди же пользуются, людям же нравится, значит, и палки не так уж торчат, и связующее не так уж пахнет.

Но вы идёте чуть дальше — вы ещё и студентов им научить требуете.
Но вы идёте чуть дальше — вы ещё и студентов им научить требуете.

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


И вот это избавление в вашем представлении и происходит на примере наколенного творения с деревянными квадратными колёсами.

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

отладчик никому не нужен, прерывания никому не нужны..


Arduino — это AtMega. В ней есть и прерывания, и аппаратные таймеры (1 занят миллисекундным счетчиком, да.).

… энергосбережение никому не нужно..
Кому это нужно, тот знает, что делать. ;)
Почему придумал?

В Ардуине нет пристойных таймеров — вы утверждаете, что это потому, что они никому не нужны.

Теперь рассмотрите в этом же свете тот факт, что в ардуине нет отладчика, нет поддержки режимов энергосбережения, куча библиотек с говнокодом, рассчитанным исключительно на работу в бесконечном цикле, а весь проект делается одной бесконечной простынёй кода.
Опять…
В Ардуине нет пристойных таймеров

Чтобы помигать 5 лампочками — и непристойных таймеров хватает. В 95% случаев этого достаточно.

в ардуине нет отладчика нет поддержки режимов энергосбережения

У всех свои недостатки. На велосипеде, например, зимой ездить неудобно. Поэтому большинство зимой на велосипеде не ездит. Но некоторые — ездят и зимой. Можно рассказать им, как они страдают, и воще удобнее работать из дома, и все их проблемы от мяса. ;)

куча библиотек с говнокодом

Это кроссплатформенное. Могу сказать разве, что то, что мне попадалось — оно просто работает. Качество оценивать не пытался.

весь проект делается одной бесконечной простынёй кода

То есть если ардуинщик разделит свою простыню на несколько файлов, каждый класс отдельно, да еще и положит в git, то его, может быть, не сожгут на костре. :)
Чтобы помигать 5 лампочками — и непристойных таймеров хватает. В 95% случаев этого достаточно.


Вы продолжаете оправдывать убогий говнокод тем, что «ну ведь обычно работает же».

Много что «обычно работает». Скрутка алюминиевого провода с медным «обычно работает». Жучок вместо предохранителя «обычно работает». Езда с непристёгнутым ремнём «обычно работает».

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


Все это явное нарушение правил монтажа, эксплуатации и движения.
А вот какие правила разработки ПО нарушает софтовый (раз он срабатывает не от аппаратного прерывания) таймер? Я вижу только переполнение на 49 сутки в этой вот реализации. Тот, кому это критично — знает что делать.
То есть тот факт, что это таймер с негарантированным срабатыванием, вас не напрягает?..

Ну, ок.
таймер с негарантированным срабатыванием

Что понимать под термином «негарантированное срабатывание»? Может сработать на ${время выполнения 1 цикла программы} позже? Ок, я в курсе. У меня есть калькулятор, я могу оценить, насколько критично это, что включится насос на 10 мс позже.
Может не сработать? Почему?
То и понимать.

Не только период, но сам факт срабатывания этого таймера зависит от кода, функционально с таймером никак не связанного. Переклинило у вас что-нибудь в loop() — и всё, привет.

И с чего вы взяли, что насос включится позже на 10 мс, а не на 10 с? В ардуине уже появились средства для профилирования всего, что ей в loop() накидали?
Переклинило у вас что-нибудь в loop() — и всё, привет.


Переклинило у вас где-нибудь в обработчике прерывания… все, привет.
Не нужно делать так, чтобы переклинивало.

В ардуине уже появились средства для профилирования всего, что ей в loop() накидали?

В loop() кидает программист. Если он не знает, чего он накидал
В loop() кидает программист. Если он не знает, чего он накидал…


Я правильно сейчас понял, что и вы, и топикстартер делаете code review и проверку реакции на внешние отказы для всех сторонних библиотек, которые в ваших проектах в loop() напиханы?

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

Если программист не проверяет, что он импортирует… Даже changelog не читает… И результат никто не тестирует… И это явно прописано в Arduino CodeStyle Guide
… :)
Или не все так плохо?

Нет. ATMega — это ATMega. Микроконтроллер такой. В настоящее время довольно бессмысленный ввиду крайне унылого сочетания цена/возможности.

А Ардуино — это набор плат и среда разработки, созданная в 2003 году на уровне 1993 года, да так на нём и оставшаяся.

Извините, что вмешиваюсь в вашу дискуссию, но я так понял, что автор статьи прикрутил таймеры ради многозадачности, а не ради самих таймеров. Просто с помощью них на Ардуине данная задача решается проще, хоть и не сильно правильно. Так можно сделать и на любой другой платформе без ОСРВ.
С другой стороны при использовании ОСРВ или более высокого уровня абстракции, например IEC 61131-3, для многозадачности таймеры изучать вообще не нужно. Причем эта многозадачность уже получается правильная по всем какнонам эмбеддерства.

Нннуу, можно так сказать, но это такая многозадачность, условно съедобная. Маленький кусочек от настоящей многозадачности.

Меня в авторе другое смущает: зачем он продолжает утверждать, что вот этот закат солнца вручную — это хорошо, правильно и вообще кому-то реально нужно, когда простым уходом на любую современную ОСРВ все эти проблемы решаются сразу и сильно лучше.
Катать имеет смысл, когда ОСРВ в имеющиеся ресурсы не влезает. Attiny и маленькие PICи всё-таки умирать не собираются.
Ну да, ATTiny/PIC/STM8 хорошо чувствуют себя в мелких прикладных задачах, когда надо, например, корпус минимального размера, ну или себестоимость до последнего цента оптимизировать. И пишут под такие задачи на голом C.

Но топикстартер-то аж целый мегасервер ваяет. И делает это зачем-то на AVR в ардуине, хотя на Cortex-M с ОСРВ было бы не только на порядок удобнее и быстрее, но в общем даже и дешевле (ATMega2560 не совсем копейки стоит).
Дык пусть ваяет, мне его способ не нравится, а идея вполне жизнеспособна. На меге\стм8 можно использовать планировщик или игрушечную ОС (собственно, они уже есть, достаточно скачать), а потом наворачивать задачи, пока хватит тактов и памяти, вот только 95%, что писать придётся на чистом С, асм или форте. Наверняка, если чудовищно извернуться с мультиплексированием, то и на тиньке решить поставленную задачу можно, но, если не идти на принцип, я бы взял маленький Cortex, например, М0, и использовал FreeRTOS, даже дешевле и быстрее выйдет.
Лично мне в ардуинщиках не нравится, что они выкидывают кучу готовых наработок на любую тактовую частоту и память, делая вид будто до появления на плате ардуино подобного МК не существовало.

Не знаю, но могу предположить разные варианты:


  • ОСРВ может противоречить концепции построения Arduiono IDE — т.е требует переделки библиотек и всего кода. А иначе все, что сделано сейчас, с ОСРВ просто не совместимо. Вот и придумывают такие реализации многозадачности.
  • Возможно прайсовая политика на платы Ардуино не приветствует расточительство ресурсами, необходимое для ОСРВ. Я замечал несправедливость на рынке МК, когда 32-ух битный кортекс с 512кб флеши стоил дешевли 8-и битки с 16-ю кб. Так что тут надо смотреть — возможно Ардуино АГ или как их там, зарабатывают на платах, а пользователи мучаются.
1) Это не так. Более того, для ардуины есть ОСРВ — библиотека с FreeRTOS, так что проблема не в ОСРВ, проблема в том, что среда все десять лет своего существования тупо не развивалась никак вообще.

2) Arduino AG вне всякого сомнения зарабатывает на платах, и пока они продаются — запредельная убогость среды разработки их волнует крайне мало.

1) я не имел ввиду, что ОСРВ нельзя портировать на Ардуино. Я не сомневаюсь, что уже сейчас есть куча работающих вариаций. Я имел ввиду, что Ардуино коммьюнити уже наработало кучу кода и библиотек, которые с радостью используются и переиспользуются, но эти библиотеки никак не совместимы с портированными ОСРВ, хотя бы потому, что общаются с периферией напрямую в монопольных режимах. В итоге у ардуинщика достаточно сложный выбор — либо использовать любимую библиотеку, но без ОСРВ, либо ОСРВ, но остаться без библиотеки(что многих очень страшит). В итоге большинство выбирает первое и появляются такие реализации.


По 2) — я имел ввиду, что прайсовая политика на платы такая, что плата на 8-и битном контроллере с 16кб флеши стоит, например, один доллар, а на 32-х битном с 512кб — 10, хотя контроллеры сами по себе могут стоить одинаково. Ардуино зарабатывает, а пользователи вынуждены себя ограничивать.

1) Это всё легко решается, если бы у кого-либо из этой прекрасной среды было бы желание решать. А там, как демонстрирует топикстартер, нет не только желания, но даже понимания, нафига — ну ведь и так работает же как-то.

2) Нет, это не так. У них костяк составляют платы на AVR, а ради больших денег идут платы с внешними довесками — Wi-Fi, LoRa и т.п. Платы с Cortex-M пошли плохо, ибо ввиду убогости программной среды никаких особых преимуществ не предоставляли, кроме тупо более высокой тактовой частоты.

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


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

Ардуина хороша тем, что чтобы проверить идею, не надо ЛУТить. Ардуина, пара деталей навесом — появляется ясность. Сгорело — берём из ящика ещё одну ардуину. Но программировать Ардуино надо с первого для в Atmel Studio, родную IDE даже не стартовать, ардуинщиковые библиотеки не скачивать.
У нас с той же целью в офисе лежит стопка Nucleo на полудюжине разных чипов и полстопки LaunchPad'ов.

Вообще отладки примерно на чём угодно давно перестали быть редкостью.
Ардуино здорово снизила порог вхождения. Многих отталкивает необходимость ставить навороченную IDE, собирать или покупать плату с обвязкой, искать программатор, разбираться с настройкой и подключением — для программирования голого контроллера всё это предшествует попытке собственно запрограммировать что-нибудь. Ардуино — берешь плату, подключаешь шнурок, ставишь простую оболочку и вперед. Для новичков часто даже установка драйвера для USB шнурка становится проблемой.
Ещё нюанс — ей могут пользоваться как программисты, не работавшие раньше с железом, так и электроники, не умеющие программировать. После повторения чужого проекта они вполне могут заинтересоваться, переделать программу под свои нужды… смотришь — уже библиотеки правят и свои модули паяют. Не попробовав, они просто не смогли бы пойти дальше.
На счет таймеров, далеко не всегда нужны точные интервалы времени и работа по прерываниям. Я работаю с ПЛК, в них тоже обычно крутится бесконечный цикл: прочитал состояние входов, обработал, выставил состояние выходов. Прерывания только там, где они реально нужны (сигналы с энкодеров и т.п.), в остальном время цикла может составлять десятки, а то и сотни миллисекунд. Всё зависит от задачи, на сложном оборудовании крутится например Simatic, а что-то относительно простое вполне можно собрать на LOGO!
Моё мнение — Ардуино это не совсем про эмбеддинг, скорее такой любительский ПЛК. Отлично подойдет для ознакомления, создания прототипов устройств, можно что-то не сильно критичное на нём собрать вроде системы сбора информации с датчиков. Формат, интерфейс подключения стандартизированы, есть платы на разную производительность и количество выходов, дополнительные модули, библиотеки. Софт не перегружен лишними функциями, но под капотом обычный Си — всегда можно выбрать, насколько глубоко в него залезать. Ещё прикрутить промышленные графические языки программирования (LAD, FBD), добавить нормальные входы/выходы и можно ставить на дин-рейку, будет вполне реальный конкурент тому же LOGO! (у которого, к слову, только пару лет назад появилась возможность выделять повторяющиеся блоки в модули-подпрограммы).
электроники, не умеющие программировать
«Электроник» — это про «робота-мальчика» из советской фантастики. В русском языке принято говорить «электронщики» (совет вам на будущее, перед высказыванием в теме, в которой вы не «комильфо»).
В квалификационном справочнике написано Инженер-электроник. В дипломе должно быть тоже так.
У меня в трудовой написано «инженер-электроник». Но за совет спасибо.
Автор, а я правильно понял из косого взгляда в ваш мегакод, что в Arduino Mega Server

1) таймеры и «многозадачность» полностью вырубаются при любом затыке в loop()
2) watchdog по обстоятельствам религиозного характера вы не используете

?

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

int goLight = 0;

void keysWorks() {
if (goLight == 1) {
digitalWrite(KEY_PIN, LOW);
} else {
digitalWrite(KEY_PIN, HIGH);
}
}
Индусятина.
Но индийский код тоже работает. и не только в ардуине.
Во всяком случае, нет тут ничего блокирующего.
Я был бы крайне удивлён, если бы автору удалось в трёх строчках if-else сделать что-то блокирующее. Это бы тянуло если не на памятник, то на памятную табличку точно.
Олег, ваш менторский тон неуместен, я не ваш студент, а вы не пуп земли. В следующий раз, когда захотите получить ответ потрудитесь задать вопрос простым человеческим языком. Но тем не менее я отвечу на ваш вопрос.

Watchdog в АМС используется внешний по многим причинам, например, в Arduino Mega 2560 есть проблемы со встроенным watchdog-ом и он при некоторых условиях может срабатывать некорректно.

И прошу вас не начинать ещё одну километровую ветку пререканий — у меня нет никакого желания этим заниматься.
Рискну предположить, что вы просто не умеете им корректно пользоваться.

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

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

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

Что касается вачдога на ATMega2560. У меня складывается впечатление, что вы, Олег, очень одинокий человек, в том смысле, что на Олимпе, на котором вы находитесь, вам уже давно не встречался человек который может вам аргументированно возразить и поставить вас на место.

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

Так что, Олег, мой вам совет: снимите корону (она вам только мешает) и относитесь к людям попроще, а на вопросы смотрите поширше.
вы имеете дело с достойным оппонентом


Я просто оставлю здесь ваш код.

/* ----------------------------------------
Function addFN(char c)
Add char to FileName and move old chars
TODO: rewrite function with cycle
------------------------------------------- */

void addFN(char c) {
fn[19] = fn[18];
fn[18] = fn[17];
fn[17] = fn[16];
fn[16] = fn[15];
fn[15] = fn[14];
fn[14] = fn[13];
fn[13] = fn[12];
fn[12] = fn[11];
fn[11] = fn[10];
fn[10] = fn[9];
fn[9] = fn[8];
fn[8] = fn[7];
fn[7] = fn[6];
fn[6] = fn[5];
fn[5] = fn[4];
fn[4] = fn[3];
fn[3] = fn[2];
fn[2] = fn[1];
fn[1] = fn[0];
fn[0] = c;
}
[electro_pm.ino:165]: (error) Array 'middleUPrms[2]' accessed at index 2, which is out of bounds.
[electro_pm.ino:166]: (error) Array 'middleUPrms[2]' accessed at index 3, which is out of bounds.
[electro_pm.ino:166]: (error) Array 'middleUPrms[2]' accessed at index 4, which is out of bounds.
[electro_pm.ino:167]: (error) Array 'middleUPrms[2]' accessed at index 5, which is out of bounds.
[electro_pm.ino:167]: (error) Array 'middleUPrms[2]' accessed at index 6, which is out of bounds.
[electro_pm.ino:168]: (error) Array 'middleUPrms[2]' accessed at index 7, which is out of bounds.
[electro_pm.ino:168]: (error) Array 'middleUPrms[2]' accessed at index 8, which is out of bounds.
[electro_pm.ino:169]: (error) Array 'middleUPrms[2]' accessed at index 9, which is out of bounds.
[electro_pm.ino:169]: (error) Array 'middleUPrms[2]' accessed at index 10, which is out of bounds.
[electro_pm.ino:170]: (error) Array 'middleUPrms[2]' accessed at index 11, which is out of bounds.
[electro_pm.ino:170]: (error) Array 'middleUPrms[2]' accessed at index 12, which is out of bounds.
[electro_pm.ino:171]: (error) Array 'middleUPrms[2]' accessed at index 13, which is out of bounds.
[electro_pm.ino:165]: (error) Array 'UPrms_[2]' accessed at index 2, which is out of bounds.
[electro_pm.ino:166]: (error) Array 'UPrms_[2]' accessed at index 3, which is out of bounds.
[electro_pm.ino:166]: (error) Array 'UPrms_[2]' accessed at index 4, which is out of bounds.
[electro_pm.ino:167]: (error) Array 'UPrms_[2]' accessed at index 5, which is out of bounds.
[electro_pm.ino:167]: (error) Array 'UPrms_[2]' accessed at index 6, which is out of bounds.
[electro_pm.ino:168]: (error) Array 'UPrms_[2]' accessed at index 7, which is out of bounds.
[electro_pm.ino:168]: (error) Array 'UPrms_[2]' accessed at index 8, which is out of bounds.
[electro_pm.ino:169]: (error) Array 'UPrms_[2]' accessed at index 9, which is out of bounds.
[electro_pm.ino:169]: (error) Array 'UPrms_[2]' accessed at index 10, which is out of bounds.
[electro_pm.ino:170]: (error) Array 'UPrms_[2]' accessed at index 11, which is out of bounds.
[electro_pm.ino:170]: (error) Array 'UPrms_[2]' accessed at index 12, which is out of bounds.
[electro_pm.ino:171]: (error) Array 'UPrms_[2]' accessed at index 13, which is out of bounds.


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

#define MAX_UI_SENSORS 14 // max 14


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

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

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

А теперь просто встаньте перед зеркалом и повторяйте вслух «мне сложно с первой попытки написать цикл на С», пока до вас не дойдёт.

P.S. Про «сложный модуль» upload.ino, примерно целиком состоящий из if'ов в три-пять строчек, даже комментировать смешно.
Нет, Олег, это именно остервенение человека, которому указали, что корона у него на голове съехала набок.
Но вам-то сложно с первой попытки написать цикл на С.
Олег, дорогой мой, ваши попытки меня уесть с помощью копания в legacy-коде двухгодичной давности просто жалки — не позорьтесь. Вы задеты и уязвлены потому, что не привыкли, чтобы вам указывали на ваши ляпы и, как следствие, ваша реакция крайне предвзята.
Но вам-то сложно с первой попытки написать цикл на С.
Я думаю снова Break! (продолжать нет смысла)
Если имеете дело с массивами — используйте sizeof(). И sizeof(array)/sizeof(array[0]). И не будет таких ошибок.
Если имеете дело с массивами — используйте sizeof(). И sizeof(array)/sizeof(array[0]). И не будет таких ошибок.

Про это я естественно знаю и использую. Тут же дело в том, что этот многострадальный модуль был написан ещё за 3 года до появления АМС, т. е. 5 лет назад и работал в жёстко детерминированной системе в конфигурации 1/13.

Там не предусматривалось никаких изменений по каналам, поэтому и код такой. Потом модуль был интегрирован в АМС тоже в жёсткой конфигурации 1/13, а уже потом… я решил добавить возможность изменять количество каналов, а про отправку данных MajorDoMo просто забыл, потому, что к тому времени уже не использовал её.

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

Человек с руками из плеч такого просто никогда не напишет.
Простите
/** The Constant NUMBER_3. */
public static final int NUMBER_3 = 3;
/** The Constant NUMBER_4. */
public static final int NUMBER_4 = 4;
/** The Constant NUMBER_5. */
public static final int NUMBER_5 = 5;
/** The Constant NUMBER_6. */
public static final int NUMBER_6 = 6;
/** The Constant NUMBER_6. */
public static final int NUMBER_7 = 7;

Насяльника обещала всех уволитьма за это…

(классика с ithappens)
Я тут реальный драйвер один портировал. Был в немом восторге — всё, что вы не хотели знать о магических числах:

if (rev == 4)
{
    temp_u8 = 0x09;
    FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8);
    error = fpc1020_reg_access(fpc1020, &reg);
    if (error)
        goto out;

    temp_u64 = 0x0808080814141414;
    FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64);
    error = fpc1020_reg_access(fpc1020, &reg);
    if (error)
        goto out;
}
else if (rev == 3)
{
    temp_u64 = 0x1717171723232323;
    FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64);
    error = fpc1020_reg_access(fpc1020, &reg);
    if (error)
        goto out;

    temp_u8 = 0x0f;
    FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_RST_DLY, &temp_u8);
    error = fpc1020_reg_access(fpc1020, &reg);
    if (error)
        goto out;

    temp_u8 = 0x18;
    FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8);
    error = fpc1020_reg_access(fpc1020, &reg);
    if (error)
        goto out;
}
В экспериментальной ветке потокового декодера эта функция давно переписана в виде:

void addFN(char c) {
  for (int i = MAX_FN_BUFFER - 1; i > 0; i--) {
    fn[i] = fn[i - 1];
  }
  fn[0] = c;
}


в основной ветке код остался старым потому, что модуль сложный и легче его заменить целиком после отладки экспериментальной ветки, чем улучшать каждую функцию в отдельности.
«Улучшать».

Боже, да этот цикл написать — быстрее, чем те портянки, что вы производите.
void addFN(char c) {
  for (int i = sizeof(fn)/sizeof(fn[0]) - 1; i > 0; i--) {
    fn[i] = fn[i - 1];
  }
  fn[0] = c;
}


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


Конкретнее. Название документа, номер страницы.

37.7 ATmega2560 rev. F
• ADC differential input amplification by 46dB (200x) not functional

37.8 ATmega2560 rev. E
No known errata.

37.9 ATmega2560 rev. D
Not sampled.

37.10 ATmega2560 rev. C
• High current consumption in sleep mode

37.11 ATmega2560 rev. B
Not sampled.

37.12 ATmega2560 rev. A
• Non-Read-While-Write area of flash not functional
• Part does not work under 2.4 volts
• Incorrect ADC reading in differential mode
• Internal ADC reference has too low value
• IN/OUT instructions may be executed twice when Stack is in external RAM
• EEPROM read from application code does not work in Lock Bit Mode 3
«Производитель» в данном случае — это Arduino, умудрившееся сломать watchdog прямо в бутлоадере, как-то так:

habr.com/post/189744

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

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

Но ведь по коду видно, что не удастся легко управлять сотнями различных сущностей. Архитектура вашего Mega Server — event-loop, что конечно весьма распространено от различных библиотек и ОС для MCU, так и до сервисов на базе libevent и т. д. Только непременным атрибутом такого подхода является асинхронный ввод/вывод, отсутствие блокировок и интенсивных вычисления. И вот тут Arduino и как аппаратная платформа, так и програмная только вставляет палки в колёса. У ATmega нет ни DMA, ни нормально FIFO для периферии. Заглянешь в библиотеку с реализацией 1-wire — две задержки на 500 и 400 мкс. Вот и выходит, что с вашей библиотекой софтовых таймеров не поморгаешь светодиодом на 1 кГц в параллель с обработкой данных от сенсора температуры. А уж про сотни сущностей и говорить не приходится.

Вот и выходит, что с вашей библиотекой софтовых таймеров не поморгаешь светодиодом на 1 кГц в параллель с обработкой данных от сенсора температуры.

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

Во вторых, 1-wire датчики температуры имеют вполне приемлемый режим с дельтой 0,25 С и задержкой 190 мс и даже 96 мс при дельте 0,5 С, что во многих случаях тоже приемлемо.

И да, вы правы, мигать быстрее этих 96 мс не получится, но при скважности задержки 96 мс в 5 минут (типичное время замера температуры) на реальных задачах это особой роли не играет потому, что 99,(9) процентов времени в системе остаются типовые задержки в районе 10 мс.

Если нужен жёсткий реалтайм, то конечно это решение не подходит.

А уж про сотни сущностей и говорить не приходится.

Просто скачайте дистрибутив и ознакомьтесь с его работой.
на реальных задачах это особой роли не играет потому, что 99,(9) процентов времени в системе остаются типовые задержки в районе 10 мс.

Словосочетание "реальные задачи" весьма расплывчато. 99,(9) процентов у вас не выйдет. В вашем коде читаются последовательно три датчика. 300 мс. опрашивать датчики, на мой взгляд это уже перебор даже без требований жесткого реалтайма. За такое время можно прозевать кучу важных событий.


Просто скачайте дистрибутив и ознакомьтесь с его работой.

Скачал дистрибутив. Ознакомиться с работой не смог, но код поглядел. Моё впечатление схоже с приведенными выше — типичный Arduino-style. Вы реализуете кооперативную многозадачность, при этом выполняете блокирующие операции на непотребное время. Приводите как пример Mega Server работающий годами, но код содержит явные ошибки (Да-да, обращение за границу массива в модуле electro_pm.ino). У gcc есть опции -Wall и -Werror, поклонники Arduino о них не знают? Работа годами — это из разряда чуда, а не умелого применения.
После этого трудно не согласиться с Олегом Артомоновым, что студентам профильных ВУЗов стоит держаться подальше от Arduino, пока они не изучат основы на базе более зрелых RTOS. Arduino идеально для всяких простых "скетчей" и имеет свою целевую аудиторию, но в ВУЗе для будующих профессионалов в данной области — это как программирование на соответсвующих специальностях изучать используя Лого Миры с черепашкой.

В вашем коде читаются последовательно три датчика. 300 мс.

Откуда вы взяли цифру 300 мс? Вы её измеряли или вывели из чего-то?

Невнимательно поглядел, там таки команда сразу всем датчикам по шине выдаётся.

с вашей библиотекой софтовых таймеров не поморгаешь светодиодом на 1 кГц в параллель с обработкой данных от сенсора температуры


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

А таймер на миллисекундном счетчике для интервалов в 500 мксек не годится никакой.

Да, мой пример в данном случае некорректен. Но с использованием готовой библиотеки Arduino для этого датчика и Mega Server, даже 50 мс. для других задач не получить.

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


Да. Надо просто запомнить про этот недостаток. Где тайминги критичны — не использовать, или использовать с умом.
Где временные интервалы значительно больше секунды (теплица — отличный пример) — использовать или нет — дело вкуса/религии.
А почему конкретно нельзя просто изначально использовать нормальные решения?..
это вы сейчас спрашиваете у дачников-огородников со школьниками или у студентов и выпускников инженерно-электротехнических факультетов?
У собравшихся здесь профессионалов, чей проект скачали более 20 тысяч раз, кхе-кхе.
а что не так? профессионалы-дачники хвастаются своим поливом. Не удивительно, что 20 тысяч таких же дачников захотели им воспользоваться.
Ну я б и полив немного иначе бы сделал, пока клубника мимо не проплыла. Хотя какой из меня дачник, я туда только шашлык жрать езжу.
Не факт, что все 20 тысяч скачивали с целью реального применения. Я, например, дважды скачал в попытках доказать ТС, что в его проекте вовсе нет «сотен тысяч строк кода»
Естественно, далеко не все кто скачивал устанавливали и работают с АМС, просто объективно оценить количество работающих систем мы не можем (поскольку они не шлют нам никакую телеметрию), объективно нам доступны только данные о скачивании, поэтому они и указываются.

У каждого свой критерий нормальности. Когда-то нормальным считалось мигать светодиодом с помощью генератора на 2 транзисторах. Сейчас без 80 МГц, 512 флеша и RTOS никак не обойтись. Хотя лампочки те же, и клубника та же.

Тут, конечно, у кого как, а у меня RTOS спокойно живёт на STM32F030F4P6 за 35 рублей.
UFO just landed and posted this here
Читаю я ваши комментарии и удивляюсь: вы на лету точно схватываете все тонкие нюансы, которые до народа обычно не доходят даже после усердных объяснений. Любопытно, если не секрет, какой у вас опыт разработки и интересы в микроконтроллерной области?
Just for fun.
В институте когда-то 8048 учили. С тех пор мигать лампочкой появилась масса новых способов. ;)
Приятно иметь дело с умным человеком.
Sign up to leave a comment.

Articles