Altinkaya: турецкие корпуса для РЭА
РадиоЛоцман - Все об электронике

Почему не стоит использовать Arduino для обучения программированию

Журнал РАДИОЛОЦМАН, май 2018

Hack van de dam

Я бы мог начать статью словами «Почему Arduino – отстой» или «Почему Arduino – барахло», что привлекло бы огромный трафик к странице в Интернете. Но я не сделал этого, потому что это просто неправда. Arduino – не «барахло», и сам по себе не один из представителей этого семейства ничем не плох. Просто это не самый лучший инструмент для обучения людей программированию, что зачастую вводит их в заблуждение. Позвольте мне объяснить вам, почему.

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Что такое Arduino?

«Arduino – это открытая платформа для прототипирования электроники, основанная на гибком, простом в использовании оборудовании и программном обеспечении. Она предназначена для новичков, профессионалов и все тех, кто заинтересован в создании интерактивных объектов или сред», – именно так представлена Arduino своими разработчиками [1]. И они правы. Для создания интерактивных объектов или сред проект Arduino подходит идеально. Вам доступно невообразимое количество примеров кода, вы можете с легкостью считывать датчики (работа с которыми в обычном случае, даже при наличии опыта программирования, может занимать от нескольких часов до нескольких дней), и получаете доступ к большой базе пользователей для обсуждения вопросов. Создание интерактивных объектов – это, прежде всего, взаимодействие с человеком. Подключите датчик к исполнительному устройству, создайте новые алгоритмы и экспериментируйте… Однако для обучения программированию или использования возможностей встраиваемой электроники такой подход плох.

Именно в этом и заключается мое недовольство Arduino, когда речь заходит о начальном обучении программированию. Путь изучения микроконтроллеров может быть непростым, но он должен опираться на силу этих маленьких существ. Использование Arduino для изучения программирования подобно использованию Макдональдс для изучения кулинарии; вы получаете еду очень быстро, но не получаете навыков самостоятельного приготовления пищи. Когда вам нужно быстро перекусить, Макдональдс –вполне хороший вариант (спорная мысль, но лишь иллюстрирующая мою точку зрения), но это уж точно не кулинарный класс.

Пять причин, почему (не в порядке важности)

1. Отсутствие проектного пространства, разбиения кода и приличной интегрированной среды разработки

Для меня это большая неприятность. Я понимаю, что не следует перегружать новичков переизбытком опций, но среда Arduino IDE выглядит как насмешка над приличной записью кода. Может быть, нужно преклонить колени, чтобы уговорить их сделать цветовое выделение переменных, но для начала хотя бы дайте возможность просмотра их определений. Посмотрите, как это выглядит в Code::Blocks [2] на Рисунке 1. Другой момент состоит в том, что весь код необходимо писать в одном «эскизе» (скетче). Если нужно написать серьезную программу с функциями, которые будут использоваться позже, то хорошая практика (или даже похвальная) заключается в создании модульных фрагментов кода. Запись всего в один длинный файл идет в разрез с этой целью и стимулирует написание неструктурированного кода, называемого «макароны», с запутанным порядком выполнения и определениями переменных везде и нигде.

Почему не стоит использовать Arduino для обучения программированию
Рисунок 1. Опция поиска определений переменных и их
реализация в среде Code::Blocks.

Общие соображения, касающиеся того, почему так важны заголовочные файлы, очень хорошо изложены на сайте [3]. Кроме того, замечательное руководство по модульному программированию в Си (на английском языке) можно найти в (почитайте посты на форуме). Чтобы получить четкое представление о том, как это делается правильно, загляните, пожалуйста, в подробное руководство по заголовочным файлам в Си, выпущенном MIT [4] (на английском языке):

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

Написанию модульного кода отлично помогает возможность поиска определений и реализаций файлов. Но Arduino IDE не обеспечивает простых способов создания других Си- и h-файлов, а также не позволяет искать определения в своих собственных файлах кода. (Кто сможет сказать, что на самом деле делает функция «digitalWrite»)? Изучая программирование на Си, пожалуйста, научитесь правильно использовать заголовочные файлы.

2. Плохие уровни абстракций, плохие именования

