Почему я не люблю Arduino

Повышение квалификации

Платформа Arduino как система программирования для микроконтроллеров AVR завоевала заслуженную популярность. Платы Arduino стали очень дешевы (не фирменные конечно, а те, которые делают китайцы и продают на ebay, aliexpress и dx.com), примеров кода очень много, среда программирования и язык хорошо описаны, для большинства электронных устройств и микросхем написаны готовые библиотеки. Однако профессионалы и радиолюбители, которые уже имеют минимальный опыт работы с микроконтроллерами, часто говорят про Arduino с отвращением, и предпочитают использовать традиционные инструменты разработки (avr-libc + gcc, WinAVR, AVR Studio, IAR). Почему?

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

Для того, чтобы понять, в чем тут дело, давайте бросим общий взгляд на принципы программирования в Arduino и на обычном GCC (язык C). Условно назовем программирование на Arduino как AVR Arduino, и традиционное программирование как AVR GCC. Для тестов возьмем обычную Arduino-совместимую плату metaboard [1] (микроконтроллер ATmega328P), попробуем написать для неё код AVR Arduino и код AVR GCC, и подробно разберем, в чем разница.

metaboard-IMG 1402

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

• Среда программирования
• Обзор языка, как построена программа
• Как прошивать программу в память микроконтроллера платы
• Отладка программы
• Цена железа
• Эффективность кода, дополнительные возможности

[Среда программирования]

Закачка и установка среды программирования AVR Arduino никаких вопросов не вызывает. Закачиваете инсталлятор, запускаете, получаете готовую среду разработки. Дистрибутив Arduino IDE 1.0.6 на момент написания статьи 141107 занимал 52.6 мегабайта.

Arduino-IDE-main-window

Для тех, кто не знает, краткая справка: AVR Studio это популярная IDE от Atmel, а WinAVR это тулчейн, т. е. компилятор gcc и библиотеки для AVR. Оба они бесплатные, и должны использоваться совместно. Закачка и установка этих двух компонентов тоже особых вопросов не вызовет, если знаете где их искать (Google безусловно поможет). На сегодняшний день 141107 уже можно установить Atmel Studio 6, в этом случае WinAVR устанавливать не потребуется (тулчейн уже входит в состав Atmel Studio). Я по старинке предпочитаю AVR Studio 4.19, WinAVR и готовые файлы makefile.

AVR-Studio-main-window

В плане простоты установки и использования AVR Arduino однозначно выигрывает. Но в плане удобства использования и функционала Arduino IDE намного беднее.

[Обзор языка: как построена программа]

У нас будет простейшая схема тестового устройства - светодиод через нагрузочный резистор подключен к цифровому порту 13 Arduino, это соответствует ножке порта GPIO PB5 микроконтроллера ATmega328P (подробнее про соответствие нумерации портов Arduino и соответствие этой нумерации ножкам микроконтроллера см. [2]).

ATmega328P-LED-connection

Программа должна на 0.5 секунды выдавать в порт лог. 1 (светодиод загорится), и затем на 0.5 секунды выдавать лог. 0 (светодиод погаснет). В результате получатся мигания светодиодом с частотой 1 Гц.

Программа AVR Arduino (скетч в терминах IDE Arduino), которая просто мигает светодиодом:

				// Переменная для организации интерфейса со светодиодом (LED),
// используется порт 13 Arduino:
int Led = 13;
 
//Подпрограмма предварительной настройки.
void setup ()
{
   pinMode (Led, OUTPUT);     // настройка порта LED как выхода
}
 
// Главный цикл программы.
void loop ()
{
   digitalWrite (Led, HIGH);  // зажечь светодиод
   delay (500);               // задержка на 500 мс
   digitalWrite (Led, LOW);   // погасить светодиод
   delay (500);               // задержка на 500 мс
}

Как видите, для новичка все очень просто и понятно. Программа делится на 2 основные части - предварительная настройка, которая всегда осуществляется в подпрограмме setup, и тело бесконечного цикла, который прокручивается снова и снова, находится в подпрограмме loop. Имена setup и loop зарезервированные, их просто надо запомнить (что довольно просто), и использовать всегда одинаково. Для настройки режима работы ножки порта применяется подпрограмма pinMode, для переключения состояния выхода используется подпрограмма digitalWrite, для задержки подпрограмма delay.

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

Точно такая же программа, которая тоже просто мигает светодиодом, но уже на AVR GCC (AVR Studio):

				//Подключение заголовков, в которых определены порты микроконтроллера,
// и имя подпрограммы задержки:
#include < avr/io.h >
#include < util/delay.h >
//Объявление имени LED для ножки порта, куда подключен светодиод:
#define LED PB5
// Основная функция, где находится главный цикл программы.
void main (void)
{
   //До начала главного цикла всегда делаются предварительные настройки.
   DDRB = (1 << LED);  // настройка порта LED как выхода
   
   //Главный бесконечный цикл программы.
   while(1)
   {
      PORTB |=  (1 << LED);     // зажечь светодиод
      _delay_ms (500);          // задержка на 500 мс
      PORTB &= ~(1 << LED);     // погасить светодиод
      _delay_ms (500);          // задержка на 500 мс
   }
}

