Книга довольно интересная и может быть рекомендована всем, кто, так сказать, «продолжает» работу с Arduino. Совсем начинающим она довольно бесполезна, а вот для расширения представления о том, как со всем этим хозяйством обращаться, подходит вполне. Но целевая аудитория не настолько разбирается в предмете, чтобы воспринять критично некоторые утверждения автора и расшифровать многочисленные ляпы переводчика в сговоре с редакторами. Причем автору промахи простительнее, так как он явно программист, а не электронщик, и не может разбираться в предмете досконально. А вот редакторы обязаны были такие места прокомментировать.
Все написанное далее не имеет цели как-то задеть автора и издательство, которые сделали хорошее дело. Я пишу это с надеждой облегчить жизнь читателю, которому посчастливится наткнуться на эти мои измышлизмы. Книга, повторяю, полезная и содержательная, и отдельные промахи не меняют этого моего отношения.
В перечислении далее страницы указываются по официальной электронной версии.
О хорошем
Сначала, как принято, о хорошем.
1. «Использование переменных типа int для хранения номеров контактов приводит к напрасному расходованию памяти» (стр. 63) — более, чем своевременное замечание. Далее в книге несколько раз напоминается, что номера контактов должны вообще-то вводиться 8-битовыми константами. Жаль только, что эта мысль проводится не очень последовательно, потому что широко распространенное стремление обозначать переменными типа int номера выводов — клиника, которая не оправдывается никакой удобочитаемостью текста (и чего там удобочитаемого-то?).
2. «Но в действительности температура в виде вещественного числа нужна только тогда, когда требуется отобразить ее на экране. Другие операции с температурой, такие как сравнение или усреднение при нескольких попытках чтения, вполне можно выполнять с непреобразованным значением типа int, и при этом они будут выполняться значительно быстрее» (стр. 91). Без комментариев.
3. «Быстрый ввод/вывод» (стр. 94) — очень правильный раздел, в нем идет речь об преодолении основного недостатка платформы Arduino: многотонных наслоений нагроможденных друг на друга библиотек.
4. Упоминание о том, что для снижения потребления нужно удалить светодиод по питанию (стр. 110). Почему-то в разговоре о снижении энергопотребления об этом забывают упомянуть абсолютно все.
5. Весьма содержательная и полезная для любителей глава 13 «Цифровая обработка сигналов».
О плохом
Теперь о досадных ошибках. Я их поделил на грубые ляпы (автора или переводчиков/редакторов) и мелкие придирки с моей стороны.
Грубые ляпы:
1. «Контакты в следующей группе подписаны Analog In (аналоговые входы) с номерами от 0 до 5. … Несмотря на то что они обозначены как аналоговые входы, их можно использовать и как цифровые входы или выходы. Но по умолчанию они действуют как аналоговые входы» (стр. 24).
Нет, не так. Все выводы портов AVR по умолчанию работают, как цифровые входы без подключенного подтягивающего резистора. И аналоговые выводы А1-А5 не исключение – с чего бы? Это обычные выводы обычных портов (Arduino-номера 14-19), которые среди прочего могут работать, как входы АЦП. И это качество они приобретают только тогда, когда вы обращаетесь к analogRead, не ранее.
2. Табл 5.1. «Потребление электроэнергии платами Arduino» (стр. 105) ввела меня в настоящий ступор:
Извините, а чего там в Mini есть такого, что должно потреблять лишних 20 мА от внешнего источника? Полез смотреть в оф. схему: вроде ничего. Стабилизатор MIC5205, судя по его описанию потребляет что-то 150 мкА. Не поленился проверить живьем: включил Mini Pro в источник 5 В (напрямую) и в 12 В (через RAW). Как и следовало ожидать, совершенно одинаковое потребление: около 20 мА. Так до сих пор и не могу понять, откуда автор эти данные надыбал — не из головы же выдумал?
3. «Снижение рабочей частоты» (стр. 108). Заблуждение, что снижение рабочей частоты будто бы уменьшает энергопотребление, широко распространено даже в профессиональной среде. На самом деле оно уменьшает только потребление тока, а потребление энергии в расчете на каждый такт заметно увеличивает (так как график рис. 5.3 не прямой, а изогнутый, причем, по словам Монка, несуразный светодиод по питанию тут был отключен):
В двух словах: пусть напряжение питания = 3 В. Процедура в 16 тактов при 16 МГц займет 1 мкс, то есть энергии при этом потребится (ток 8 мА, табл 5.2) 3х8х10-3х10-6 = 24 нДж. При 1 МГц та же процедура займет 16 мкс, и энергии при этом потребится (ток 2,6 мА, табл 5.2) 3х2,6х10-3х16х10-6 = 124,8 нДж. И если в промежутках между этими процедурами вы вводите AVR в состояние энергосбережения, то потеряете в энергии в пять раз. Потому выигрыш будет только, если использовать снижение тактовой частоты, как отдельный прием, больше ничего не делая. А тогда, когда основное время контроллер простаивает, куда больший эффект даст применение sleep, и в этом случае частоту стоит делать как можно выше.
4. «Операции чтения/записи с памятью ЭСППЗУ выполняются очень медленно — около 3 мс» (стр. 142).
Типичный признак непонимания, как работает EEPROM. Запись в нее действительно длится 3,3 мс. Но чтение совсем нет: 1 такт для первого байта, плюс по 4 такта задержки перед чтением каждого последующего, если читать подряд. То есть максимум 5 тактов — 0,3125 микросекунды в случае Arduino 16 МГц, в 10 000 раз быстрее, чем утверждает Монк. А вот про то, чему в каждом даташите по AVR посвящен стандартный раздел «Preventing EEPROM Corruption», в главе про EEPROM почему-то ни слова.
Мелкие придирки
Стр. 50. «и сохранив в папку Libraries, находящуюся в папке Arduino (в папке Documents (Документы))» — вы способны понять из этой фразы, в какой папке какая расположена? Я нет.
Далее там же: «Чтобы среда разработки Arduino IDE обнаружила вновь установленную библиотеку, ее нужно перезапустить» — кого ее? Библиотеку?
Стр. 54. «Аналогичный справочник с описанием команд на русском языке можно найти по адресу arduino.ru/Reference. — Примеч. пер». Спасибо, дарагой, но при этом нужно упомянуть, что arduino.ru/Reference не обновлялось с неизвестно какого времени, а перевод там местами сделан с грубыми ошибками. Иначе твой неискушенный читатель будет поставлен в тупик, например, не найдя по указанному адресу неоднократно упоминаемой в книге константы INPUT_PULLUP.
Стр. 57. «…программы можно выгружать в микросхемы памяти на плате Arduino, а затем переносить их на свои платы» — да? И где же на плате Arduino эти самые «микросхемы памяти»?
Стр. 59. «…и последовательными интерфейсами трех типов, поддерживаемыми микроконтроллером: УСАПП, ППИ и ДПИ». Хотел без комментариев, но не удержался. Что характерно, глава 7 называется «Интерфейс I2C» и речь в ней идет про TWI, а глава 9 называется «Взаимодействие с устройствами SPI». Так что ни, извините за выражение, ППИ, ни ДПИ вы больше в книге не встретите и можете до скончания века гадать над расшифровкой этих сокращений. Зато УАПП и УСАПП вовсю эксплуатируются в главе 10 «Программирование последовательного интерфейса». Ну да, а вулкан, который уничтожит Соединенные Штаты, проснется на территории Желтокаменного национального парка.
Стр. 78. «Попробуйте нажимать кнопку энергичнее, это должно помочь получить четкий переход между состояниями без эффекта дребезга» — совершенно непростительная рекомендация для книги, претендующей на некий «профессиональный» подход. И тоже очень распространенное заблуждение для тех, кто своими руками кнопки включает редко. Единственная разновидность кнопок, мало подверженная дребезгу — из токопроводящей резины (телефонные тастатуры, например). Все остальные кнопки, выключатели, переключатели и т.д. дребезжат абсолютно вне зависимости от того, как на них нажимают, и требуют специальных мер защиты от дребезга.
Стр. 84. Спасибо за наводку на библиотеку TimerOne, но из текста и примера понять, как с ней работать, невозможно. И, кстати, интересный вопрос, точнее, сразу пучок вопросов: почему картинки для разных пинов на рис. 3.3 сдвинуты на восьмую часть периода? Это так само получается? За счет чего, и как этим можно управлять? и т.д.
Стр. 103. «Следующий скетч увеличивает частоту АЦП со 128 кГц до 1 МГц»
Наш уважаемый Монк кое-что забыл упомянуть. А именно, во всех даташитах всех AVR имеется следующий абзац:
By default, the successive approximation circuitry requires an input clock frequency between 50kHz and 200kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200kHz to get a higher sample rate.
На самом деле в АЦП источников ошибок и дребезга и без того хватает, чтобы их еще увеличивать искусственно. А задач, которые требуют быстрого АЦП-преобразования, для 8-битовых контроллеров просто не возникает (не обрабатывать же на них звук, в самом деле). Если нужно точная/быстрая АЦП-конверсия, то проще поставить внешний модуль и не маяться дурью.
Стр. 142. «Флеш-память в Arduino гарантирует сохранность данных только для 100 000 циклов записи» – на самом деле до 10 000.
Стр. 196. Рис. 10.4. – не соответствует тексту и скетчам, потому что один из изображенных Uno использует штатный Serial, а не его программную имитацию, о которой идет речь в этом разделе.
Кажется, все. Может, чего-то пропустил, не знаю.
Комментарии (25)
GennPen
12.02.2017 14:03Не поленился проверить живьем: включил Mini Pro в источник 5 В (напрямую) и в 12 В (через RAW). Как и следовало ожидать, совершенно одинаковое потребление: около 20 мА.
По идее, ток должен был еще и уменьшиться, если бы стоял импульсный стабилизатор, а не линейный который при стабилизации излишки энергии переводит в бесполезное тепло.
PKav
12.02.2017 15:48+2Профессиональная работа… Ну, наверное, если нужно не какое-то примитивное поделие, а сложное и стабильно работающее устройство, то стоит писать непосредственно в каком-нибудь AVR Studio с полным пониманием работы контроллера и периферии. Даже если не хочется делать свою плату для устройства, можно ведь стереть контроллер на плате Arduino, прошивать по ISP и отлаживать по JTAG или dW.
areht
12.02.2017 17:42А есть мануал по отладке ардуины? Я как-то пытался к этому подступиться, понял, что без для отладки надо брать минимум stm32
PKav
12.02.2017 17:45Если по AVR, то есть отладчик AVR Dragon, работает в AVR Studio. А сама Arduino, вроде как, не имеет средств отладки. И да, STM32 гораздо стабильнее и удобнее по всем параметрам, чем AVR.
aamonster
12.02.2017 18:41+1Afaik для ардуины традиционный путь — отладка через вывод логов в uart. В принципе, для несложных задач достаточно (да и на будущее полезная привычка — не всегда можно подлезть отладчиком, и тогда грамотные логи спасают)
Для сравнения, на stm32 новичку без отладчика смерть: зальёшь через бутлоадер прогу и пытаешься понять, почему она вообще не запускается… 2-3 доллара на отладчик спасают закипающие мозги.
GarryC
12.02.2017 19:48Могу посоветовать эмулятор Ардуино circuits.io, там реально можно отлаживать с точками останова и просмотром внутренних переменных, но все в эмуляторе, но при этом в схемном окружении — посмотрите, классная вещь.
areht
12.02.2017 21:41Хорошая штука, но…
Вот моя ардуина читает температуру с DS1820 и рисует график с ней на ST7735. А в эмуляторе таких компонент нет. Делать для эмулятора отдельный скетч?
Да и это… Я там блок питания коротнул, и ничего не взорвалось…GarryC
12.02.2017 21:54Вы попали в самое больное место этого проекта — отсутствие возможности создавать свои компоненты, а вроде бы раньше она была ...
Есть одна возможность, я с ней поигрался — можно поставить более, чем один контроллер и каждому дать свою прошивку, то есть эмулировать недостающие компоненты на дополнительных камнях, но как то кривовато получается.
Да, не взорвалось, а Вы точно этого хотели? )) Но амперметр показал большой ток — уже неплохо, лучше коротнуть в эмуляторе, чем в реале.
areht
12.02.2017 23:25> дать свою прошивку, то есть эмулировать недостающие компоненты на дополнительных камнях
А где её брать? Мне даже от мысли самому писать эмулятор DS1820 уже больно. Проще уж действительно отсадить низкоуровневую часть на отдельный контроллер, сделать веб-интерфейс, и отлаживать высокоуровневую часть в нормальной IDE, с unit-тестами и куртизанками.
Но там без гарантий отсутствия проблем на реальной железке…
> Да, не взорвалось, а Вы точно этого хотели? ))
Я бы хотел, что бы взрывался тот (транзистор), через который пошел большой ток. А то лишние 50мА я могу не заметить.
Goron_Dekar
12.02.2017 20:17+2Снижение рабочей частоты» (стр. 108). Заблуждение, что снижение рабочей частоты будто бы уменьшает энергопотребление, широко распространено даже в профессиональной среде
А вот и нет. Это как раз идея о том, что частоту всегда надо вытягивать в максимум и падать в sleep при первой возможности — заблуждение. И причина этому — периферия. Оба механизма сбережения электропитания важны.
1) Частый уход в sleep и подъём может потреблять больше энергии, чем снижение частоты. Пока раскочегарится PLL, пока затактируется периферия также проходит время и тратится ток. У stm32 это 1-2мс, что равносильно 10 мс работы на пониженой частоте. Если ядро вашей rtos будит МК каждые 10 мс, то sleep может не давать выгоды. Увы.
2) Тактирование периферии. Большая частота тактирования ядра приводит к большим значениям предделителей. А работа предделителей это тоже потребление тока.
Поэтому профессионалы используют и снижение частоты, и режим сна для гибкого управления потреблением микроконтроллера. И у современных микроконтроллеров сложная и разветвлённая система управления тактированием.YRevich
12.02.2017 20:26Совершенно с вами солидарен, когда речь идет о пробуждении-засыпании каждые 10 мс. Даже если при этом собственно действия занимают 100 мкс, все равно за это время ни один датчик раскачаться не успеет. В этом случае одназначна надо гибко совмещать снижение частоты и засыпание, когда паузы большие. Есть такая периферия, которой и пары секунд для выхода на режим недостаточно. Но мы не об этом, а о более простых случаях: не слишком вникающий человек видит снижение потребления, и начинает уверять меня, что если запустить МК от часового кварца, то тут и настанет всем сплошное благолепие. Нет, не настанет, а будет только хуже.
Indemsys
12.02.2017 20:32Абсолютно верно.
В этой статье все так называемые замечания о «грубых ляпах» крайне сомнительны.
Скажем якобы ляп в разделе «Потребление электроэнергии платами Arduino».
Даже минимальный поиск в google за 10 сек показывает что Mini Pro с питанием от USB имеет контроллер на 3,3 В и 8 МГц, а с питанием от внешнего источника 5 В и 16 МГц. Соответствено это и вызывает 2-х кратную разницу в потреблении.
Пожелаю автору глубже вникать в тему прежде чем кого-то обвинять в ляпах.
YRevich
12.02.2017 20:54Не въезжаю, о чем вы, при чем тут гугл и 8-16 МГц. В таблице сравниваются Мини Про 5 В и Мини Про 9В, посмотрите внимательно.
Androniy
12.02.2017 20:50У stm32 2-3 миллисекунды выход из standby режима (в этом режиме периферия не работает, в основном). Уйти и вернуться в stop режим — несколько микросекунд. Выйти из sleep режима — до 10 тактов (при высоких скоростях намного меньше микросекунды). В процессе работы нет никакого смысла использовать standby режим, хотя это и возможно. Так что вы преувеличиваете затраты на переход в низкопотребляющий режим и обратно. Снижать тактовую частоту имеет смысл там, где вы часто ждете тормозную периферию, но глубоко спать не можете, т.к. можете не успеть обработать пришедшие данные. Во всех остальных случаях эффективней работать на максимальной частоте и чаще спать.
Goron_Dekar
13.02.2017 17:42Уйти и вернуться в stop режим — несколько микросекунд.
Это не так.
When exiting Stop mode by issuin
g an interrupt or a wakeup event, the HSI RC oscillator is
selected as system clock.
Это значит, что в stop mode вырубается осциллятор и для того, чтобы оттуда вернуться, нужно врубить HSE, дождаться выхода на режим, врубить PLL, дождаться выхода на режим. Это всё и будут те самые 2 мс.
Выйти из sleep режима — до 10 тактов
Там уже интереснее. Но советую как-либо померить энергопотребление в sleep mode при работающей периферии типа USART + DMA и разной частоте. Разница при снижении частоты всё равно есть, ~15% на каждые 2 раза снижения частоты тактирования.Androniy
13.02.2017 18:36Ну в общем, да, если вам нужен HSE. Генератор запускается за 2 миллисекунды. Плюс еще на остальные расходы менее 1 миллисекунды. В общем случае около 3х миллисекунд получается.
Рассчитать энергопотребление помогает профилирование питания в STM32CubeMX. Возможно, в разных задачах результат будет разный, но в моих случаях уменьшение частоты приводило только к увеличению энергопотребления (по крайней мере по расчетам).Goron_Dekar
13.02.2017 20:22А без HSE максимальной частоты не будет. Значит выход из stop режима на максимальную частоту — 2+ мс.
Про увеличение потребления при уменьшении частоты это интересно. Не могу скачать новый STM32CubeMX, просит регистрацию. Старый считал электропотребление без учёта затрат на раскачку осциллятора. Не уверен, что он считал потребление предделителей. А микроамперметра у меня сейчас нет, померить не могу.
ncix
12.02.2017 23:42В тему или нет, но есть одно скверное (и очень массовое) заблуждение насчет Ардуино — что код в Arduino IDE пишется на каком-то своем специальном языке, похожем на упрощенный С. На самом же деле это самый что ни на есть настоящий С++ с ООП шаблонами и всем остальным, что поддерживает компилятор avr-gcc, который собственно и используется в IDE.
osmanpasha
13.02.2017 07:07Только стандартная библиотека STL там отсутствует почти полностью (видел vector и ещё несколько компонентов), и вместо некоторых компонентов сделаны свои упрощенные аналоги (типа класса String)
osmanpasha
13.02.2017 07:31Странно, а сейчас и vector не могу найти. Видимо, память подводит. В общем, кажись из коробки нет STL совсем. Но есть порт uClibc++
vektory79
Огромное спасибо за комментарий. Надо будет распечатать и вложить прямо в книгу.