«Язык программирования» Arduino использует множество предопределенных функций для использования периферийных устройств Arduino. Имена многих из этих функций вводят в заблуждение или используют плохие абстракции, просто не описывая того, что они делают. Хорошая аппаратная абстракция экономит время разработчика, плохая абстракция усложняет и запутывает. Вот несколько примеров:

  1. analogWrite(int):
    Функция «записывает аналоговое значение (ШИМ) в порт микроконтроллера». Вы скажете: «Что? ШИМ стал аналоговым?». Он настолько же аналоговый, насколько аналоговая информация на компакт-диске. Сигнал широтно-импульсной модуляции НЕ аналоговый; частота ШИМ Arduino равна «приблизительно» 490 Гц, и нет никаких указаний касающихся того, какой должна быть комбинация RC, чтобы сделать аналоговый сигнал. Это вводит в заблуждение. Сказанного достаточно для управления светодиодом, но это не «аналоговый сигнал», который можно было бы использовать в качестве уставки для аналоговой системы управления.
     
  2. И конечно, если уж вы предоставили возможность генерировать сигнал ШИМ, то хотя бы позвольте установить его частоту.
     
  3. pinMode():
    Я должен признать, что ошибка уже исправлена, но некоторое время назад были доступы только значения «INPUT» и «OUTPUT». Если бы потребовалось получить вход с подтягивающим резистором, пришлось бы еще выполнить функцию digitalWrite() для порта, который только что был сделан входом. Те, кто знают архитектуру AVR, понимают, что тем самым производится запись в регистры DDRx и PORTx, но для новичков включение подтягивающего резистора записью в порт, который только что был сделан входом, выглядит очень странной. Сейчас все исправлено, но для этого потребовалось слишком много времени; функция pinMode() уже использовалась, и нуждалась только в этой дополнительной опции. Здесь не только не было абстрагирования от «железа», но эта функция создавала код, который не мог нормально переноситься на другие микроконтроллеры. (Вероятно, поэтому функция была исправлена в момент появления платы Arduino Due).
     
  4. Переменные:
    Зачем использовать все типы char, int, long и т.д.? Использование stdint (uint8_t, uint16_t, int32, …) даст более правильное понимание и более переносимый код. Тип int – это 16-битная величина для компилятора AVR-GCC, тогда как для компилятора GNU ARM – 32-битная…
     
  5. Отсутствие абстракций и свойств системы:
    progmem. Очень многие используют для отладки сроковые последовательности, которые сохраняются в ОЗУ. Фиксированные строки могут храниться во Flash-памяти и считываться из нее; эти функции присутствуют в пакете avr-libc. Поэтому я думаю, что 90% людей, сказавших «память Arduino переполнилась», были бы рады добавлению какого-нибудь ключевого слова.

3. Ужасная документация

Документация по функциям в Arduino ничего не сообщает о том, какие в них используются периферийные модули (не говоря уж о более глубоком уровне), скрывая это от обычных пользователей. Раньше я использовал openFrameworks. По крайней мере, с их средой разработки можно в коде посмотреть, как реализуются те или иные функции. С Arduino вы работаете вслепую. Можно ли обращаться к таймеру из функции servo()? Будет ли отправка строки в последовательный порт блокировать выполнение программы? Будет ли функция analogWrite() влиять на другие функции времени? В руководстве по Arduino вы об этом не прочитаете.

В справочнике по Arduino также описывается её «язык программирования». В базовой структуре используются некоторые функции Си и Си++, описанные, опять же, непонятно. «Arduino» – не тот язык, который вы не постеснялись бы указать в своем резюме. Чтобы считаться программистом, надо уметь программировать на Си! Сходства и различия этих функций неясны, что приводит к путанице при переходе на другие микроконтроллеры или в среды разработки ANSI-C. Где используются классы? Где используются структуры? Я понимаю, что Arduino не хочет отпугивать новых пользователей, но как же они станут «продвинутыми» пользователями?

4. Отсутствие доступа к периферии и напрасная трата ресурсов

Я знаю, что, смешав скетч с «реальным» Си и используя регистры Atmel, вы можете получить доступ к периферии Arduino и микроконтроллера. Но, если уж вы продвинулись так далеко, пожалуйста, доставьте себе удовольствие и напишите собственный код, где вы будете знать, какая периферия используется и каким образом. Начиная программировать микроконтроллеры, я был поражен скоростью их работы (PIC, 8 МГц). Написание кода, оптимизированного для периферии, использование прерываний для параллельного выполнения максимально возможного числа задач – все это показало мне, какая сила заключена во встраиваемых устройствах и компьютерах. Поэтому, с моей точки зрения, использование Arduino для освоения программирования встраиваемых систем отнимает бесценную возможность научиться созданию по настоящему эффективных и мощных приложений.