Вроде тоже все несложно, но у новичка, который не знаком с программированием, сразу возникает куча непонятностей и вопросов. Что такое #include, что они делают и зачем? Что такое #define, void, main, и почему while? Что такое DDRB, PORTB, и что за странные манипуляции с ними происходят?

Понятно, что гугление даст конечно ответы на все эти вопросы. Кто не боится трудностей, тот разберется. Но если еще добавить, что нужно не забыть в свойствах проекта (либо в makefile) указать тактовую частоту и тип микроконтроллера, настроить опции компиляции... И еще перед этим надо установить саму среду компиляции AVR GCC и научиться делать с нуля проекты (или запускать на компиляцию готовые), найденные в Интернете, то этот снежный ком проблем легко может раздавить новичка. Сложность быстрого старта - одна из причин, почему новички бегут от AVR GCC, и почему так популярна платформа AVR Arduino.

Общая структура программы очень похожа у обоих систем, но очевидно, что у AVR Arduino все сделано намного проще, а у AVR GCC все выглядит для новичка сложнее, но зато для профессионала имеется весь набор возможностей.

[Как прошивать программу в память микроконтроллера]

AVR Arduino. Программа загружается в память микроконтроллера через USB, прямо в среде программирования. Программатор при этом не нужен. Технология загрузки работает на основе программы UART bootloader, которая прошита в память микроконтроллера Arduino. Обмен данными при этом идет через порты 0 и 1, и порт соединен с USB через специальный, заранее установленный на плате чип FTDI (преобразователь Virtual USB COM - TTL RS-232). Ничего настраивать особо не надо, нужно только подключить к компьютеру плату кабелем USB (драйвер FTDI устанавливается при установке Arduino IDE), и выбрать после компиляции в меню Файл -> Загрузить (Ctrl+U).

AVR Studio. Можно так же пользоваться USB-загрузчиками (наподобие USBasp или BootloadHID), но для прошивки надо пользоваться отдельными утилитами - такими как Khazama, AVRDUDE и т. п. Если знать, что и как делать, то никаких проблем нет, но для новичка это не самый лучший выбор.

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

[Отладка программы]

Для обоих систем программирования, и для AVR Arduino, и для AVR GCC сразу доступна система отладки на основе последовательного порта UART. Отличие только в том, что в Arduino все уже готово и настроено, осталось только вставить в программу операторы отладочного вывода и открыть окно монитора, а в случае AVR GCC все настраивать и подготавливать надо самому [5]. Само собой, это обстоятельство тоже переманивает новичков в сообщество Arduino. Так что способ отладки по типу написал - прошил - проверил - не заработало - снова написал - прошил -... доступен как для Arduino, так и для GCC, но у Arduino все существенно проще и все подготовлено заранее.

Зато если у Вас есть отладчик AVR Dragon или AVR JTAGICE mkII, то в среде для AVR Studio для Вас открывается море волшебных возможностей - полноценная отладка и по исходному коду, и по дизассемблированному листингу программы, просмотр регистров и памяти, точки останова, пошаговое выполнение программы! Вместе с отладочным выводом через UART ни о чем больше программисту мечтать не надо, написание программ превращается в удовольствие. Для Arduino это счастье недоступно.

[Цена железа]

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

AVR Arduino. Ассортимент фирменных плат, которые просто "бери и используй" - довольно большой. Однако они достаточно дороги, цена начинается примерно с $30 (за Arduino UNO) и выше. Можно найти и подешевле, но тогда приготовьтесь встретиться со сложностями - либо нет встроенного в плату USB-TTL RS232, либо в плату не прошит загрузчик (для Arduino Nano 3.0 за $6 это обычное дело), либо придется разбираться в настройках и документации.

Примечание: с дешевым железом, которое продается на ebay и в других подобных Интернет-магазинах, часто бывают непреодолимые для новичка трудности. Например, продается Arduino Nano, в которую не прошит загрузчик. Плата абсолютно исправна, определяется на компьютере как виртуальный COM-порт, но вместе со средой Arduino IDE работать отказывается! Для решения проблемы нужно прошить в память микроконтроллера загрузчик Arduino, работающий через UART. Но чтобы загрузчик прошить, его нужно сначала найти в Интернете, или скомпилировать, и затем прошить в память микроконтроллера. И при этом не забыть правильно установить фьюзы. Для тертого спеца это несложно, но у новичка обязательно возникнут проблемы. Так что придется покупать либо дорогую фирменную плату Arduino, либо собирать или покупать программатор, и во всем разбираться самому. Если новичок пройдет этот квест, то среда Arduino ему уже собственно не нужна =).

