Comments 292
у него весьма превратное представление об Arduino вообще и об «ардуинщиках» в частности
ну
Мигание пятью светодиодами
организуется многозадачность
После такого — естественно оно будет превратным.
Но не
для студентов МИРЭА, как будущих инженеров микропроцессорных систем
Пример xakep.ru/2018/04/13/hack-aigo-hdd
Там человек квалификации совершенно космической (действительно крутой дядя), но додумался для снятия дампа взять ардуино-код.
3. Подождать заданный промежуток времени, учитывая следующие подводные камни:
я убил уйму времени, пока не узнал, что, оказывается,
работает корректно только с задержками, не превышающими 16 383 мкс;
• delayMicroseconds
и затем снова убил столько же времени, пока не обнаружил, что delayMicroseconds,
если ей на вход передать 0, работает совершенно
неправильно!
Этот код выполняется по десять раз за одну микросекунду. 0xF1 сюда включен, поскольку был единственным регистром, который менялся при вычислении контрольной суммы. Воз можно, это какая‐то временная переменная,
используемая арифметико‐логическим устройством. Обрати внимание
на уродливый хак, которым я перезагружаю Arduino, используя picocom, когда
Arduino перестает подавать признаки жизни (понятия не имею почему).
Ну и вместо стражей включения стоит использовать #pragma once, учитывая, что компилятор ее поддерживает, а вопрос переносимости вообще не стоит.
#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 пришлось бы каждый раз кастовать к числу (потому что функция, куда эти константы суют, может принимать любое количество миллисекунд, а не только заранее перечисленные здесь).
Enum, на мой взгляд, должны использоваться, когда все допустимые значения можно заранее перечислить — это ведь перечислимый тип. Тут же константами сделаны только какие-то заранее определенные величины, которые просто автору понравились, но допустимые значения ими не ограничиваются.
И если пользователю захочется задать интервал например, в 4 минуты (для которых константы нет), то ему придется руками писать 4*60*1000, что, на мой взгляд, выглядит плохо и непонятно.
Но все, что выше, я писал применительно к эмбедингу, если бы писал для ПК, то ориентировался бы на std::chrono.
Ладно, спор явно пошел о вкусах, но лично мне вызов
myCycle cycle(MS_01*2*60*60*1000, true);
кажется менее понятным, чем myCycle cycle( 2_h, 0_min, 0_sec, 0_msec, true);
Ну и переопределять операторы для enum, так чтобы выходить за пределы этого самого enum'a по-моему фе.
В остальном я бы согласился со всеми Вашими рассуждениями, если бы речь шла не об эмбединге, т.к. считаю, что при финальной оптимизации тик таймера с достаточно большой вероятностью увеличится, хотелось бы при этом ограничиться изменением в одном месте.
Это позволило бы в дальнейшем безболезненно изменить этот квант, естественно, отвязавшись от Ардуиновского millis()
Это — совершенно лишняя абстракция. Накладные расходы на неё заметны, а понадобится она скорее всего никогда (точнее, к тому времени вы успеете переписать весь код с нуля несколько раз). Пример нормального решения — функции sleep(), usleep(), nanosleep(), у которых кванты, соответственно, секунда, микросекунда, наносекунда — выбирайте нужное, а если сомневаетесь, то используйте последний так как он заведомо покрывает все варианты. Для измерения интервалов меньше наносекунды всё равно потребуется принципиально другой подход (и, вероятно, полностью другая платформа), поэтому встраивать их теоретическую поддержку опять же незачем.
Ну и можете считать что таймер — это асинхронная функция задержки.
Чтобы не хотел сказать автор, но данная статья подтверждает слова лектора о том, что для реализации многозадачности нужно быть немного больше, чем простым "ардуинщиком" — по крайней мере знать, что такое таймеры и уметь их применять. Вот если бы вообще без таймеров — вот это был бы уровень для ардуино.
Посыл был в том, что требуется знать и применять такую штуку, как таймеры. Понимать, что такое их переполнение, перезагрузка. Понимать, что с их помощью решаются далеко не все задачи многозадачности и можно попасть впросак во вполне обычной задаче.
Я ничего не говорю об авторе. Я говорю об ардуинщиках, которые прочтут статью и начнут программировать многозадачность по тому принципу, что вы описали.
Насчет уровня сложности и понимания — ну хотя бы необходимо понимание того, что любой код любого таймера должен будет выполняться за время, меньшее, чем период самого меньшего таймера в системе. Иначе вы пропускаете циклы со всеми вытекающими.
Конечно, если период самого меньшего таймера сделать в 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 эффективных строк.
а уж на аудит десятка библиотек, используемых в проекте, никаких сил не хватит — для этого нужно создавать специальный отделБросить взгляд на чужие исходники, прежде чем тащить их в свой проект — никак нельзя считать проведением полноценного аудита, но это делать просто необходимо, особенно в эмбединге, где ресурсы железа на вес золота.
Так делать нельзя — АМС это распределённая система контроллер-браузер и обе части системы равноценны и представляют собой одно целое. Если посчитаете все строки кода в проекте — то все скажут вам спасибо, по крайней мере будем знать сколько их (и желательно считать не «эффективное» значение, а реальное).
Что касается библиотек, то в идеальном мире так и нужно сделать, а ещё лучше написать свои собственные библиотеки, но в реальном мире на это банально не хватает ресурсов.
Затрудняюсь оценить ваш метод подсчёта и что понимается под «эффективными строками»Это вовсе не «мой» метод, а довольно распространенный метод подсчета метрик кода 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 итого
а ещё лучше написать свои собственные библиотекиА вот это не факт, т.к. некоторые вещи, например криптографию, не стоит браться писать, не являясь профессионалом в данной области, а, во вторых, как Вы справедливо подметили — «на это банально не хватает ресурсов»
Считать ли css программным кодом — вопрос дискуссионный. Я, например считаю, что html — это не код, а контент, а css — разметка, вот JavaScript, безусловно, программный код. Но ведь изначально речь шла о программировании микроконтроллера, а html, css и JavaScript исполняются в браузере, поэтому я их и не учитывал.
Также нужно учитывать следующий момент. Codestyle AMS исповедует немного нестандартный подход, а именно, табличное форматирование и упаковку кода, поэтому многие его фрагменты, если их привести к стандартному виду, станут занимать на порядок большее количество строк.
Можно спросить, что вас не устраивает в этом классе?
Оригинальное 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 можно расширить и даже сделать его шаблонным для поддержки разнообразных типов данных. Более того, от него можно унаследоваться и использовать какие-то свои (типы).
*прИдумали. Пардон.
есть готовые функции работы с целыми блоками данных
Если доступ к блоку, к примеру, организован через цикл внутри реализации eeprom_read_block — это будет сильно отличается от цикла с ардуиновским read()?
Кстати, а зачем Ардуинщику реализовывать "это" через циклы и побитовые операции? Разве без них не обойтись?
P.S. Если выгорит одна штука (тьфу-тьфу!..), так и быть, запощу на хабре статейку «Как заработать $1M на ардуино». Ну, а не выгорит — не запощу :D
А что при переполнении таймера millis()? Раз в 49 суток пропускаем 1 тик высокоуровневых таймеров?
Где-то читал, в ПО какого-то то самолёта обнаружили аналогичную проблему; при uptime 49 суток то ли зависал, то ли перезагружался один из контроллеров. Спасает то, что так долго самолёт не летает.
bool myCycle::check() {
if (millis() - _start >= _period) {
сработает не так как хочется.
millis() < _start — по идее, таймер остановится.
19, 47, 67 мс.
В 5 строк. ;)
Вот та простыня для ардуины достаточно легко масштабируется на любое разумное количество софтовых таймеров. Да, где необходима точность — так делать не нужно.
Чем ваш вариант (которого вы так и не показали) лучше?
Ладно, пусть это очипятка.
Простыня из статьи делает совсем другое. Там каждый таймер можно запустить не тогда, когда значение счетчика нацело делится на Х, а когда нужно.
В простыне из математики — только вычитание.
У вас — деление (хз, во что развернет его компилятор).
Походу, у вас от ардуиновского С++ просто подгорает ;)
С чего вы взяли что произвольно то?
Можете запустить свой таймер, например, синхронно с нажатием кнопки?
Сможете, конечно, но это будет уже не так красиво.
Вообще ваша позиция забавна: «Я ничего не понял, но оно работать не будет».
Тоже мне бином ньютона. Будет работать, не переживайте.
Спрогнозировать, сколько тактов займет сравнение
time%LED1period == 0
сможете? Каюсь, не читал я даташитов, но что-то мне подсказывает, что деления с остатком ATMEGA не умеет. Мне кажется, что гонять цикл с делением внутри только для проверки на 0 — это очень, пардон, попахивает говнокодом.Если вам не нравится..
Не то чтобы не нравилось… Еще раз намекаю: короткий и какбы очевидный код — не всегда хороший. Длинный код — не обязательно плохой. Бывают случаи, когда классы — это хорошо. Бывают — когда неважно.
… то можно и иначе реализовать
Конечно. Только если захочется сделать тот же функционал, что и в простыне, только без классов — получится такая же простыня, или чуть больше, но на гордом С.
Можете запустить свой таймер, например, синхронно с нажатием кнопки?
Сможете, конечно, но это будет уже не так красиво.
удивительно, насколько такие элементарные вещи могут казаться некоторым сложными ))
слышали про такую страшую вещь как прерывания?
вот на прерывании по фронту на пине это легко реализуется (давайте теперь поспорим 5 строк мне на это понадобится или 11, это критически важно))
Да, если использовать приведенную в статье простыню — это будет в 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) {...}
Кратко, лаконично, без делений и умножений.
Если следующее событие дальше, чем переполнение таймера — ставим срабатывание на обнуление таймера, по нему снова пересчитываем. Ну а аппаратный таймер выбираем уже исходя из нужной точности, поведении во сне и т.п. — обычный таймер, LPTIMER, RTC…
И после этого жаловаться на превратное отношение?
Не будучи электронщиком я лет 10 назад заинтересовался AVRками. Тогда, чтобы запустить шаговый двигатель пришлось попотеть (AVR studio, assemler, ЛУТ) — в это есть свои плюсы. Но теперь с Ардуиной, тот же ШД, термопары, ИК-темометры на работе я припахиваю к своей экспериментальной установке за смешные деньги в 15 минут.
А курящие в коридоре электронщики, заглядывают в комнату, смотрят на Ардуино и тоскливо спрашивают: «Может вам на установку сделать автоматизацию?» (За немалые деньги)
А ведь на Ардуино всё хорошо работает и я доволен!
А как будут организованы таймеры — по циклам, прерываниям и аппаратным таймерам — это чисто технический вопрос и я бы не стал так близко воспринимать его к сердцу :)
Ардуино совершило настоящее чудо из чудес — приобщила к программированию микроконтроллеров и техническому творчеству миллионы людей.Здесь надо все же разделять железную и софтверную компоненты. Что касается железа, то с Вами трудно не согласиться. А вот что касается софта — то имеются две стороны медали. С одной стороны — просто замечательно, что можно помигать светодиодом совершив всего «пару кликов мышки» и сделать это можно не имея вообще никаких познаний в программировании. С другой стороны — многие из этих вновь приобщенных людей так и остаются работать в этой обособленной среде разработки, даже перейдя от мигания светодиодом до вполне серьезных проектов, вроде Вашего AMS. Здесь люди пытались делать замечания про качество Вашего кода, причем, высказано отнюдь не все, Ваше агрессивное «работает, и нет никому дела, как это написано» отбивает желание комментировать. Вот это, как раз, и вызывает раздражение опытных разработчиков по отношению к «ардуинщикам». А такой подход во многом вызван именно замкнутостью среды разработки, что приводит и к замкнутости разработчиков в своем «чудном маленьком мирке Ардуино», тем самым отдаляя их от всего остального сообщества программистов, занимающихся серьезной разработкой под микроконтроллеры. А учиться, судя по Вашему коду, Вам еще есть много чему.
если вы попытаетесь дать своему 10-летнему ребёнку даташит на STM32, то на этом его знакомство с волшебным миром микроконтроллеров будет закончено и скорее всего на всю жизнь. А если вместо даташита на STM32 вы дадите ему Ардуино, то со временем он может перейти и к STM32.
Кстати, на 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, то на этом его знакомство с волшебным миром микроконтроллеров будет закончено и скорее всего на всю жизнь
Вы когда-нибудь в жизни такую штуку, как «операционная система», вообще видели?..
Однако с другой стороны, для проектов, которые «профессионалами-эмбеддерами отработаны 20 и более лет назад» — почему бы наоборот не порекомендовать ардуину?
Для игрушек, для старта школьникам, для теплиц и бассейнов садоводам и дачникам.
Неужели нельзя без снобизма «или только как святые отцы завещали или никак»?
PS: грубо говоря, я понимаю, что выпускнику «факультета мостостроения» негоже строить курятник или сортир без расчетов и сопромата, но это же не значит, теперь каждый дачник тоже должен его знать и чтоб нини самопала.
Современные же применения для встроенных МК — это те же коптеры, дроны, системы автовождения с анализом изображений от нескольких камер в реальном времени, прыгучие собаки-роботы с их сложной динамикой, распознание банкнот со скоростью десятки в секунду…
Вообще-то ключевое слово в этом всем — "встроенные". Это означает, что такую систему поставил и забыл — то есть ты ее не видишь, не слышишь, не имеешь к ней доступ, когда захочется и она не требует никакого обслуживания — ни периодического, ни ремонта, ни апгрейдов.
И это, как ни странно, очень важное понятие, которое трудно обьяснить программисту — что цикл разработки такой железки заканчивается не тогда, когда оно начало моргать лампочками и крутить моторчиками по команде от кнопки, что для десктопного программиста означает "уже продакшн, если что-то зависнет, или заработает неправильно, пользователь перезагрузит", а только тогда, когда такая железяка будет готова к тому, что будет работать в режиме 24/7/365 вообще без какой либо необходимости вмешательства пользователя или разработчика и при всевозможных внешних условиях, включая пропадания и появления питания, изменения температуры и других внешних условий и в том числе неадекватной реакции пользователей, которые об этой железяке ничего не знают.
Эмммм… Разве эта статья имеет отношение к Ардуино?
Что я понял из прочитанного и лекций Олега.
Олег говорит, что Ардуино — устаревшее железо и не слишком удобная экосистема. Ардуинщик! Если хочешь двигаться дальше — изучай это и это.
Автор статьи говорит: а я на Мега таки забабахал платформу и давай, ардуинщики, велкам в неё.
Разве я неверно описал ситуацию?
Но.
Наряду с 99% абсолютно правильной информации Олег позволяет себе говорить вещи абсолютно не соответствующие действительности. Проблема в том, что Олег произносит эти вещи не в курилке среди своих собратьев по разуму, а с трибуны технического университета и на головы несчастных студентов.
На протяжении всех лекций Ардуино у него выступает в роли «мальчика для битья». То у Олега ардуинщики не смогут помигать пятью светодиодами, то «подход с бесконечным циклом не работает на сложной программе» то ещё куча высказываний подобного рода.
На самом деле подход с бесконечным циклом прекрасно работает на сложной программе и в этом каждый может убедиться, скачав дистрибутив АМС для любой из десятка платформ от Mega 2560 до ESP32.
подход с бесконечным циклом не работает на сложной программе
Насколько я помню, любая GUI программа под Windows — это бесконечный цикл обработки сообщений.
Если бы существовал Единственно Правильный и Универсальный способ написания программ — все бы пользовались только им, писали правильные программы, и никто не писал неправильные.
Насколько я помню, любая GUI программа под Windows — это бесконечный цикл обработки сообщений.Позвольте поправить: не любая программа, а основной поток выполнения любой программы. Но на этот поток нельзя навесить ни ресурсоемкие вычисления, ни обработчики событий, требующих быстрой (насколько это позволяет диспетчер) реакции. Для этих целей приходится запускать отдельные потоки.
На самом деле подход с бесконечным циклом прекрасно работает на сложной программе и в этом каждый может убедиться, скачав дистрибутив АМС для любой из десятка платформ от Mega 2560 до ESP32
Скажите, а цель этих ваших мучений — она какая?
То есть вы серьёзно в 2018 году пишете относительно большой проект, работающий, если я вас правильно понял, на бесконечном цикле, когда человечество уже десятилетия как изобрело прерывания, многозадачность, шедулеры, потоки, сообщения и множество других прекрасных вещей.
Зачем?
А зачем вы упорно пытаетесь что-то делать на инструментарии, который устарел десятилетия тому назад, понять довольно трудно.
И разумеется ничто не мешает мне сделать следующий проект на столь милой вашему сердцу RIOT OS — интересы у меня очень обширные.
Ардуино это платформа, которой пользуются миллионы людей и проект написанный на Ардуино имеет шанс быть понятым и используемым множеством людей в DIY, в отличии от RTOS и чистого C++.
А что, это как-то противоречит тезису «она устарела»?
Так вот, с тем, чтобы превзойти автомат Калашникова по сумме показателей, проблемы есть уже не первое десятилетие, хотя Минобороны очень хочет.
А с тем, чтобы превзойти ардуину по всем показателям разом, проблемы нет вообще никакой.
"скачав дистрибутив АМС для любой из десятка платформ от Mega 2560 до ESP32."
Но это не Ардуино! Это Ваша ОС(?) на том или ином железе.
А дальше выбор пользователя — доверять вашей системе или той, что двигает Олег.
И ту и другую надо изучать, тратить время, ресурсы.
Олег ратует за STM32, вы — ряд другого железа, в том числе и 32bit МК среди него.
Поэтому, ИМХО, эти заметки к Ардуино отношения не имеют. Они о (условном) "соревновании" Riot OS на STM32 И AMS на том, куда Вы его портировали.
И, в некоторой степени, это "прикрытие" AMS лейблом Ардуино.
Чтобы не приходилось по принципу «Ах, как это у нас нет абстрагированных от железа таймеров? Я вот сейчас возьму и за неделю докажу обратное!» в муках рожать то, что все остальные люди получают тупо из коробки, готовое к использованию и существенно более высокого качества.
«первый» автор был ближе к истине, когда рассказывал на лекции будущим инженерам про отсутствие многозадачности на андрунно, т.к. с точки зрения этого самого инженера и с точки зрения потенциальных задач — её там нет. сказки про управление сотней «сущностей» и красивые картинки это очень хорошо, но ровно до момента уточнения, что скрывается за понятием «сущность» и каково время отклика/обмена.
если Mega Server управляет 100 клапанами или светодиодами — откуда будет нагрузка на ядро? опрос кнопки или включение реле это единичные команды, они физически не могут воссоздать любую ощутимую «нагрузку». почему хоть это и является истинной причиной и основой работы — никак не упомянуто в статье?
не упомянуто, что «управление шаговым двигателем» — это тупая выдача пачки импульсов dir и step на отдельный контроллер.
не упомянуто, что «датчики влажности» — это тупые каналы ацп. они физически всегда работают сами по себе, параллельно контроллеру, и уж конечно будет достаточно скорости опроса 1sps/s. где нагрузка для контроллера с частотой 16МГц?
не упомянуто, что «сервоприводы» — это тупые сервы с отдельным контроллером, которым для управления достаточно софтового шим на 50 Гц. это сложнее первых вариантов, но не может быть ощутимо в масштабах скорости работы контроллера.
не упомянуто, что любые оставшиеся виды датчиков и исполнительных механизмов для ардуйни — по сути вариации вышеперечисленного. и конечно же, такая «нагрузка» не может «грузить» RTOS даже на 8-битном камне.
ардрунно это крайне удобный инструмент, и для автоматизации и для обучения и для прототипирования. низкий порог вхождения, масса готовых модулей (дешёвых!). наличие большого количества готовых поделок, в т.ч. опенсорс, откуда можно заимствовать работающие решения. но если оспаривать того автора и впустую не набрасывать кал на вентилятор — нужно привести аргументы на уровне того самого автора. студентов инженеров не учат проектировать поливалки для цветов.
И, во вторых, лучше вообще не врать, особенно когда ты выступаешь с кафедры университета и программируешь поведение (на основе внушаемых стереотипов) десятков (а учитывая распространение лекций через интернет) тысяч людей.
ещё раз — инженеров не учат дизайнить поливалки с дискретностью управления в одну секунду. никакой многозадачности и многопоточности с точки зрения «обычных» для инженерных применений у ардуины нет, неважно насколько тридэ она рисует на экране погодной станции. ну и лекцию он читал не на DIY митапе где собрались самоделкины с смузи.
перегибы в сторону анрдрунно — это просто личный бзик автора
Именно об этом я и говорю. Именно перегибы, именно «бзик» и именно «личный». И до этого никому не было бы дела, если бы лектор не транслировал этот бзик с кафедры технологического университета.
А про сами лекции никто ничего не говорит — они отличные.
с точки зрения подачи материала а также целевой аудитории — лучше соврать про проблемы с пятью светодиодами будущему инженеру на профильном семинаре
Зачем будущему инженеру по микроконтроллерах разбираться в тонкостях старинной демо-платы на старинном контроллере, вот что непонятно.
Почему будущему инженеру любого другого профиля иметь возможность быстро решить свою задачу с помощью недорогой и широко распространенной демо-платы — зашквар?
Почему будущему инженеру любого другого профиля иметь возможность быстро решить свою задачу с помощью недорогой и широко распространенной демо-платы — зашквар?
А почему бы будущему инженеру не уметь решать свои задачи современными средствами?
Откуда вот это «деды на турбопаскале под дос писали — и мы будем»?
Я думаю основная проблема в том, что Ардуино открыло двери в мир эмбеддерства сравнительно большой аудитории программистов и не-программистов, которые мало понимают, чем управление GUI отличается от управления поливом или ШИМ мотором. В прошлом начинающий эмбеддер должен был изучить немало соответствующей литературы и одно только изучение микроконтроллерной периферии и последовательных интерфейсов наталкивало на правильные мысли в стиле "Хмм, а скорость-то тут ограничена" или "А как обеспечить приемлемое время реакции на такое событие, если мне параллельно надо и то и это делать?"
Так как эмбеддерсто, в принципе, опасная штука — одно дело, если такой горе-айтишник сделает свой полив на ардуино, который пропустит свой таймер и зальет теплицу невзначай — ну ладно, случилось один раз, бывает, ущерб небольшой. Но ведь они ж лезут дальше — в умный дом, управляя электричеством, скоро автопилоты на ардуино запустят. И ардуинщики будут доказывать, что софт-реалтайм ничем не хуже обычного… А то, что защитный автомат на ардуино вдруг не сработал вовремя и спалил мотор — ну то такое, либы кривые. Или руки?
По-моему, именно на это хотел намекнуть Олег, заявляя, что со светодиодами будут проблемы. Если хочешь заниматься эмбеддерством серьезно, управляя сложной и зачастую очень дорогой периферией (в десятки и сотни раз дороже самого Ардуино) — Ардуино подход — неправильный. Он дает ложную уверенность, что все просто, когда на самом деле нет. И расплата наступит, только позже.
В прошлом начинающий эмбеддер должен был изучить немало соответствующей литературы
Раньше программист должен был знать по именам все регистры в своем процессоре. И машинные коды основных команд. И таблицу прерываний. А сейчас поустанавливают своих фреймворков и жаваскриптов…
;)
Знание напамять всех управляющих регистров таймера никак не гарантирует, что, например, локальная проблема 2000 не будет организована каким нибудь другим способом.
Нет, просто подход к обучению и принципам разработки должен быть другой. А то в данной статье показывается:
- О, а давайте помигаем пятью различными светодиодами с различными периодами...
- Берем ардуино, таймеры, пять строк кода и вуаля — мигает!
- А теперь заменим светодиоды на моторчики от квадрокоптера…
- … Ой (подбирая отрезанные пальцы), я, кажется, забыл вам рассказать: это софтверная многозадачность с ее очевидными недостатками...
Сорри за возможно неудачный пример, но то что такого сценария еще не произошло — это чистая случайность. Смысл в том, что начинать изучать эмбеддерство надо немного с другого ракурса… И с Ардуино и без...
В среде программирования Arduino из коробки тех же нормальных таймеров нет. Это как бы факт, и для 2018 года нашей эры это немного позор.
И большинство ардуинщиков о том, как эти таймеры сделать — и часто о том, что их вообще можно сделать — не имеют никакого понятия, а меньшинство радостно производит вот такие порождения сна разума, как в этой статье, «а что такого, что у меня весь проект в одном цикле крутится, ну у меня там по-любому задержки обычно не больше десятка миллисекунд».
Операционные системы, в том числе на микроконтроллерах, в том числе предоставляющие программисту прямо из коробки массу нужны и полезных сервисов, в том числе таймеры, шедулер и IPC, человечество изобрело, мягко говоря, не вчера — и только ардуинщики (что блестяще демонстрирует здесь ТС, подтверждая мои слова) продолжают считать, что весь остальной мир по-прежнему на ассемблере в регистрах ковыряется, чтобы hello world запустить.
1) Родных средств многозадачности в среде Arduino нет, хотя вообще-то в 2018 году неплохо было бы их иметь (и даже несколько раньше тоже можно было бы). Вообще среда Arduino темпами своего развития напоминает известную картинку про сравнение модельного ряда BMW и Жигулей — за десять лет в ней случилось примерно ничего.
2) Сделать многозадачность руками можно на чём угодно, хоть на ATTiny; на старших атмегах можно и ОСРВ нормальную запустить. Остаётся только вопрос — зачем это делать, и ответ на него можно выразить другой картинкой, про буханку хлеба и троллейбус (и ваша статья в целом этому увлекательному процессу модернизации буханки и посвящена). Ни экономического, ни технического смысла использовать AVR — а тем более, Ардуину — в абсолютном большинстве проектов нет.
То есть, непонятно, зачем вообще вы пишете этот ужас, когда человечество довольно много лет тому назад придумало куда более удобные решения.
Как я уже написал в статье, ваши лекции хороши и всё вы в них говорите правильно, но ваше отношение к Ардуино и использование её в качестве объекта для титрирования на протяжении всех лекций вызывает мягко говоря недоумение. Кроме просто пренебрежительного отношения вы ещё и допускаете фактические ляпы, заявляя, что мигание пятью светодиодами в независимых режимах затруднительно на Ардуино. И подобных ляпов я насчитал в ваших лекциях около десятка.
Дело в том, что вы высказываете своё пренебрежительное отношение этой технологии, не в кулуарах и не в личной беседе, а с трибуны технического университета, тем самым формируя такое же предвзятое отношение к Ардуино и у студентов.
Это не значит, что студенты университета должны учиться на Ардуино, но и обвинять Ардуино во всех смертных грехах по делу и без дела тоже не стоит, тем более, что вы выступаете в роли безусловного авторитета для ваших слушателей.
В то время, как в 2018 году любой разработчик на любой нормальной платформе (RIOT, mbed, ChibiOS, FreeRTOS, Contiki...) просто из коробки получает полноценные таймеры с кучей возможностей, вы потратили уйму времени и сил, только чтобы написать кособокое примитивное их подобие.
Откуда такой снобизм и пренебрежение?
Во-вторых, поясните, почему меня должен волновать объём этой индустрии, причём волновать настолько, чтобы я начинал замалчивать её крупные недостатки? Я вроде как сотрудником Arduino AG не являюсь.
И речь идёт не о том, что вы должны что-то замалчивать, а о том, что вы высказываете несправедливые и предвзятые суждения об этой технологии, взять хотя бы вашу цитату из второй лекции, вынесенную в начало статьи о том, что на Ардуино затруднительно мигать пятью светодиодами в независимом режиме — это просто не соответствует действительности — на Ардуино нет никаких проблем с подобным миганием.
Вы же сами всей своей статьей демонстрируете, что да, на Ардуино затруднительно мигать пятью светодиодами.
Вы накатали несколько страниц текста про то, как вы в вашей ардуине солнце вручную закатываете, чтобы получить убогое подобие функционала, который в любой микроконтроллерной ОС разработчику доступен из коробки.
Мы вроде бы уже установили, что суждения мои справедливы и непредвзяты.
Где это мы установили?
Вот вами написан здоровенный текст о том, что для получения на ардуине кривого, косого и убогого таймера вам пришлось изрядно потрудиться. В комментариях к которому вы, к тому же, демонстрируете полный набор типичных для ардуинщиков заблуждений — начиная с того, что весь остальной мир, кроме вас, ардуинщиков, до сих пор регистры из даташитов перепечатывает.
А пользовались бы вы средой, с которой за последнее десятилетие произшло что-либо хорошее, вам бы вообще всего этого писать бы не пришлось.
Потому что в том же 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 мигание светодиодом по таймеру выглядит так:
Какая религия запрещает на Ардуино обернуть любые таймеры в любую обёртку и использовать мигание светодиодом вообще в одну строку?
Просто не надо рассказывать, что это легко и приятно, а вот те, у кого солнце само каждый день за горизонт садится, вот они-то как раз и мучаются.
Объясняю как это делается: один раз пишется (простенькая) библиотека, а затем в любой момент в код вставляется одна строка. И да, это на Ардуино тоже работает.
— Веб-сервер
— Сайтовый движок
— 8 сайтов, каждый со своим функционалом, дизайном и топологией
— С поддержкой честных интерактивных 3D-сцен
— Power Monitor-ом на 14 каналов и сетевым осциллографом
— Поддержкой nRF24 связи с датчиками и второй распределённой частью
— 60-ю датчиками и актуаторами
— Dash-панелью работающей в реальном времени
— И прочими возможностями, описанными в статье
То, обещаю, в тот же день я вам предоставлю эту библиотеку.
P.S. Если не секрет, а зачем это всё делать на 8-битном контроллере с 8 КБ памяти, кроме как из желания очистить душу страданиями?
А в остальном — из-за того, сколько вы мучились в этой вашей ардуине с вещами, которые всем остальным миром давно решены и признаны тривиальными, вам кажется, что в этом наборе функционала есть что-то сложное.
То есть такой библиотеки в мире ардуино на данный момент попросту не существует.
Олег, вы это серьёзно? Написание такой библиотеки это детская задачка для начинающего ардуинщика.
А вот аналога описанного мной функционала или хотя бы чего-то похожего, сделанного на RIOT OS мы от вас никогда не дождёмся (даже в теории).
Написание такой библиотеки это детская задачка для начинающего ардуинщика
И при этом готовой библиотеки, в которой она бы решалась, нет. Всё чудесатее и чудесатее.
Может быть, это потому, что вы немножко путаете? Детская задача — это написание того, чем вы с уважаемой публикой поделились. Ну, где «требует специальной оптимизации кода под конкретную задачу» и прочая бессмысленная порнография.
А написание нормальной подсистемы таймеров — задача несколько более серьёзная. Вы к ней пока даже не приступали.
А вот аналога описанного мной функционала или хотя бы чего-то похожего, сделанного на RIOT OS мы от вас никогда не дождёмся (даже в теории).
Было бы удивительно ожидать иного — на кой чёрт мне это делать?
Ок, подведу итог встречи под девизом «Нео сражается с Морфиусом» :)
Я думаю мы с Олегом достаточно (бесплатно) позабавили публику, каждый из этой поучительной дискуссии сам сможет сделать соответствующие выводы.
Победила дружба! (Я думаю продолжать нет смысла)
Я так думаю, если "нормальной" системы таймеров в понимании одного участника нет, может, именно такая система никому не нужна. Что ненормального в предложенном троллейбусе, который за час пишется? А если не упаковываться оформлять как класс (не нужно если N таймеров, достаточно 2) — ещё быстрее.
Магия STM32 выглядит прельстиво, но без документации это просто колдунство. Какая точность у этого решения, будет ли оно с чем-то конфликтовать… Если тупо скопировать тот код — чем это лучше подхода "ардуинщика", налабавшего свой велосипед из delay()?
Ровно тем же путём вы можете придти к выводу, что отладчик никому не нужен, прерывания никому не нужны, разделение проекта на файлы исходников и заголовочные никому не нужно, лучшая скорость UART — это 9600 бит/с, энергосбережение никому не нужно, etc.
Что ненормального в предложенном троллейбусе, который за час пишется?
Вы издеваетесь, что ли?
«Если требуется управление в более жёстком реальном времени, то это требует специальной оптимизации кода под конкретную задачу, перестройки архитектуры или, в совсем крайних случаях, выделения отдельного контроллера под специфические функции»
Ах, да, прерывания и аппаратные таймеры же никому не нужны.
Вы издеваетесь, что ли?
Олег, очень не хочется затевать очередной холивар, потому, что к единому мнению мы не придём, замечу только:
1. никто не говорит, что предложенное решение идеально и лучше других — но это рабочее и проверенное решение на платформе Ардуино.
2. ТТХ этого решения достаточно для решения 95% практических задач «простых людей», там, где требуется жёсткое реальное время никто не предлагает использовать его.
3. Ардуино — это не ущербная и не устаревшая платформа, а ПО ФАКТУ (нравится нам это или нет) инструмент, используемый миллионами людей. И игнорирование этого факта это ничто иное, как узколобый снобизм.
Судя по вашим высказываниям у вас особые проблемы с пониманием пункта 3
Человечество же давно уже серийно производит велосипеды, у которых колёса круглые, с металлическими спицами, надувной камерой и покрышками с красивым рисунком.
То, что на вашей любимой платформе таких велосипедов не бывает, поэтому миллионы людей с грохотом переваливаются на поделках типа вашей, ни разу не говорит в её пользу.
Ещё, что я хочу донести до вас: в других проектах и для других целей я (с удовольствием) буду пользоваться решениями за которые вы ратуете (никто не спорит с тем, что они хороши и правильные), но АМС — это многофункциональная, в том числе и обучающая платформа для тех людей, для которых доступен только уровень Ардуино. Это принципиально Ардуино-based проект.
всего лишь реально работающее решение «здесь и сейчас»
А почему вы так упорно не хотите вместо уродливых костылей «здесь и сейчас» использовать нормальные решения?
в том числе и обучающая платформа
Вот это-то и страшно — что вы ещё и обучать кого-то там хотите на примере кода качества «я сделяль».
Это принципиально Ардуино-based проект
Да хотя бы и в вашей ардуино нормальное решение вам сделать какая религия мешает? У вас же даже все средства для этого есть.
Ардуино головного мозга, дендрофекальное что-то слепили, работает — и ладно?
К тому же, это не отвечает на вопрос, почему нельзя сразу использовать нормальные решения, которые человечество придумало, когда вашего проекта даже в мечтах ещё не было.
Но вы идёте чуть дальше — вы ещё и студентов им научить требуете.
Но вы идёте чуть дальше — вы ещё и студентов им научить требуете.
Это ещё одно ваше заявление, которое элементарно не соответствует действительности. Прямо не сходя с этой страницы вы можете (по поиску) найти 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().
А Ардуино — это набор плат и среда разработки, созданная в 2003 году на уровне 1993 года, да так на нём и оставшаяся.
Извините, что вмешиваюсь в вашу дискуссию, но я так понял, что автор статьи прикрутил таймеры ради многозадачности, а не ради самих таймеров. Просто с помощью них на Ардуине данная задача решается проще, хоть и не сильно правильно. Так можно сделать и на любой другой платформе без ОСРВ.
С другой стороны при использовании ОСРВ или более высокого уровня абстракции, например IEC 61131-3, для многозадачности таймеры изучать вообще не нужно. Причем эта многозадачность уже получается правильная по всем какнонам эмбеддерства.
Меня в авторе другое смущает: зачем он продолжает утверждать, что вот этот закат солнца вручную — это хорошо, правильно и вообще кому-то реально нужно, когда простым уходом на любую современную ОСРВ все эти проблемы решаются сразу и сильно лучше.
Но топикстартер-то аж целый мегасервер ваяет. И делает это зачем-то на AVR в ардуине, хотя на Cortex-M с ОСРВ было бы не только на порядок удобнее и быстрее, но в общем даже и дешевле (ATMega2560 не совсем копейки стоит).
Лично мне в ардуинщиках не нравится, что они выкидывают кучу готовых наработок на любую тактовую частоту и память, делая вид будто до появления на плате ардуино подобного МК не существовало.
Не знаю, но могу предположить разные варианты:
- ОСРВ может противоречить концепции построения Arduiono IDE — т.е требует переделки библиотек и всего кода. А иначе все, что сделано сейчас, с ОСРВ просто не совместимо. Вот и придумывают такие реализации многозадачности.
- Возможно прайсовая политика на платы Ардуино не приветствует расточительство ресурсами, необходимое для ОСРВ. Я замечал несправедливость на рынке МК, когда 32-ух битный кортекс с 512кб флеши стоил дешевли 8-и битки с 16-ю кб. Так что тут надо смотреть — возможно Ардуино АГ или как их там, зарабатывают на платах, а пользователи мучаются.
2) Arduino AG вне всякого сомнения зарабатывает на платах, и пока они продаются — запредельная убогость среды разработки их волнует крайне мало.
1) я не имел ввиду, что ОСРВ нельзя портировать на Ардуино. Я не сомневаюсь, что уже сейчас есть куча работающих вариаций. Я имел ввиду, что Ардуино коммьюнити уже наработало кучу кода и библиотек, которые с радостью используются и переиспользуются, но эти библиотеки никак не совместимы с портированными ОСРВ, хотя бы потому, что общаются с периферией напрямую в монопольных режимах. В итоге у ардуинщика достаточно сложный выбор — либо использовать любимую библиотеку, но без ОСРВ, либо ОСРВ, но остаться без библиотеки(что многих очень страшит). В итоге большинство выбирает первое и появляются такие реализации.
По 2) — я имел ввиду, что прайсовая политика на платы такая, что плата на 8-и битном контроллере с 16кб флеши стоит, например, один доллар, а на 32-х битном с 512кб — 10, хотя контроллеры сами по себе могут стоить одинаково. Ардуино зарабатывает, а пользователи вынуждены себя ограничивать.
2) Нет, это не так. У них костяк составляют платы на AVR, а ради больших денег идут платы с внешними довесками — Wi-Fi, LoRa и т.п. Платы с Cortex-M пошли плохо, ибо ввиду убогости программной среды никаких особых преимуществ не предоставляли, кроме тупо более высокой тактовой частоты.
Я вот что хочу заметить в целом. Мне кажется очень важную вещь, которая упускается: Ардуино не открыла дорогу широким массам в программирование контроллеров. Ардуино сильно упростила процесс повторения чужих наработок.
Попытка же типового Ардуинщика (азы Си, один-два повторенных чужих проекта) сделать что-то самостоятельно натыкается на необходимость поднять такой пласт знаний, что он, в большей степени, и "замерзает" на этом уровне.
Ещё нюанс — ей могут пользоваться как программисты, не работавшие раньше с железом, так и электроники, не умеющие программировать. После повторения чужого проекта они вполне могут заинтересоваться, переделать программу под свои нужды… смотришь — уже библиотеки правят и свои модули паяют. Не попробовав, они просто не смогли бы пойти дальше.
На счет таймеров, далеко не всегда нужны точные интервалы времени и работа по прерываниям. Я работаю с ПЛК, в них тоже обычно крутится бесконечный цикл: прочитал состояние входов, обработал, выставил состояние выходов. Прерывания только там, где они реально нужны (сигналы с энкодеров и т.п.), в остальном время цикла может составлять десятки, а то и сотни миллисекунд. Всё зависит от задачи, на сложном оборудовании крутится например Simatic, а что-то относительно простое вполне можно собрать на LOGO!
Моё мнение — Ардуино это не совсем про эмбеддинг, скорее такой любительский ПЛК. Отлично подойдет для ознакомления, создания прототипов устройств, можно что-то не сильно критичное на нём собрать вроде системы сбора информации с датчиков. Формат, интерфейс подключения стандартизированы, есть платы на разную производительность и количество выходов, дополнительные модули, библиотеки. Софт не перегружен лишними функциями, но под капотом обычный Си — всегда можно выбрать, насколько глубоко в него залезать. Ещё прикрутить промышленные графические языки программирования (LAD, FBD), добавить нормальные входы/выходы и можно ставить на дин-рейку, будет вполне реальный конкурент тому же LOGO! (у которого, к слову, только пару лет назад появилась возможность выделять повторяющиеся блоки в модули-подпрограммы).
электроники, не умеющие программировать«Электроник» — это про «робота-мальчика» из советской фантастики. В русском языке принято говорить «электронщики» (совет вам на будущее, перед высказыванием в теме, в которой вы не «комильфо»).
1) таймеры и «многозадачность» полностью вырубаются при любом затыке в loop()
2) watchdog по обстоятельствам религиозного характера вы не используете
?
То есть, если на шаге N у меня включается насос, а на шаге N+1 какая-нибудь из многочисленных библиотек отправляется в страну вечной охоты, потому что от обслуживаемого ею датчика, например, спустя год работы провод отвалился, то насос у меня не выключится, пока весь водоносный пласт на грядку с клубникой не выкачает?
int goLight = 0;
void keysWorks() {
if (goLight == 1) {
digitalWrite(KEY_PIN, LOW);
} else {
digitalWrite(KEY_PIN, HIGH);
}
}
Watchdog в АМС используется внешний по многим причинам, например, в Arduino Mega 2560 есть проблемы со встроенным watchdog-ом и он при некоторых условиях может срабатывать некорректно.
И прошу вас не начинать ещё одну километровую ветку пререканий — у меня нет никакого желания этим заниматься.
И да, как уже было сказано выше, причём не мной, прекрасный образчик индийского кода.
Во-вторых, относительно вас не надо сильно гадать на кофейной гуще, достаточно в код посмотреть. Он такой, на четвёрочку с минусом: судя по всему, у вас нет ни соответствующего образования, ни опыта участия и/или ковыряния в других реальных проектах, ни серьёзного общения с другими программистами — вы пытаетесь самостоятельно научиться писать. В результате у вас посредственная платформа, посредственная архитектура и посредственная имплементация, и всё это вы компенсируете банальным усердием, производя простыни плохого кода.
Ну, то есть, вы вот ни разу не тот человек, от которого имеет смысл принимать багрепорты на вотчдог в ATMega2560.
Что касается вачдога на 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.
(зевая) Не благодарите.
#define MAX_UI_SENSORS 14 // max 14
то ошибки не будет. В дистрибутиве количество токовых каналов уменьшено до 1 потому, что не всем нужно большее количество каналов и математика модуля отъедает очень много памяти.
А фрагмент отправки данных в MajorDoMo я просто забыл поправить, но это несложно сделать и в следующей версии я эту ошибку исправлю.
Вы производите индусский говнокод, при этом считаете себя программистом, способным учить других, и «достойным оппонентом». До не то что идеального, а просто минимально приличного кода вам как ползком до Луны — и пока вы даже не начали в эту сторону двигаться, предпочтя вместо этого заниматься самоубеждением, что у вас и так всё хорошо.
А теперь просто встаньте перед зеркалом и повторяйте вслух «мне сложно с первой попытки написать цикл на С», пока до вас не дойдёт.
P.S. Про «сложный модуль» upload.ino, примерно целиком состоящий из if'ов в три-пять строчек, даже комментировать смешно.
Если имеете дело с массивами — используйте sizeof(). И sizeof(array)/sizeof(array[0]). И не будет таких ошибок.
Про это я естественно знаю и использую. Тут же дело в том, что этот многострадальный модуль был написан ещё за 3 года до появления АМС, т. е. 5 лет назад и работал в жёстко детерминированной системе в конфигурации 1/13.
Там не предусматривалось никаких изменений по каналам, поэтому и код такой. Потом модуль был интегрирован в АМС тоже в жёсткой конфигурации 1/13, а уже потом… я решил добавить возможность изменять количество каналов, а про отправку данных MajorDoMo просто забыл, потому, что к тому времени уже не использовал её.
Вот и вся история вопроса.
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, ®);
if (error)
goto out;
temp_u64 = 0x0808080814141414;
FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64);
error = fpc1020_reg_access(fpc1020, ®);
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, ®);
if (error)
goto out;
temp_u8 = 0x0f;
FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_RST_DLY, &temp_u8);
error = fpc1020_reg_access(fpc1020, ®);
if (error)
goto out;
temp_u8 = 0x18;
FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8);
error = fpc1020_reg_access(fpc1020, ®);
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;
}
в основной ветке код остался старым потому, что модуль сложный и легче его заменить целиком после отладки экспериментальной ветки, чем улучшать каждую функцию в отдельности.
о ней есть информация как в интернете, так и в документации производителя
Конкретнее. Название документа, номер страницы.
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
habr.com/post/189744
Надо править загрузчик, а это противоречит религиозным убеждениям автора, пишущему не под атмегу, а под «социально-культурный и технический феномен нашего времени под названием ардуино».
Последнему клиенту, который приходил к нам с ардуиной (ради переработки её
Мигание пятью светодиодами в означенных им режимах это абсолютно тривиальная задача для 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 идеально для всяких простых "скетчей" и имеет свою целевую аудиторию, но в ВУЗе для будующих профессионалов в данной области — это как программирование на соответсвующих специальностях изучать используя Лого Миры с черепашкой.
с вашей библиотекой софтовых таймеров не поморгаешь светодиодом на 1 кГц в параллель с обработкой данных от сенсора температуры
Я не уверен, что температуру из того датчика имеет смысл читать чаще чем раз в секунду. А если это температура в теплице — достаточно и раз в минуту. Не вижу проблемы.
А таймер на миллисекундном счетчике для интервалов в 500 мксек не годится никакой.
А таймер на миллисекундном счетчике для интервалов в 500 мксек не годится никакой.
Да, мой пример в данном случае некорректен. Но с использованием готовой библиотеки Arduino для этого датчика и Mega Server, даже 50 мс. для других задач не получить.
с использованием готовой библиотеки Arduino для этого датчика и Mega Server, даже 50 мс. для других задач не получить.
Да. Надо просто запомнить про этот недостаток. Где тайминги критичны — не использовать, или использовать с умом.
Где временные интервалы значительно больше секунды (теплица — отличный пример) — использовать или нет — дело вкуса/религии.
У каждого свой критерий нормальности. Когда-то нормальным считалось мигать светодиодом с помощью генератора на 2 транзисторах. Сейчас без 80 МГц, 512 флеша и RTOS никак не обойтись. Хотя лампочки те же, и клубника та же.
Таймеры и многозадачность на Ардуино