У меня на работе многие пытаются писать на Arduino циклы управления. Используя функцию micros(), они отмечают время начала функции loop(), выполняют свои задачи, а затем снова опрашивают функцию micros() для ожидания завершения времени цикла. Это крайне расточительное использование ресурсов микроконтроллера, которые могли бы быть полезными для добавления новых задач, или для процессов, которые не могут работать в одной системе отсчета времени. Одно лишь это делает mbed лучше Arduino. Реализация функции Ticker, хотя и не лишена недостатков, но, по крайней мере, использует синхронизацию на основе прерываний, оставляя основной цикл для «медленных» задач.

5. Отсутствие «реальной» отладки

Когда в Arduino использовался ATmega328, у разработчика не было порта отладки. Теперь появилась серия плат Due, и отладочные порты имеют микроконтроллеры Microchip (Atmel) от серии tiny (DebugWire) до серии XMEGA (PDI и JTAG), однако пользователям Arduino этот мощный набор инструментов по-прежнему недоступен. Думаю, что при использовании правильно настроенного отладчика время разработки приложений у меня снижается процентов на 30. Поэтому ARM интересен хотя бы тем, что может использовать реализацию OpenOCD, предоставляющую разработчику широкие возможности отладки и программирования. Несколько точек останова дают очень быструю индикацию выполняемого кода и возникающих ошибок. Меня приводят в восторг все новые наборы разработки ARM с интегрированным аппаратным отладчиком. Добавьте поддержку arm-gdb и OpenOCD, и вы на вершине! Настройка этих инструментов может оказаться немного затруднительной, но полностью стоит того, чтобы попытаться создать достойное встроенное приложение.

Какова же альтернатива?

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

  • Scratch [5]. Это веселый и легкий инструмент для детей и подростков, желающих освоить программирование, который даже поддерживает возможность разбиения кода. Конечно же, он не предназначен для встраиваемых систем, но для детей это хороший способ понять, что такое программа.
     
  • Mbed [6]. Онлайн компилятор с открытым кодом, поддерживающий множество модулей и плат на микроконтроллерах различных производителей, включая NXP, Analog Devices, STMicroelectronics, Nordic Semiconductor, Ublox, который отлично подходит для новичков, так как не требует установки инструментальных средств. С компилятором предлагается огромный архив примеров, которые можно легко импортировать в свой проект. Да, речь именно о проектах. Вам дается возможность полного контроля над исходным кодом и его структурой, включая онлайн управление версиями. Предоставляемый mbed код – это Си++, использующий классы и перегрузку операторов, что лично меня, воспитанного на ANSI-C, первоначально немного сбивало с толку, однако документация, которую вы тоже найдете в своем проекте, прозрачна и доступна. Использование периферии нельзя назвать простым, но можно косвенно использовать таймеры для генерирования прерываний по времени, и, опять же, все это хорошо документировано. Вам не нравятся онлайн сервисы? Хорошо, можно работать оффлайн. Единственный, на мой взгляд, недостаток mbed – отсутствие возможности отладки с использованием точек останова и наблюдения.
     
  • Компилятор AVR-GCC/WinAVR [7] с микроконтроллерами серии Xmega. Пакет программ AVR-GCC (с библиотеками avr-libc) имеет солидную репутацию и очень хорошую базу пользователей [8]. Причина, по которой я рекомендую серию Xmega, – это «фантастическая» документация. Правда, из-за того, что для каждого периферийного устройства есть отдельное указание по использованию, Atmel Studio имеет очень «раздутые» размеры, но зато предоставляет реальный набор мощных инструментов для разметки кода, отладки (точки останова) и симуляции (просмотр и изменение битов регистров периферии). При использовании отладчика Dragon (переоцененного) можно работать с устройствами, имеющими память программ до 32 Кбайт. Конечно, начинать с такого набора без каких-либо знаний в области программирования будет тяжело, но всегда можно найти информацию в Интернете или попросить помощи у знающего друга. При чтении указаний по применению у меня возникает ощущение, что можно создать систему, которая после настройки все будет делать самостоятельно: DMA будут отправлять полученные значения АЦП в память, система событий будет запускать таймеры для запуска ЦАП, и тому подобное. Поработать придется довольно много, но вы сделаете действительно встраиваемую систему. Это как самостоятельно приготовить суши вместо того, чтобы идти в Макдональдс…
     
  • Использовать отладочные платы Launchpad/STM32/… [9]. Другие ARM платы. И да, и нет… Конечно, ARM – это будущее, но начинать с этого, думаю, довольно сложно. Кроме того, при использовании бесплатных инструментальных наборов вам придется потратить уйму времени на их настройку. Правда, это полезно; оценочная плата с интегрированным отладчиком (8 евро за плату серии STM32F0 Discovery [10] – не сравнить с продуктами Atmel/Microchip), и еще что-то, и в своем резюме вы сможете указать, что работали с ARM. Однако документация в основном посредственная и пугающе объемная. Кроме того, набор опций в компиляторах и средах разработки настолько велик, что порой трудно разобраться, почему программа не компилируется.