Если Вы делаете свою платку наподобие veroduino, то ограничены в выборе микроконтроллера - среда Arduino поддерживает не все микроконтроллеры, которые есть у Atmel.

AVR GCC. Тут просто море возможностей. Можно изготовить плату буквально на коленке (см. [6]), и это будет стоить копейки. И конечно же, Вы можете использовать абсолютно любое железо, любые платы, в том числе и самодельные конструкции на AVR - как Arduino-совместимые, так и не совместимые.

[Эффективность кода, дополнительные возможности]

Теперь давайте сравним размер кода, который дает скетч AVR Arduino, и программа AVR GCC на языке C. Обе выполняют свою работу, и выполняют её хорошо, но сколько места при этом занимает код?

Arduino IDE:

	Размер скетча в двоичном коде: 1 090 байт (из 32 256 байт максимум)

AVR GCC (компиляция с оптимизацией по скорости, это установка по умолчанию):

	AVR Memory Usage
----------------
Device: atmega328p
Program: 216 bytes (0.7% Full)
(.text + .data + .bootloader)
Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)

Как видите, результирующий код получается 1090 байт у AVR Arduino, и 216 байт у AVR GCC. Даже для такой простейшей программы GCC по размеру кода в 5 раз эффективнее Arduino! Как говорится, комментарии излишни. Если еще добавить, что у Arduino невозможно настроить никакие опции оптимизации и опции библиотек ввода/вывода (stdio/printf), память катастрофически кончается при попытке создать любую более-менее сложную программу, то понятно, почему у профессионалов одно упоминание про Arduino вызывает кривую усмешку.

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

AVR Arduino. Набор библиотек очень обширный, и с течением времени постоянно пополняется - по мере появления на рынке нового оборудования и устройств. Библиотеки понятны и хорошо документированы. Работа с внутренней памятью EEPROM, сеть Ethernet, сеть WiFi, сотовая связь GSM, файловая система на картах SD, управление сервомашинками, шаговыми двигателями, I2C, UART, цифровой и аналоговый ввод и вывод, различные символьные и графические индикаторы, 1-Wire - все это есть и доступно, можно использовать "из коробки", ничего нигде искать не надо. Для некоторых продвинутых плат, которые имеют достаточно мощный процессор и аппаратный интерфейс USB, также доступны и другие возможности, такие как интерфейс USB и базовое управление задачами (шедулер). Однако нет доступа к исходному коду библиотек. Короче говоря - ешь что дают, и не жалуйся. Иначе и быть не может - тогда вся простота Arduino улетучится как дым. Так что про сложные проекты забудьте.

AVR GCC. С библиотеками, которые можно найти в интернете в виде готового исходного кода, возможностей на порядок больше, чем у Arduino. Однако доступно это богатство в основном только для тех, кто понимает что делает. Вся мощь ядра AVR в Ваших руках - пишите хоть на C, хоть на ассемблере. Бешеное быстродействие AVR и полное управление кодом позволяет реализовать даже такие совершенно невероятные вещи, как программная обработка физического уровня интерфейса USB (я имею в виду такой шедевр программистского искусства, как библиотека V-USB).

Резюме - в прямых руках AVR GCC позволяет делать на порядок более эффективные и более сложные программы, чем Arduino.

AVR Arduino. Примеры готовых проектов/скетчей есть как в самой среде Arduino IDE, так и в Интернете. Поначалу простота и кажущаяся легкость программирования Вас будет очень радовать. Но по мере развития и усложнения задач ничего готового в Интернете Вы уже не найдете, и в программировании постоянно будете натыкаться на грабли и глюки, которые не сможете ни исправить, ни отладить.

AVR GCC. Готовых проектов можно найти намного больше. Возможности AVR GCC с Arduino сравнивать просто смешно. Но это конечно доступно только для тех, кто понял основную кухню GCC.

Из всего вышесказанного не значит, что мне не нравятся платы Arduino. Вовсе нет - они очень удобны, недороги, практичны, их легко купить или даже сделать самому. Как раз платы Arduino я очень люблю, и с удовольствием применяю в разработках. Но мне не нравится именно среда программирования Arduino, и предпочитаю использовать традиционный GCC (AVR Studio или Atmel Studio, или даже Visual Studio [9]).

Выводы: если Вам нужно быстренько состряпать что-то типа светофора или новогодней гирлянды, или если надо как можно проще повторить какой-то готовый проект, то тогда Arduino хорошо подходит. Если же нужно решить задачу максимально эффективно, и Вы хотите как можно больше приблизиться к пониманию - как на самом деле все устроено и работает, то Ваш выбор язык C, тулчейн AVR GCC и даташит на используемый микроконтроллер. Arduino обычно выбирают те, кто готов пожертвовать эффективностью, скоростью кода и своими деньгами в угоду простоте использования железа и легкости программирования.

http://microsin.net/programming/avr/why-i-hate-arduino.html