Заключение

Arduino – отличный «фаст фуд программирования» – легкодоступный, дающий быстрый результат и иногда даже изящный. Но для того, чтобы узнать «как программировать» или «как добиться максимальной производительности микроконтроллеров», или же для использования в качестве первого шага Arduino не подходит. Для этого изучайте настоящую кулинарию; начинайте с нуля – с кипящей воды, затем кладите туда scratch, готовьте картофель с mBed и делйте суши с Atmel, чтобы в конечном итоге выйти на фристайл с отладочными платами ARM.

Ссылки

Перевод: Vadim по заказу РадиоЛоцман

На английском языке: Why Arduino is not the right educational tool

Электронные компоненты. Бесплатная доставка по России
Для комментирования материалов с сайта и получения полного доступа к нашему форуму Вам необходимо зарегистрироваться.
Имя
Фрагменты обсуждения:Полный вариант обсуждения »
  • "Единственный, на мой взгляд, недостаток mbed – отсутствие возможности отладки с использованием точек останова и наблюдения." Здесь автор глубоко заблуждается, Eclipse + обвязка в виде GNU ARM Tools + "mbed export" отлично все решают, позволяя выполнить полноценную отладку
  • AkaU, эта заметка была написана более 5ти лет назад. На mbed.org и github хранится история релизов начиная с 5.1.0. А всё, что было пять лет назад и больше - это летопись по меркам роста возможностей софта. Так что, быть может, автор и не ошибался в 2013м году.
  • "Бесплатный" софт Arduino только для начинающих. Подробно от первых рук [url]http://tim4dev.com/2016/07/arduino-advantages-disadvatages/[/url] "...Преимущества Ардуино Готовность к использованию (Ready to Use) — является самым большим плюсом Arduino. Вы уже имеете «на борту» регулятор питания, микроконтроллер, программатор, интерфейсы для подключения устройств, и программные библиотеки. [COLOR="Red"]Вы не должны думать о программировании[/COLOR] микроконтроллера или [COLOR="red"]способах подключения периферии[/COLOR]. [COLOR="red"]Вы не должны изучать регистры микроконтроллера, диаграммы, блок-схемы и набор инструкций[/COLOR]. Вы [COLOR="red"]просто подключаете Arduino к USB порту ПК[/COLOR] и [COLOR="red"]делаете революцию в мире[/COLOR] «интернет вещей»..." Из ссылки - [url]https://www.rlocman.ru/review/article.html?di=138878[/url] "...Минусы Arduino (Что ужасно): Arduino IDE – это самый худший и самый непригодный редактор кода после «Блокнота». В один день [COLOR="red"]вы переключитесь на достойный внешний редактор[/COLOR], однако вам [COLOR="red"]все равно придется оставить открытой Arduino IDE [/COLOR]для программирования устройства; Загрузчик Arduino. Для того, чтобы завершить какое-либо Arduino-устройство, вам придется вручную запрограммировать загрузчик в каждый «чистый» микроконтроллер ATmega. Это [COLOR="Red"]уменьшает доступный объем Flash-памяти программ на 2 КБайта[/COLOR]; Всего несколько вариантов: если вы будете использовать официальные платы Arduino, [COLOR="red"]то выбрать[/COLOR] вы сможете [COLOR="red"]только из вариантов с 30 Кбайт или 254 КБайт встроенной памяти программ[/COLOR]. [COLOR="red"]Что будет[/COLOR], [COLOR="red"]если ваш код занимает, скажем 42 КБайта[/COLOR]? Единственный выбор – использование клона Sanguino, который не полностью совместим с Arduino; [COLOR="red"]Нет простого способа изменить тактовую частоту,[/COLOR] не так ли? Модель микроконтроллера с питанием 3.3 В и тактовой частотой 8 МГц может безопасно работать на частоте 12 МГц; Функция digitalWrite() выполняется за 56 циклов (хотя автором был получен результат в 400 циклов). По крайней мере, это легко выяснить и перейти к использованию прямого доступа к портам (второй элемент для изменения, после Arduino IDE). Как правило, [COLOR="red"]Arduino не очень удобна для написания эффективного кода[/COLOR]; [COLOR="red"]Вы не сможете (по крайней мере, просто) отключить библиотеку последовательной коммуникации[/COLOR], используемую по умолчанию, чтобы использовать TX и RX прерывания, независимо от того, была она запущена, или нет; [COLOR="red"]Подпрограмма обслуживания прерывания по переполнению таймера запускается через каждые 16000 циклов в фоновом режиме[/COLOR]. Это сделано для работы функций millis() и micros(),[COLOR="red"] даже когда они не используются[/COLOR]; Пустой Arduino проект для платформы Arduino UNO занимает 466 Байт и 666 Байт для Arduino Mega2560. Дополнительное расходование ресурсов не устраивает многих, в том числе и автора статьи. Также неприятно видеть ошибки компиляции проекта, связанные с вышеописанными изменениями; Последнее, но не менее важное – [COLOR="red"]среда разработки Arduino, без сомнения, «скрывает» важные аспекты архитектуры микроконтроллера: регистры, прерывания и таймеры[/COLOR]. Их знание просто необходимо..." Из сказанного можно сделать следующий вывод - "Новизна" Arduino состоит в "простоте" использования, но взамен "программист" не может контролировать и использовать ресурсы микроконтроллера. Следовательно, на платах Arduino разработать приличную программу для профессионального применения невозможно...
  • Совершенно согласен. От Arduino проектов веет игрушечностью. Полив цветов, который можно обеспечить и простейшим таймером на логике; управление роботизированной рукой, которая вообще не имеет практического применения. Единственный известный мне серьёзный проект на Arduino - это устройство управления 3D принтером, например [URL="https://www.repetier.com/firmware/v092/index.php"]https://www.repetier.com/firmware/v092/index.php[/URL]. Но он противоречит концепции Arduino. Это не скетч, а хорошо структурированный проект, с заголовочными файлами, разбиением на классы и модули. Совместимость с Arduino формальная, компилируется в Arduino IDE. HAL собственный, Arduino библиотеки не использует.
  • Ардуино не является частью элементной базы типа МИКРОКОНТРОЛЛЕР. Это некоторый элемент вида "черный ящик" с собственной аппаратной начинкой и минимальными "добавками" для обеспечения функционирования инструментов (дополнительных расширенных функций) IDE. Тут управление на уровне регистров и ассемблера неуместно - его заменяет вариант языка высокого уровня. В противном случае придется детально изучать не только сам МК, установленный на платке, но и особенности построения IDE "на глубоком уровне" что явно не одно и то же по сравнению с изучением "чистого МК". При том, что не отменяются и возможности более подготовленных специалистов "покопаться поглубже". Просто необходимо принять концепцию работы с "черным ящиком" в пределах предоставляемого производителем IDE референс-описания предоставляемых той IDE средств ([url]https://www.arduino.cc/reference/en/[/url]). А кому охота непосредственно с МК работать - берем ассемблер. Далее можно и Си. Точно так же на сегодня вряд-ли кто из большинства пользователей-разработчиков простейшего ПО для компьютеров будет писать что-то под ассемблером, минуя не только операционную систему но и биос - работая напрямую с железом материнки и прочей начинкой. ... Исходя из вышеизложенного... Действительно ардуинка по классу ближе к простейшим компьютерам и/или системе-на-кристалле, чем к классическим "истинным микроконтроллерам". По сему и начинать с нее для желающих в дальнейшем работать с "чистым железом" вида МК не слишком удобно. Скорее наоборот - выгодно использовать подобные ардуино устройства как мост между прикладными МК класса "периферия с мозгами" и полноценными компьютерами и/или сложными сетевыми системами обработки стандартизированных потоков данных.