Программирование AVR Arduino: что там внутри? (FAQ) Tue, March 19 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Arduino: что там внутри? (FAQ) Печать
Добавил(а) microsin   

Рассматриваются разные вопросы использования Arduino.

На официальном сайте Arduino есть хороший ответ на этот вопрос. Здесь я просто выскажу свое мнение.

Arduinо, как платформа разработки, стала популярной благодаря хорошо сбалансированной аппаратной архитектуре (физика) и выбранной модели продвижения (идея). На рисунке схематично показана структура системы программирования Arduino.

Arduino-IDE-inside

Пояснения к рисунку: AVR GCC это бесплатный компилятор с языка C/C++ (в результате компиляции получается двоичный файл программы пользователя с расширением HEX, подробнее см. [10]). AVRDUDE это бесплатная утилита программатора, которая передает загрузчику микроконтроллера (он стоит на плате Arduino, обычно это микроконтроллер ATmega328P) код программы пользователя в виде HEX-файла.

[Физическая (программно-аппаратная) сторона вопроса]

Arduino = загрузчик + AVR + библиотеки, инструментарий

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

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

Библиотеки и инструментарий. Компания Atmel вместе сообществом GNU GPL много сделали для поддержки платформы AVR со стороны программного обеспечения. Появился базовый бесплатный инструментарий (AVR Studio, AVR GCC, avr libc, WinAVR). Также появилось множество бесплатного инструментария и библиотек для него под разные платформы разработки - Windows, Linux, Mac. Все это было взято за основу, и послужило на благо популярности среды разработки Arduino.

[Идейная сторона вопроса]

Arduino = простота + открытость + гибкость

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

Открытость. Все программное и аппаратное обеспечение Arduino - открытое, причем программное обеспечение не только открытое, но еще и бесплатное. Бесплатны и среда разработки Arduino, и инструментарий, и библиотеки. Вы можете использовать все это по своему усмотрению без ограничений, если конечно соблюдаете условия свободной лицензии GNU GPL.

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

Я не буду здесь перечислять официальные платы Arduino - их список можно найти как в самой среде разработки (Сервис -> Плата), так и на официальном сайте arduino.cc. Сначала я остановлюсь на платах, которые есть на ebay, а потом о платах - кандидатах на самостоятельное изготовление.

[Полные аналоги, которые можно купить на ebay]

Эти платы примерно в 3..10 раз дешевле официальных. Но хочу предупредить - частенько китайские платы попадаются без прошитого загрузчика, поэтому у новичков с ними бывают проблемы. Плата нормально определяется при подключении через USB, но из среды разработки не программируется! Если у Вас есть программатор ISP, то Вы легко можете "починить" такую плату.

Платы Arduino продаются не только на ebay.com. Есть смысл поискать их также на dealextreme (dx.com) и на aliexpress.com, однако ассортимент там обычно меньше, чем на ebay. Как искать: введите в Google поисковый запрос вида Arduino site:домен_интернет_магазина, например:

Arduino site:ebay.com

Для интернет-магазинов dealextreme и aliexpress домены будут соответственно dx.com и aliexpress.com. Для уточнения поиска вводите в строку запроса полное название платы:

Arduino Mega 2560 site:ebay.com

В таблице перечислены платы - аналоги официальных плат Arduino с кратким описанием их отличий.

Таблица 1. Аналоги официальных плат Arduino.

Название платы Внешний вид Мин. цена, $ AVR Загрузчик Описание
Arduino Uno ArduinoUno R3 4 ATmega168, ATmega328 Arduino UART Самая популярная плата, полностью совместимая и по форм-фактору (подходят все шилды), и по программному обеспечению. Мост USB-UART бывает реализован как на чипе FTDI, так и на отдельном микроконтроллере ATmega16U2. Основной контроллер AVR может быть как в корпусе DIP28, так и в корпусе TQFP32.
Arduino Diecimila ArduinoDiecimila 15 ATmega168, ATmega328 Arduino UART Близняшка платы Arduino Uno - ничем принципиально не отличается, кроме завышенной цены.
Arduino Nano ArduinoNano-V3 0 2.7 ATmega328 Arduino UART Миниатюрная платка, полностью программно совместимая, однако из-за "нестандартного" форм-фактора шилды подключать можно только проводами.
Arduino Mega 2560 arduinomega2560 r2_front 10.6 ATmega2560 Arduino UART Полноразмерный форм-фактор, плата с расширенными возможностями, у нее больше портов ввода-вывода.
Arduino Leonardo ArduinoLeonardo 13.5 ATmega32U4 Atmel DFU Полноразмерный форм-фактор. Интерфейс USB подключен напрямую к микроконтроллеру, без промежуточного моста.
Arduino Leonardo Pro Micro ArduinoLeonardo-Pro-Micro 6.6 ATmega32U4 Atmel DFU Миниатюрная платка, урезанный (по размеру) аналог Arduino Leonardo. Шилды можно подключить только проводами.
AVR-USB32U4 AVR-USB32U4-top-IMG 2310 11 ATmega32U4 Atmel DFU Эта платка является аналогом Arduino Leonardo Pro Micro. Заказать её можно только на сайте microsin.net. Отличительная особенность платы - наличие макетных полей, на которых можно собрать свою радиолюбительскую конструкцию.
Adafruit Atmega32u4 Breakout Board Adafruit-ATmega32u4-Breakout-Board-pic2 20 ATmega32U4 Atmel DFU По схеме примерно то же самое, что и AVR-USB32U4.
Teensy 2.0 Teensy-2 0 16 ATmega32U4 Atmel DFU То же самое, что и AVR-USB32U4, но меньше габариты, и отсутствуют поля для макетирования.

[Неполные аналоги]

Неполные аналоги отличаются тем, что у них нет на борту аппаратного моста USB-UART. Поэтому для работы с ними (загрузки кода, использования Serial Monitor) нужно использовать отдельные переходники USB - TTL UART [2].

Особого внимания заслуживает платка metaboard. Она также сделана без аппаратного моста USB-UART. Но переходник USB - TTL UART для загрузки кода ей не нужен, потому что она загружается через свой собственный программный USB, основанный на замечательной библиотеке V-USB. Платка metaboard замечательна тем, что она недорогая, схема у неё простая, и она замечательно подходит для самостоятельной сборки. В отличие от стандартных плат Arduino, интерфейс USB у платы metaboard многофункционален - его поведение в операционной системе полностью зависит от пользовательского программного обеспечения, прошитого в память микроконтроллера.

Таблица 2. Функциональные аналоги плат Arduino без встроенного аппаратного моста USB-UART.

Название платы Внешний вид Мин. цена, $ AVR Загрузчик Описание
Arduino Pro Mini ArduinoProMini 4 ATmega328 Arduino UART То же самое, что и Arduino Nano, но без моста USB-UART.
Arduino Fio ArduinoFio 25 ATmega168, ATmega328 Arduio UART То же самое, что и Arduino Pro Mini, но другой форм-фактор. Моста USB-UART нет, и на мой взгляд цена платы неоправданно завышена.
Metaboard metaboard-IMG_1402.JPG 9 ATmega328 USBasp При использовании metaboard со средой разработки Arduino есть отличия, касающиеся загрузки кода, использования портов PD2 и PD4, а также интерфейсов USB и UART. На плате metaboard есть макетное поле для сборки собственной схемы. Возможностей у интерфейса USB больше, чем у стандартных плат Arduino. Подробнее см. [3] и FAQ [4] "Чем metaboard отличается от стандартного Arduino?".

[Самодельные платы]

К самодельным платам, которые могут стать Arduino-совместимыми, могут стать любые устройства с микроконтроллером AVR, в которые прошит UART-загрузчик. Больше всего подойдут для этой цели микроконтроллеры ATmega168 и ATmega328, потому что они выпускаются не только в корпусах TQFP, но и в корпусах DIP - наиболее удобных для любительской сборки.

Я уже упоминал metaboard как отличного кандидата для самостоятельной сборки. Также есть интересная разработка, основанная на макетной плате veroboard - veroduino [5].

Таблица 3. Кандидаты на самостоятельное изготовление платы Arduino.

Название платы Внешний вид Мин. цена, $ AVR Загрузчик Описание
Veroduino veroduino-stripboard-layout 1 ATmega328 Arduino UART По схеме все то же самое, что и Arduino Pro Mini.

Загрузчик (bootloader) - одна из основных вещей, что отличает Arduino от простого микроконтроллера AVR компании Atmel. Когда Вы собираете свою плату, или когда случайно купили на ebay плату, не прошитую загрузчиком, то Вам нужен внешний программатор ISP, чтобы прошить в память микроконтроллера загрузчик. Но когда Вы прошили загрузчик, то можно программатор ISP положить на полку - больше он не понадобится (за исключением каких-то специальных случаев), потому что дальше перешивать память программ микроконтроллера удобнее с помощью загрузчика.

Загрузчик [6] это по сути маленькая программа, предназначенная для только одной цели - перепрошить микроконтроллер программой пользователя. Загрузчик размещен в старших адресах пространства памяти программ (FLASH), а программа пользователя - в младших адресах (начиная с нулевого адреса). На рисунке показан типичный пример распределения памяти программ (FLASH) микроконтроллера ATmega328.

Arduino-ATmega328-Bootloader-Memory-Map

Примечание: если у Вас есть программатор ISP [9], то Вы можете настроить среду разработки Arduino так, чтобы использовать для загрузки именно программатор, а не bootloader. Достоинство такого метода загрузки в том, что Вы можете полностью задействовать всю доступную память программ (FLASH) микроконтроллера (потому что загрузчик уже не используется, и его область памяти программ свободна для использования).

Микроконтроллер Arduino сконфигурирован фьюзами так, чтобы при запуске системы (включение питания, сброс) управление всегда получал загрузчик. Затем загрузчик некоторое время ждет (1..2 секунды) загрузки программы пользователя, и если загрузка не началась, то запускает программу пользователя (передает управление на адрес 0). Таким образом, всегда можно при желании перезаписать программу пользователя, и тем самым обновить или полностью изменить функционал устройства. Код загрузчика при этом остается нетронутым.

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

[На что нужно обратить внимание при программировании загрузчика]

Чтобы записать загрузчик, Вам обязательно нужен внешний ISP-программатор [9]. Программатор обычно подключается к программируемой платой Arduino через 6-выводный коннектор ISP, который обычно всегда установлен на плате Arduino. При подключении коннектора убедитесь, что он ориентирован правильным образом. Если есть сомнения при подключении, то обратитесь к схеме платы и её описанию.

Загрузчик можно записать прямо из среды разработки Arduino (Tools -> Burn Bootloader), перед этим нужно сначала выбрать тип программатора и тип платы в меню Tools.

Выбор загрузчика. Поскольку могут быть различные варианты реализации целевой системы - может быть применена разная модель микроконтроллера (ATmega168, ATmega328, ATmega32U4 и т. п.). Загрузчики для разных моделей микроконтроллеров могут быть несовместимыми друг с другом.

Частота кварцевого резонатора. Обязательно убедитесь, что прошиваемый Вами загрузчик точно соответствует рабочей частоте системы. Рабочая частота микроконтроллера обычно зависит от конфигурации фьюзов и от частоты внешнего кварцевого или керамического резонатора (чаще всего применяют кварцевые резонаторы на 8 или 16 МГц, но могут быть и другие варианты).

Фьюзы. Для правильного функционирования загрузчика важны 2 аспекта, которые конфигурируются фьюзами - выбор размера секции загрузки (фьюзы BOOTSZ1, BOOTSZ0), разрешение работы загрузчика (фьюз BOOTRST), а также конфигурирование тактовой частоты (фьюзы, управляющие генератором тактовой частоты и прескалером - CKDIV8, SUT1, SUT0, CKSEL3..0).

Если Вы неправильно прошьете фьюзы BOOTSZ1, BOOTSZ0, BOOTRST, то код загрузчика не будет запускаться, и загрузчик работать не будет. Точно также если Вы неправильно сконфигурируете фьюзами тактовый генератор и прескалер, то микроконтроллер может заработать на той частоте, на которую загрузчик не рассчитан, и работоспособность загрузчика также будет нарушена. Для вычисления правильного значения фьюзов Вам поможет калькулятор фьюзов [7].

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

Таблица 4. Загрузчики Arduino UART.

AVR Тактовая частота Прошивка Размер секции загрузки, байт Фьюзы (HEX)
ATmega8 8 ArduinoBOOT-mega8-8MHz.hex 1024 HFUSE=CA LFUSE=DF
16 ArduinoBOOT-mega8-16MHz.hex
ATmega168 8 ArduinoBOOT-mega168-8MHz.hex 2048

HFUSE=DD
LFUSE=E2
EFUSE=00

16 ArduinoBOOT-mega168-16MHz.hex
ATmega328 8 ArduinoBOOT-mega328-8MHz.hex 2048 HFUSE=DA
LFUSE=FF
EFUSE=05
16 ArduinoBOOT-mega328-16MHz.hex 2048

Прошивки загрузчиков Arduino можно найти в папке, где установлена система разработки Arduino, обычно это папка с полным путем наподобие c:\Program Files\Arduino1.0.6\hardware\arduino\bootloaders. Там же можно найти исходный код загрузчиков. Также готовые прошивки и исходный код всех загрузчиков можете скачать по ссылке [8], см. папку arduino\bootloaders\HEX архива, и ищите там имена файлов прошивок, указанные в таблицах 4, 5, 6 (имя файла прошивки указано в столбце Прошивка).

Таблица 5. Загрузчики Atmel DFU.

AVR Тактовая частота Прошивка Размер секции загрузки, байт Фьюзы (HEX)
ATmega32U4 8 BootloaderDFU-mega32u4-8MHz.hex 4096 HFUSE=D8
LFUSE=DE
EFUSE=F3
16 BootloaderDFU-mega32u4-16MHz.hex

Таблица 6. Загрузчики USBasp.

AVR Тактовая частота Прошивка Размер секции загрузки, байт Фьюзы (HEX)
ATmega168 12 USBaspLoader-mega168-12MHz.hex 2048 HFUSE=D6
LFUSE=DF
EFUSE=00
16 USBaspLoader-mega168-16MHz.hex
20 USBaspLoader-mega168-20MHz.hex
ATmega328 12 USBaspLoader-mega328-12MHz.hex HFUSE=DA
LFUSE=F7
EFUSE=03
16 USBaspLoader-mega328-16MHz.hex
20 USBaspLoader-mega328-20MHz.hex

[Исходный код загрузчиков]

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

В таблице я привел описание самых популярных загрузчиков, которые используются в Arduino-совместимых платах. Исходный код загрузчиков вместе с готовыми прошивками можно скачать по ссылке [8].

Таблица 7. Разновидности загрузчиков, которые можно использовать для платформы разработки Arduino.

Название AVR Описание
Arduino UART ATmega8, ATmega168, ATmega328 и другие Используется для большинства плат Arduino, когда код загружается через мост USB-UART.
Atmel DFU ATmega32U4 и другие Применяется для случаев, когда микроконтроллер AVR имеет на борту аппаратный интерфейс USB. Загрузчик основан на протоколе Atmel DFU Flip и открытой библиотеке LUFA.
USBasp ATmega168, ATmega328 Применяется для плат metaboard. Загрузчик основан на открытой библиотеке V-USB, эмулирует поведение популярного программатора USBasp.

Как компилировать. Для компиляции Вам потребуется тулчейн AVR-GCC, доступный для большинства операционных систем - Linux, Mac OS, Windows. На операционной системе Windows тулчейн можно получить, если скачать и установить пакет WinAVR или среду разработки Atmel Studio.

Компилируется загрузчик командами утилиты make. Обычно для этого нужно зайти в каталог с исходным кодом загрузчика, и выполнить 2 команды:

make clean
make hex

После этого в текущем каталоге появится файл с расширением HEX - готовая прошивка загрузчика, которую нужно записать в память микроконтроллера с помощью обычного ISP-программатора [9] (не забудьте также правильно установить фьюзы микроконтроллера!).

Инструкции по компиляции и настраиваемым опциям можно обычно получить, изучая содержимое файла Makefile проекта загрузчика, и сопутствующие файлы документации readme.txt.

[Версии загрузчиков Arduino UART]

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

Текущие загрузчики (например те, который поставляются с Arduino 0009) главным образом одинаковы для плат Arduino Diecimila и Arduino NG (с Atmega169). Оба работают на скорости 19200 и занимают 2 килобайта памяти программ ATmega168. Различие у них только в том, сколько загрузчик ждет поступления кода программы, и количество вспышек светодиода (pin 13 LED), когда загрузчик запускается. У Arduino Diecimila используется автоматический сброс, поэтому для этой платы загрузчик ждет очень малый интервал времени (меньше секунды), и светодиод у этого загрузчика мигает только 1 раз. Загрузчик Arduino NG ждет 6..8 секунд (потому что плата сбрасывается вручную при загрузке), и светодиод мигает 3 раза при старте загрузчика.

В распространяемых платах загрузчик Arduino NG имеет незначительные отличия. В нем разрешен внутренний pull-up резистор на выводе 6, и не разрешен внутренний pull-up резистор на выводе RX. Также не делается таймаут при приеме неправильных данных, поэтому если Вы начнете передавать данные в плату сразу после сброса платы, то Ваш скетч никогда не запустится (см. вопросы "Почему мой скетч не запускается ...").

Загрузчик платы Arduino BT делает некоторые операции для настройки модуля Bluetooth.

Загрузчик для ATmega8 занимает всего лишь 1 килобайт памяти программ. Он не отсчитывает таймаут при приеме неправильных данных. Поэтому для передачи данных в плату после сброса Вам нужно подождать 6..8 секунд, пока не запустится скетч.

Некоторые древние версии загрузчиков работают на скорости 9600 бод вместо 19200. Чтобы код скетча мог загружаться с таким загрузчиком, Вам нужно поменять на 9600 переменную serial.download_rate в файле настроек preferences.txt.

ADABOOT. Продвинутый загрузчик, поставляемый с Arduino-совместимыми платами Wulfden Freeduino Kits. Его код основан на коде загрузчика Arduino UART. "Lady Ada", Limor Fried из Adafruit Industries, сделала множество исправлений и добавлений в код загрузчика с целью получения универсальности (код загрузчика работает в любой версии Arduino IDE, скетчи запускаются сразу после включения питания, скетчи запускаются сразу после загрузки). Последние ревизии Brian Riley унифицировали исходный код для микроконтроллеров ATmega168, ATmega328 и ATmega644, так что получился один файл исходного кода и один файл makefile. Добавлено мигание светодиодом pin 13 LED, индицирующее процесс загрузки. Этот загрузчик можно использовать на старых, новых (и самостоятельно изготовленных) платах, как оборудованных, так и не оборудованных функцией автосброса (со средой разработки Arduino-0009 и платами Arduino Diecimilia).

Дополнительную информацию по изменениям кода загрузчика можно найти на сайте Lady Ada (см. Bootloader for the Atmega328 site:learn.adafruit.com). Исходный код ADABOOT можно загрузить на сайте разработчика (см. ADABOOT - an ATmega Arduino(tm) compatible bootloader site:wulfden.org), или в одном архиве [8].

[Пример конфигурирования загрузчика Arduino UART]

Процесс получения прошивки загрузчика состоит из предварительного конфигурирования Makefile, где настраиваются опции (если это необходимо) и последующей компиляции командами make clean и make. Конечно же, для компиляции у Вас должен быть установлен тулчейн (компилятор AVR GCC и библиотеки). На операционной системе Windows тулчейн можно получить, если установить пакет разработки WinAVR или Atmel Studio.

Когда нужно получить загрузчик для Arduino, то чаще всего (в зависимости от типа платы или Вашей конструкции) это микроконтроллер ATmega328, или реже ATmega168, ATmega8, ATmega32U4. Поэтому сначала нужно выбрать, какой загрузчик использовать. Почти все загрузчики можно найти в папке установки Arduino c:\Program Files\Arduino1.0.6\hardware\arduino\bootloaders, распределенные по подкаталогам atmega8, atmega и другим.

Выбор загрузчика. Если Вам нужен загрузчик для ATmega8, то его исходный код и Makefile находится в папке atmega8. Если нужен загрузчик для ATmega168 или ATmega328, то см. папку atmega. Если нужен загрузчик для ATmega32U4, то его можно найти в библиотеке LUFA, см. папку Bootloaders\DFU.

Примечание: исходный код и прошивки загрузчиков можно скачать по ссылке [8].

Конфигурирование загрузчика для ATmega8. Зайдите в папку atmega8, и откройте текстовым редактором файл Makefile. Вам нужно проверить следующие опции:

• DIRAVR. Эта опция указывает на каталог установки тулчейна (в этом каталоге находится папка bin с исполняемыми файлами для компилятора и других утилит, и папка include для заголовочных файлов библиотек). Если у Вас установлен тулчейн WinAVR, то значение этой опции должно быть наподобие c:\WinAVR-20100110\avr. Если у Вас установлен тулчейн в составе Atmel Studio, то значение этой опции должно быть наподобие "c:\Program Files\Atmel\AVR Tools\AVR Toolchain" (должны быть кавычки, потому что в составе пути есть пробелы).

• DEFS. В этой опции указана тактовая частота системы через значение макропеременной F_CPU. Например, если указана опция:

DEFS = -DF_CPU=8000000 -DBAUD_RATE=19200

то это означает, что прошивка будет скомпилирована в расчете на тактовую частоту 8 МГц. 8 МГц обычно используется, если работает внутренний RC-генератор микроконтроллера AVR. Если у Вас используется другая тактовая частота, задаваемая внешним кварцевым резонатором, то укажите рядом с -DF_CPU= тактовую частоту в Герцах. Чаще всего используется тактовая частота 16 МГц, т. е. нужно указать -DF_CPU=16000000.

Примечание: важно указать правильную тактовую частоту потому, что к этому значению привязана настройка последовательного порта UART, через который загрузчик получает код от хоста (из системы разработки Arduino IDE с помощью вызова утилиты программирования AVRDUDE). Неправильная настройка UART приведет к тому, что загрузчик не сможет получить код программы пользователя, и микроконтроллер не будет перепрошиваться через загрузчик.

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

make clean
make hex

После компиляции получится файл ATmegaBOOT.hex, который можно с помощью программатора ISP записать в память микроконтроллера ATmega8. Не забудьте после программирования загрузчика правильно установить фьюзы микроконтроллера (см. таблицу 4).

Конфигурирование загрузчика для ATmega168 или ATmega328. Зайдите в папку atmega, и откройте текстовым редактором файл Makefile. Здесь все устроено несколько сложнее, потому что этот Makefile универсальный, он предназначен для получения прошивок для множества различных плат Arduino:

Таблица 8. Выбор цели (target) в Makefile для ATmegaXX8.

Плата Arduino Target
Arduino LilyPad lilypad
Arduino Pro или Arduino Pro Mini pro8, pro16 или pro20 в зависимости от используемой тактовой частоты
Arduino Diecimila diecimila
Arduino NG ng
Своя плата на ATmega328 atmega328
Arduino Pro на ATmega328P без кварца atmega328_pro8
Arduino Mega mega

Примечание: цель Target, указанная в таблице, подставляется как опция команды make при компиляции прошивки:

make clean
make < тут надо указать Target >

Первое, что Вам нужно сделать, это выбрать цель для компиляции (вариант из столбца Target таблицы 6) в зависимости от платы, которая у Вас используется. Предположим, что у Вас самодельная плата на микроконтроллере ATmega328, для которой Вы собираетесь сделать свой загрузчик. Тогда цель для компиляции у Вас будет atmega328, прошивка получается выполнением 2 команд:

make clean
make atmega328

Если у Вас используется другая тактовая частота, то проверьте значение макропеременной AVR_FREQ (по умолчанию для цели atmega328 задана тактовая частота 16 МГц: AVR_FREQ = 16000000L). После компиляции получите прошивку ATmegaBOOT_168_atmega328.hex, которую можно записать в память Вашего микроконтроллера с помощью программатора ISP. Внимание, не забудьте также правильно установить фьюзы микроконтроллера (см. таблицу 4).

Команда Burn Bootloader в меню Tools использует для управления программатором ISP утилиту avrdude. Процедура программирования загрузчика включает 4 шага: разблокирование секции загрузчика микроконтроллера, установка фьюзов, запись кода загрузчика в секцию загрузчика и наконец блокирование кода секции загрузки. Процесс программирования управляется несколькими настройками, которые заданы в файле preferences.txt среды разработки Arduino.

Примечание: секция загрузки - специальный блок памяти в старших адресах памяти программ FLASH, предназначенный для загрузчика. Подробнее см. вопрос "Загрузчик Arduino: что это такое, где его взять?".

Настройки preferences.txt для загрузчика ATmega8:

bootloader.atmega8.programmer (значение по умолчанию: stk500) протокол, который использует загрузчик.
bootloader.atmega8.unlock_bits (значение по умолчанию: 0xFF) значение для байта блокировки (ATmega8 lock byte), предназначенное для разблокирования секции загрузки.
bootloader.atmega8.high_fuses (значение по умолчанию: 0xca) значение для старшего байта фьюзов ATmega8.
bootloader.atmega8.low_fuses (значение по умолчанию: 0xdf) значение для младшего байта фьюзов ATmega8.
bootloader.atmega8.path (значение по умолчанию: bootloader) путь относительно каталога установки системы Arduino, где находится скомпилированная прошивка загрузчика.
bootloader.atmega8.file (значение по умолчанию: ATmegaBOOT.hex) имя файла прошивки загрузчика (путь находится в bootloader.path).
bootloader.atmega8.lock_bits (значение по умолчанию: 0x0F) значение для записи в байт блокировки (ATmega8 lock byte) с целью блокировки секции загрузчика (секция загрузчика блокируется, чтобы случайно не перезаписать загрузчик в процессе записи скетча).

Настройки preferences.txt для загрузчика ATmega168 (здесь либо "diecimila", либо "ng"):

bootloader.atmega168-< BOARD >.programmer (значение по умолчанию: avrispmkii) протокол, который использует загрузчик.
bootloader.atmega168-< BOARD >.unlock_bits (значение по умолчанию: 0x3F) значение для байта блокировки (ATmega168 lock byte), предназначенное для разблокирования секции загрузки.
bootloader.atmega168-< BOARD >.extended_fuses (значение по умолчанию: 0x00) значение для байта расширенных фьюзов ATmega168.
bootloader.atmega168-< BOARD >.high_fuses (значение по умолчанию: 0xdd) значение для младшего байта фьюзов ATmega168.
bootloader.atmega168-< BOARD >.low_fuses (значение по умолчанию: 0xff) значение для младшего байта фьюзов ATmega168.
bootloader.atmega168-< BOARD >.path (значение по умолчанию: bootloader168) путь относительно каталога установки системы Arduino, где находится скомпилированная прошивка загрузчика.
bootloader.atmega168-< BOARD >.file (значение по умолчанию: ATmegaBOOT_168_< BOARD >.hex) имя файла прошивки загрузчика (путь находится в bootloader.path).
bootloader.atmega168-< BOARD >.lock_bits (значение по умолчанию: 0x0F) значение для записи в байт блокировки (ATmega168 lock byte) с целью блокировки секции загрузчика (секция загрузчика блокируется, чтобы случайно не перезаписать загрузчик в процессе записи скетча).

Windows XP иногда опрашивает Ваш параллельный порт, что разрушает процесс загрузки бутлоадера. Может понадобиться добавить значение в реестре:

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Parport\Parameters]
"DisableWarmPoll"=dword:00000001

Подробнее про описание проблемы и решение см. ветку на форуме: ParallelProgrammer Can't program firmware site:forum.arduino.cc

Описание ParallelProgrammer: Parallel Port Programmer site:arduino.cc

Переменная на языке программирования C, который использует система Arduino (вообще-то используется язык программирования C++, но в данном контексте это неважно), имеет особое свойство, называемое областью видимости. Это важное отличие от ранних языков программирования, таких как BASIC, где все переменные были глобальными.

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

Локальная переменная. В отличие от глобальной переменной, локальная переменная видна только в той функции, в которой она была объявлена. В среде разработки Arduino любая переменная, которая определена вне функции (например, setup(), loop() или других), является глобальной.

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

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

Пример:

int myVal;  // это глобальная переменная. Её может использовать любая функция.
 
void setup()
{
  // ...
}
 
void loop()
{
  int i;    // переменная i видима только внутри функции loop.
  float f;  // переменная f видима только внутри функции loop.
  // ...
 
  for (int j = 0; j < 100; j++)
  {
    // к переменной j можно обращаться только в пределах фигурных скобок цикла.
  }
}

static. Если переменная объявлена с атрибутом static внутри функции, то она будет сохранять свое значение между вызовами функции. При этом по области видимости она ведет себя так же как и локальная - видима только в пределах функции, где определена.

Если переменная объявлена как static, но вне функций, т. е. она глобальная для модуля кода, то область её видимости ограничена только для функций этого модуля. Т. е. переменная ведет себя так же, как и глобальная, но она видима только для функций одного модуля, где эта переменная определена.

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

const. Переменная с этим атрибутом предназначена только для чтения, однако она все равно размещена в оперативной памяти (RAM). Если Вы случайно в программе попробуете присвоить значение такой переменной, то компилятор выдаст ошибку. Переменные с атрибутом const объявляются одновременно с инициализацией:

const int Val = 123;char const String [] = "Hello, World!";

PROGRAM. Назначение этого атрибута - разместить переменную как константу в памяти программ (FLASH). Это позволяет экономить оперативную память (RAM) микроконтроллера.

См. инструкции для Ubuntu Linux, Debian Linux, Gentoo Linux, Linux, или Linux PPC. В этом потоке форума можно получить дополнительную информацию. Или Вы также можете использовать Arduino из командной строки, не устанавливая Java.

Фактически для этого все уже готово; язык Arduino это просто набор функций C/C++, которые могут быть вызваны из Вашего кода. Ваш скетч претерпевает незначительные изменения (например, автоматическая генерация прототипов функции, подробнее см. [10]) и затем результирующий преобразованный код передается напрямую компилятору C/C++ (avr-g++). Все стандартные конструкции C и C++, поддерживаемые avr-g++, должны работать в Arduino.

Можно компилировать программы для Arduino с использованием других инструментов сборки (например, с прямым использованием фалов Makefile и/или AVR Studio). Вам просто нужно сконфигурировать их для того, чтобы использовались соответствующие файлы основных библиотек Arduino. См. также описание процесса сборки [10].

Да, конечно. Вы можете использовать плату Arduino как обычную плату разработчика AVR, напрямую программируя её на языке C (или C++) как обычный микроконтроллер AVR (используя avr-gcc и avrdude, или AVR Studio, или Atmel Studio).

Да, хотя могут потребоваться некоторые модификации основных библиотек Arduino.

Перевод документации к [11].

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

Чтобы избежать этой дополнительной нагрузки, Вы по-видимому можете создать свой бесконечный цикл, примерно так:

void loop()
{
    while (true)
    {
        // тут какие-то действия...
    }
}

После того, как скетч пройдет первую стадию процесса компиляции [], получится примерно такой код:

#include < Arduino.h >
 
int main(void)
{
        init();
 
#if defined(USBCON)
        USBDevice.attach();
#endif
 
        setup();
 
        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }
 
        return 0;
}

Несомненно, что дополнительные расходы на вычисления возникают, когда выполняется вызов serialEventRun(). Если сравнить 2 скетча (переменная x сделана volatile для того, чтобы оптимизация на ней была отключена):

void setup()
{
 
}
 
volatile uint8_t x;
 
void loop()
{
    x = 1;
}

и

void setup()
{
 
}
 
volatile uint8_t x;
 
void loop()
{
    while(true)
    {
        x = 1;
    }
}

То получится следующая разница в генерируемом коде ассемблера:

Arduino Loop Analysis

Как Вы можете увидеть, цикл while(true) заключается в простом безусловном переходе rjmp (переход относительно текущего адреса) назад на несколько инструкций. При этом loop() дополнительно выполняет вычитание, сравнение и вызов. Это как минимум 4 инструкции против одной.

Примечание. Чтобы получить листинг, какой Вы видите на скриншоте, понадобится утилита avr-objdump. Она поставляется вместе с тулчейном avr-gcc (WinAVR на Windows). Конкретное место расположения на диске зависит операционной системы, например на Windows это может быть каталог C:\WinAVR-20100110\bin\. Утилита avr-objdump может обработать файлы .hex, но в этих файлах отсутствует оригинальная информация исходного кода и комментариев. Если Вы хотите просто скомпилировать код, то у Вас может быть файл .elf, в котором содержится вся необходимая отладочная информация (исходный код вместе с двоичными данными). Для использования в качестве входного elf-файла выполните команду наподобие следующей:

avr-objdump -S output.elf > asm.txt

Затем Вы можете проанализировать выходной файл asm.txt обычным текстовым редактором.

Были проанализированы [см. 11] следующие варианты организации главного цикла в программе Arduino:

• loop. Обычная функция void loop() (которая при компиляции становится встроенной, inline).

• loop_noinline. Не встраиваемая функция void loop(), при использовании __attribute__ ((noinline)).

• while. Оптимизированный цикл while(1).

• while_noop. Не оптимизированный цикл while(1), путем добавления __asm__ __volatile__("");. Это инструкция nop, которая предотвращает оптимизацию цикла без дополнительных затрат на переменную volatile.

• while_noinline. Не встраиваемая функция void loop() с оптимизированным while(1).

• while_noinline_noop. Не встраиваемая функция void loop() с не оптимизированным while(1).

Каждый из этих скетчей был запущен на 30 секунд, в результате получилось по 300 выборок данных (полученных через задержку в 100 мс вызовом функции delay(100)). Получился следующий результат:

loop 92.4142394821974
loop_noinline 92.4142394821974
while 89.1132686084165
while_noinline 89.1132686084165
while_noinline_noop 89.1132686084165
while_noop 89.1132686084165

Выводы: 

• Не оптимизированный while(1), встроенный в void loop, работает быстрее, чем оптимизированный компилятором void loop.

• Реальная разница во времени выполнения между не оптимизированным кодом и оптимизированным кодом Adrduino по умолчанию не имеет практического значения.

Если же Вы ловите микросекунды процессорного времени, то лучше напрямую используйте avr-gcc и программирование на языке C, и не ставьте себя в зависимость от среды разработки Arduino IDE.

Далее приведен перевод раздела траблшутинга (troubleshooting) - решение проблем при разработке в системе Arduino с сайта arduino.cc.

[Общие вопросы]

Множество компонентов (и программных, и аппаратных) влияет на процесс записи скетча в память платы Arduino board, и если в каком-то из них есть проблема или ошибка, то процесс выгрузки (upload) работать не будет. Вот список компонентов, от которых зависит выгрузка программы (скетча) в плату Arduino: драйверы для интерфейса USB платы, выбор типа платы и выбор последовательного порта для подключения (эти опции выбираются в настройках среды разработки Arduino IDE), доступ к последовательному порту, физическое соединение с платой, firmware (прошивка) моста 8U2 (это дополнительный микроконтроллер ATmega8U2, установленный как мост USB-UART на плате Arduino Uno и Arduino Mega 2560), наличие загрузчика в памяти микроконтроллера платы Arduino (обычно это UART-загрузчик), состояние фьюзов микроконтроллера, и другие компоненты загрузки. Здесь приведены некоторые специфические советы для устранения проблем по каждому из этих компонентов, участвующих в процессе Upload.

[Arduino Software]

Убедитесь, что правильно выбран тип Вашей платы через меню Tools -> Board. Если у Вас платка Arduino Uno, то Вам нужно выбрать её. Также новые платы Arduino Duemilanove поступают вместе с ATmega328, в то время как старые были с ATmega168. Чтобы проверить, какой именно микроконтроллер установлен, прочитайте текст на верхней плоскости корпуса микроконтроллера (это самая большая микросхема), который установлен на Вашей плате Arduino.

MCU-ArduinoUno R3 MCU-arduinomega2560 r2_front

Дополнительную информацию по элементам меню Board Вы можете получить из Руководства по рабочему окружению среды разработки Arduino (guide to the Arduino environment site:arduino.cc).

Затем проверьте, что выбран нужный COM-порт в меню Tools -> Serial Port (если нужный порт не отображается, то перезапустите Arduino IDE, когда Ваша плата подключена к компьютеру через USB). На Mac последовательный порт должен называться наподобие /dev/tty.usbmodem621 (для Arduino Uno или Arduino Mega 2560) или /dev/tty.usbserial-A02f8e (для старых плат, основанных на мостах FTDI). На Linux, имя порта должно быть наподобие /dev/ttyACM0 (для Arduino Uno или Arduino Mega 2560) или /dev/ttyUSB0 (для старых плат). На Windows, порт будет как COM-порт, но номер порта нужно узнать через Менеджер Устройств в разделе Порты (Device Manager, раздел Ports). Если Вы не видите последовательный порт, который соответствует Вашей плате Arduino, то см. следующий раздел, посвященный драйверам.

[Драйверы]

Драйверы предоставляют для программного обеспечения (как например среда разработки Arduino) способ обмениваться данными с аппаратным обеспечением (hardware), подключенным к Вашему компьютеру (в нашем случае это плата Arduino). Для Arduino драйверы работают для предоставления виртуального последовательного порта (virtual serial port, или virtual COM-порт). Платы Arduino Uno и Arduino Mega 2560 используют стандартные драйверы (USB CDC), предоставленные операционной системой, для обмена с мостом ATmega8U2, установленным на плате. Другие платы Arduino используют драйверы FTDI для обмена с чипом FTDI на плате (или, если чип на плате не установлен, через отдельный преобразователь/мост USB-UART).

Самый простой способ узнать, установлены ли драйверы для Вашей платы - это зайти в меню Tools -> Serial Port в среде разработки Arduino, когда Ваша плата Arduino подключена к компьютеру через USB (сначала надо подключить плату, затем запустить среду разработки Arduino IDE, и затем зайти в меню Tools -> Serial Port). Сравните дополнительные появляющиеся пункты меню по сравнению с состоянием, когда плата Arduino не подключена к компьютеру. Имейте в виду, что не имеет значения, какое имя назначено последовательному порту платы Arduino, пока оно не было выбрано в меню.

На операционной системе Windows 7 (в частности на версии 64-bit) Вам возможно понадобится зайти в Менеджер Устройств и обновить драйверы для плат Arduino Uno или Arduino Mega 2560. Просто сделайте правый клик на устройство платы (оно появится с разделе Ports, когда плата подключена к компьютеру), и выберите в контекстном меню Обновить драйверы. Затем укажите Windows на соответствующий файл .inf. Файл .inf находится в подкаталоге drivers/, находящемся в каталоге установки программного обеспечения Arduino (не в подкаталоге FTDI USB Drivers этого подкаталога).

Примечание: путь до каталога установки Arduino IDE на Windows 7 может выглядеть наподобие c:\Program Files (x86)\Arduino, соответственно .inf-файл будет в подкаталоге c:\Program Files (x86)\Arduino\drivers.

Если Вы получаете ошибку на Windows XP, когда устанавливаете драйвера Arduino Uno или Arduino Mega 2560: "The system cannot find the file specified" (система не может найти указанный файл), то Вы можете попробовать следовать совету на форуме techguy.org (см. "cannot find the file specified" "during the installation of the device." site:forums.techguy.org). Совет основан на добавлении ключа "RunOnce" в раздел "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion".

На Linux платы Arduino Uno и Arduino Mega 2560 отображаются как устройства в виде /dev/ttyACM0. Эти устройства не поддерживаются стандартной версией библиотеки RXTX, которую система разработки Arduino использует для обмена данными. Загружаемый пакет программного обеспечения Arduino для Linux включает исправленную версию библиотеки RXTX, которая также ищет эти устройства /dev/ttyACM*. Библиотека с поддержкой этих устройств есть также в пакете Ubuntu (для версии 11.04). Однако если Вы используете пакет RXTX из Вашего дистрибутива, то Вам может понадобиться сделать символическую ссылку (symlink) с файла /dev/ttyACM0 на файл /dev/ttyUSB0 (эти имена указаны для примера), чтобы последовательный порт Вашей платы был виден средой разработки Arduino.

[Доступ к последовательному порту]

На Windows, если программное обеспечение слишком медленно запускается или не может запуститься, или если меню Tools открывается слишком медленно, то Вам может понадобиться запретить последовательные порты Bluetooth или другие сетевые COM-порты (запретить их можно в Менеджере Устройств). Медленный запуск (или доступ в меню) может происходить потому, что программное обеспечение Arduino делает сканирование всех последовательных портов (COM-порты) на Вашем компьютере - когда запускается, и когда пользователь заходит в меню Tools, и эти сетевые порты могут приводить к большим задержкам или сбоям.

Если Вы не можете получить доступ к порту платы Arduino, то проверьте, что у Вас не запущены какие-либо программы, которые сканируют все последовательные порты, наподобие USB Cellular Wifi Dongle software (например от Sprint или Verizon), приложения для синхронизации PDA, драйверы Bluetooth-USB (например BlueSoleil), virtual daemon tools, и т. д.

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

Убедитесь, что у Вас не установлена программа файервола (firewall software), которая блокирует доступ к последовательному порту (например, ZoneAlarm).

Вам может понадобиться выйти из программ Processing, PD, vvvv, и т. д., если Вы их используете для чтения данных через USB или последовательное соединение с платой Arduino.

На Linux в случае проблем с доступом к порту Вы можете попробовать запустить программное обеспечение Arduino от имени пользователя root, чтобы посмотреть, решит ли это проблему выгрузки (upload).

[Физическое соединение]

Первое, в чем нужно удостовериться - что Ваша плата получает питание (горит зеленый светодиод LED на плате), и плата подключена к компьютеру через USB.

С платами Arduino Uno и Arduino Mega 2560 могут быть проблемы при их подключении к компьютеру Mac через хаб USB. Если ничего не появляется в меню Tools -> Serial Port, попробуйте подключить плату напрямую к компьютеру (без хаба) и перезапустите среду разработки Arduino IDE.

Убедитесь, что ничего не подключено постороннее к цифровым выводам 0 и 1, когда Вы выгружаете скетч в плату, потому что цифровые выводы 0 и 1 задействованы под UART (он используется как канал связи с компьютером при загрузке кода скетча через bootloader Arduino). Попробуйте сделать upload, когда вообще ничего не подключено к плате (за исключением кабеля USB, конечно).

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

[Auto-Reset (функция автосброса при загрузке скетча)]

Если у Вас плата, которая не поддерживает автосброс, то убедитесь, что Вы перед загрузкой сбрасываете плату. Платы Arduino Diecimila, Arduino Duemilanove и Arduino Nano поддерживают auto-reset, и даже такие платы без встроенного моста USB-UART, как Arduino LilyPad, Arduino Pro и Arduino Pro Mini поддерживают автосброс, если они подключены через 6-pin программирующий переходник (внешний мост USB-UART).

Однако имейте в виду, что некоторые платы (Arduino Diecimila или другие), в которые случайно прошита неправильная версия загрузчика, могут требовать ручного нажатия на кнопку сброса перед запуском upload (см. далее соответствующий вопрос).

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

Если Вы получаете ошибку: [VP 1] Device is not responding correctly, то попробуйте запустить upload снова (например сбросьте плату и нажмите кнопку upload второй раз).

[Bootloader (загрузчик)]

Убедитесь, что bootloader действительно прошит в память микроконтроллера платы Arduino. Обычно это загрузчик UART, но могут быть и другие варианты. Чтобы проверить наличие UART-загрузчика, сбросьте плату. Установленный на плату красный светодиод LED (который подключен к цифровому выводу 13) должен мигнуть. Если это не так, то возможно загрузчик не прошит в память микроконтроллера Вашей платы.

Примечание: болезнью "не прошит загрузчик" часто страдают дешевые китайские платы Arduino, которые в изобилии есть в Интернет-магазинах ebay.com, dex.com и aliexpress.com.

Загрузчик Вы можете прошить с помощью внешнего ISP-программатора (см. соответствующий вопрос "Что такое загрузчик, где его взять"). Если выгрузка скетча в плату все еще не работает, то попробуйте найти помощь на форуме Arduino (см. Help getting the Arduino board up and running site:forum.arduino.cc). Возможно, Вы сразу сможете найти ответ, если кто-то раньше сталкивался с похожей проблемой. Если Вы решили задать вопрос на форуме, то пожалуйста укажите следующую информацию:

• Какая у Вас операционная система.
• Какая у Вас плата. Если это Arduino Mini, Arduino LilyPad или другая, требующая дополнительных внешних соединений (на которой нет аппаратного моста USB-UART), то пожалуйста, если это возможно, добавьте к вопросу фотографию Вашей схемы подключения.
• Могли ли Вы раньше загрузить когда-либо код скетча в плату? Если это так, то что Вы делали с платой, прежде чем она перестала работать, и не добавили ли Вы какое-либо программное обеспечение на компьютере (или может быть, Вы какое-то программное обеспечение удалили)?
• Добавьте в вопрос диагностические сообщения, которые выводятся в нижнюю часть окна системы разработки Arduino, когда включен режим подробного вывода (verbose output). Чтобы сделать это, нажмите и удерживайте клавишу Shift, когда делаете клик на кнопке upload тулбара системы разработки Arduino. Также режим verbose output можно включить постоянно через правку файла preferences.txt, опция upload.verbose (подробнее см. [10]).

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

java.lang.StackOverflowError
at java.util.Vector.addElement(Unknown Source)
at java.util.Stack.push(Unknown Source)
at com.oroinc.text.regex.Perl5Matcher._pushState(Perl5Matcher.java)

или:

at com.oroinc.text.regex.Perl5Matcher._match(Perl5Matcher.java)
at com.oroinc.text.regex.Perl5Matcher._match(Perl5Matcher.java)
at com.oroinc.text.regex.Perl5Matcher._match(Perl5Matcher.java)
at com.oroinc.text.regex.Perl5Matcher._match(Perl5Matcher.java)
at com.oroinc.text.regex.Perl5Matcher._match(Perl5Matcher.java)
at com.oroinc.text.regex.Perl5Matcher._match(Perl5Matcher.java)
at com.oroinc.text.regex.Perl5Matcher._match(Perl5Matcher.java)

то как раз это и произошло. Ищите в коде необычные последовательности символов, включающие двойные кавычки, одиночные кавычки, обратные слеши \, комментарии и т. д. Например, пропущенные кавычки могут вызвать проблемы, и это может произойти с последовательностью '\"' (попробуйте вместо этого использовать '"').

Потому что вывод RX остался неподключенным, и bootloader платы мог увидеть мусорный сигнал на входе, что не дает истечь таймауту и запустить Ваш скетч. Попробуйте притянуть вывод RX к земле через резистор 10K (или замкнуть друг на друга выводы RX и TX).

Если Вы используете Arduino Diecimila или более старую плату USB (например Arduino NG), то убедитесь, что перемычка PWR-SEL (кусочек пластика на контактах возле коннектора USB) установлена правильно. Если Вы подаете питание на плату от внешнего блока питания (подключенного через специальный коннектор питания), то перемычка должна быть установлена на 2 штырька, ближайшие к коннектору питания. Если Вы питаете плату через USB, то перемычка должна стоять на 2 штырьках, которые находятся ближе к коннектору USB.

PWR-SEL-jumper-Arduino-NG

Некоторые платы Arduino Diecimila случайно оказываются записаны загрузчиком, предназначенным для Arduino NG. Он также должен работать, но имеет больше время задержки, когда плата получает сброс (потому что у платы Arduino NG нет автоматического сброса, и должно быть предоставлено больше времени для того, чтобы при загрузке скетча успеть нажать на кнопку сброса). Вы можете распознать загрузчик NG, потому что светодиод LED на выводе 13 три раза мигнет после сброса платы (если сравнить с загрузчиком Diecimila). Если в Вашей плате Diecimila записан загрузчик NG, то Вы можете физически нажать на кнопку сброса платы перед загрузкой Вашего скетча. Вы также можете загрузить подходящий загрузчик для Вашей Diecimila (подробнее см. вопрос "Что такое загрузчик, где его взять").

Если при запуске Arduino вы получаете ошибку наподобие:

Uncaught exception in main method: java.lang.UnsatisfiedLinkError: Native Library 
/Users/anu/Desktop/arduino-0002/librxtxSerial.jnilib already loaded in another classloader

то возможно у Вас старая версия библиотеки обмена данными (communications library), находящейся поблизости. Ищите comm.jar или jcl.jar в /System/Library/Frameworks/JavaVM.framework/ или в каталогах системных переменных окружения (environment variables) CLASSPATH или PATH.

Если при запуске Arduino вы получаете ошибку наподобие:

Java Virtual Machine Launcher: Could not find the main class. Program will exit.

то убедитесь, что Вы корректно распаковали .zip-файл Arduino - в частности, что каталог lib находится внутри каталога Arduino, и там содержится файл pde.jar.

Если среда Arduino запускается слишком долго, и зависает надолго, когда Вы пытаетесь зайти в меню Tools, то это может быть из-за конфликта с другим устройством в системе. Программное обеспечение Arduino при запуске и входе в меню Tools пытается получить список всех COM-портов на Вашем компьютере. Может получиться так, что один из COM-портов, созданный каким-то из устройств на Вашем компьютере, слишком замедляет процесс составления списка. Просмотрите список COM-портов в Device Manager. Попробуйте по одному запретить устройства, предоставляющие разные COM-порты (например, устройства Bluetooth).

Прим. переводчика: у меня была именно такая проблема. Пока я не запретил устройство "Bluetooth Serial Port", система разработки Arduino запускалась очень долго, и тормозила при попытке зайти в меню Сервис.

Bluetooth-COM-Port-disable

Если вы используете плату Arduino, подключив её через USB, то убедитесь, что у Вас установлены драйверы FTDI (как это делается, см. указания Howto site:arduino.cc). Если вы используете для подключения адаптер USB-to-Serial (внешний мост USB-UART), то убедитесь, что у Вас для него установлены драйвера.

Удостоверьтесь, что плата подключена: меню портов обновляется, когда Вы открываете меню Tools. Поэтому если Вы просто отключили плату, то она не будет в списке меню.

Проверьте, что у Вас не запущены любые программы, которые сканируют все последовательные порты, наподобие приложений для синхронизации PDA, драйверов Bluetooth-USB (например BlueSoleil), virtual daemon tools, и т. д.

На Windows назначенный номер COM-порта может оказаться слишком большим. Попробуйте переназначить номер COM-порта чипа FTDI на более низкий. Вот замечание одного из пользователей:

"У меня был набор виртуальных COM-портов для Bluetooth, так что плата Arduino оказалась с назначенным портом COM17. Arduino IDE не могла найти плату, пока я не удалил другие виртуальные порты в Панели Управления (на Windows XP) и перенес COM-порт FTDI платы на COM2. После этого я убедился, что среда Arduino использует новый порт, и все заработало."

На Mac если у Вас старые версии драйверов FTDI, то Вам может потребоваться удалить их и переустановить на последнюю версию. См. тему на форуме Can't install driver on Mac OS 10.4.5 site:forum.arduino.cc.

Попробуйте установить последнюю версию драйверов с сайта FTDI, или обратиться в их службу техподдержки support1@ftdichip.com.

Прим. переводчика: иногда лучше этого не делать, см. FTDI наносит ответный удар site:habrahabr.ru.

Скорее всего причина в том, что Вы посылаете какие-то последовательные данные в плату, когда она только что включена. Во время нескольких первых секунд после включения загрузчик Arduino (что это такое, см. вопрос "Загрузчик Arduino: что это такое") ждет поступления данных от компьютера для загрузки скетча. После нескольких секунд, если данные не поступили, загрузчик завершит таймаут и запустит скетч, уже записанный ранее в память платы. Если же после включения Вы продолжаете посылать данные загрузчику, то у него не закончится таймаут, так что Ваш скетч никогда не запустится. Вам нужно либо найти способ остановить поступление данных на первые несколько секунд после включения питания платы (например, с помощью отдельного разрешаемого чипа, который пропускает последовательные данные только после выполнения процедуры настройки в функции setup() скетча), либо путем прошивки скетча в память микроконтроллера платы внешним программатором, запретив при этом фьюзами запуск загрузчика. Либо, как вариант, Вы можете записать свою версию загрузчика, у которого будет применено особое условие для запуска загрузки.

Вы сделали неправильный выбор в меню Tools -> Microcontroller. Убедитесь, что выбор микроконтроллера соответствует тому, что установлен на Вашей плате (ATmega8, ATmega168 или ATmega328). Название типа микроконтроллера написано на самой большой микросхеме платы.

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

Другая причина может быть в том, что скетч слишком велик для платы. Когда загружается скетч, Arduino 0004 проверяет поместится ли он в памяти ATmega8, базируясь в своих вычислениях на размере загрузчика в 1 килобайт. Возможно, что у Вас старый загрузчик, который занимает 2 килобайта из 8 килобайт памяти программ (FLASH) ATmega8 вместо 1 килобайта текущей версии загрузчика. Если это так, и у Вас скетч слишком велик (больше 8 - 2 = 6 килобайт), то в действительности будет загружена только часть скетча, но программа об этом никак не узнает, и Ваша плата будет постоянно перезагружаться (reset, pause, reset...).

Если у Вас есть доступ к программатору наподобие AVR-ISP или наподобие программатора на основе параллельного порта (см. также [9]), то Вы можете загрузить последнюю версию загрузчика для Вашей платы через пункт меню Tools | Burn Bootloader. Иначе Вы можете сообщить системе Arduino количество свободного пространства, доступного для скетчей, путем редактирования переменной upload.maximum_size variable в файле preferences.txt (подробнее, где найти этот файл, см. [10]). Поменяйте 7168 на 6144, и рабочее окружение Arduino после этого будет корректно предупреждать о ситуации, когда скетч слишком велик.

Микроконтроллер ATmega168, установленный на плату Arduino, дешевле, но у него всего только 16 килобайт памяти программ (и 2 килобайта из них ушло на загрузчик), что весьма немного.

Если Вы используете вычисления с плавающей точкой (float, double), то попытайтесь переписать этот код на целочисленную арифметику, что даст экономию примерно 2 килобайта. Удалите все операторы #include в начале скетча для тех библиотек, которые не используете.

Иначе оптимизируйте алгоритм - чаще всего именно оптимизация алгоритма позволяет сделать программу короче.

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

Микроконтроллер на плате Arduino (ATmega168 или ATmega328) может поддерживать формирование PWM (ШИМ) только на определенных выводах (только на 3, 5, 6, 9, 10 или 11). Вызов analogWrite() на любых других выводах приведут к выдаче лог. 1 (5V) для значений, больших 128, и лог. 0 (0V) для значений, меньших 128. Старые версии плат Arduino с микроконтроллерами ATmega8 могут поддерживать вывод PWM только на выводах 9, 10 и 11.

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

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

Если Вы декларируете функцию, у которой возвращаемый тип из 2 слов (например "unsigned int"), то рабочее окружение не реализует эту функцию и не создаст прототип для неё. Это означает, что Вам нужно предоставить свое собственное определение, или поместить определение функции до того, как она будет вызвана.

Если Вы получаете ошибку наподобие:

avrdude: Yikes!  Invalid device signature.
       Double check connections and try again, or use -F to override
       this check.

то могут быть 2 разных случая. Либо Вы неправильно выбрали плату в меню Tools -> Board, либо Вы используете неправильную версию avrdude. Arduino использует незначительно модифицированную версию avrdude для выгрузки скетчей в плату Arduino. Стандартная версия опрашивает сигнатуру микроконтроллера платы (board device signature), и это может не понять загрузчик платы, в результате чего произойдет ошибка. Убедитесь, что используете именно ту версию avrdude, которая поставляется вместе с системой Arduino.

Что делать, если нужно выводить в порт Serial сообщения на русском языке, но программа Serial Monitor системы программирования Arduino IDE выдает вместо русских букв нечитаемые символы?

russian-output-Serial-Monitor

Самый простой способ - использовать вместо Serial Monitor терминальный клиент putty. У него есть очень гибкие настройки для сессии подключения, и можно без проблем отображать русские буквы в нужной кодировке.

russian-output-putty

Проблема в недоработке среды Arduino IDE - программа Serial Monitor не умеет отображать текст в кодировке UTF-8. К сожалению, пока разработчики этот баг не исправят, пользоваться Serial Monitor для отображения русскоязычных сообщений нельзя, придется довольствоваться только английским шрифтом. Или используйте putty! При настройке сессии putty не забудьте правильно выставить настройки последовательного порта (9600, 8 бит данных, 1 стоп-бит, без бита четности, т. е. те же паратетры, что используются в скетче), и не забудьте выставить кодировку окна UTF-8.

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

Для этого существует несколько способов:

1. Можно создать несколько отдельных файлов, и подключать их в проекте директивой #include.

2. Если часть кода уже хорошо отлажена, то можно организовать для этого отдельную библиотеку.

3. Создать в папке проекта отдельные файлы с расширением *.cpp и заголовочные файлы *.h. Подробное описание этого способа см. в статье [14].

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

Multiple libraries were found for "Wire.h"
Multiple libraries were found for "Adafruit_ILI9341.h"

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

Например, в моем случае не хватало памяти программ:

C:\Users\mylogin\AppData\Local\Temp\arduino_build_415117/
  controller.ino.elf section `.rodata' will not fit in region `rom'

c:/users/mylogin/appdata/local/arduino15/packages/arduino/tools/
  arm-none-eabi-gcc/4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/
  ../../../../arm-none-eabi/bin/ld.exe: region `rom' overflowed by 2160 bytes

После того, как я оптимизировал код и уменьшил его размер, ошибки "Multiple libraries were found" исчезли автоматически.

Более подробную информацию по ошибкам компиляции можно получить, если разрешить опцию "Show verbose output during compilation" (File -> Preferences).

[Mac OS]

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

Последнее обновление Java от Apple пытается использовать 64-битную версию стандартных библиотек (native librarу), однако приложение Arduino поставляется с 32-битной версией библиотеки RXTX. Если Вы запустите Arduino, то получите ошибку примерно такого вида:

Uncaught exception in main method: java.lang.UnsatisfiedLinkError: /Applications/arduino-0016/Arduino
16.app/Contents/Resources/Java/librxtxSerial.jnilib: no suitable image found. Did find:
/Applications/arduino-0016/Arduino 16.app/Contents/Resources/Java/librxtxSerial.jnilib:
no matching architecture in universal wrapper

Чтобы это исправить, кликните на приложение Arduino (например Arduino 16.app) в Finder, и выберите Get Info из меню File. В панели info поставьте галочку Open in 32 Bit Mode. После этого система Arduino должна нормально запуститься.

Если Вы получаете ошибку наподобие:

Link (dyld) error:
dyld: /Applications/arduino-0004/Arduino 04.app/Contents/MacOS/Arduino Undefined symbols: /Applications/arduino-0004/librxtxSerial.jnilib undefined reference to _printf$LDBL128 expected to be defined in /usr/lib/libSystem.B.dylib

то возможно Вам нужно обновить систему до версии Max OS X 10.3.9 или более свежей. Старые версии несовместимы имеют некоторые несовместимые системные библиотеки.

Error inside Serial.< init >() 
gnu.io.PortInUseException: Unknown Application 
     at gnu.io.CommPortIdentifier.open(CommPortIdentifier.java:354) 
     at processing.app.Serial.(Serial.java:127) at processing.app.Serial.(Serial.java:72) 

Такая ошибка означает, что порт в действительности используется каким-то другим приложением . Пожалуйста, удостоверьтесь, что не запустили никакие другие программы, которые обращаются к последовательным портам или портам USB, наподобие программы синхронизации PDA, менеджеры устройств bluetooth, определенные файерволы и т. д. Также имейте в виду, что некоторые программы (например Max/MSP) сохраняют открытыми последовательный порт, даже когда они его не используют - Вам может понадобиться закрыть любые пути, которые используют последовательные порты, либо полностью закрыть приложения, которые используют нужный Вам последовательный порт платы Arduino.

Если Вы используете среду Arduino 0004 или более раннюю версию, или если используете её вместе с Processing, то Вам нужно запустить macosx_setup.command, и затем перезагрузить компьютер. Arduino 0004 включает в себя модифицированную версию этого скрипта, который должны запускать все пользователи (даже те, кто выполнял скрипт, идущий вместе с Arduino 0003). Вы также можете удалить содержимое каталога /var/spool/uucp.

[Windows]

Это может быть вызвано конфликтом с процессом Logitech 'LVPrcSrv.exe'. Откройте Task Manager (Диспетчер задач) и посмотрите, работает ли эта программа, и если да, то попробуйте прибить её процесс, и затем снова сделайте upload (подробнее см. `as.exe' hanging intermittently site:mingw-users.narkive.com).

Если в операционной системе Windows Вы получаете при двойном клике на исполняемом файле arduino.exe ошибку, например:

Arduino has encountered a problem and needs to close.

то Вам нужно запускать Arduino с помощью командного файла run.bat. Будьте терпеливы, рабочее окружение среды разработки Arduino требует некоторое время для запуска.

Если на Вашем компьютере уже установлена система cygwin, то при попытке компиляции скетча Arduino Вы можете получить примерно такую ошибку:

6 [main] ? (3512) C:\Dev\arduino-0006\tools\avr\bin\avr-gcc.exe: *** fatal 
error - C:\Dev\arduino-0006\tools\avr\bin\avr-gcc.exe: *** system shared memory
version mismatch detected - 0x75BE0084/0x75BE009C.

Эта проблема может быть из-за несовместимых версий cygwin DLL.

Найдите файлы cygwin1.dll, используя стандартный инструментарий поиска Windows Start->Find/Search, и удалите все эти файлы, кроме самых свежих по версии. Самая свежая версия должна находиться в каталоге x:\cygwin\bin, где 'x' обозначает диск, на который у Вас установлен дистрибутив cygwin. Рекомендуется перед поиском сделать перезагрузку, если Вы не можете найти другие cygwin DLL.

Если Вы не нашли старых версий DLL, но ошибка не исчезает, то убедитесь, что у Вас не запущен cygwin, когда Вы используете Arduino. Если и это не помогает, то попробуйте удалить cygwin1.dll из каталога Arduino, и заменить его файлом cygwin1.dll из Вашей существующей установки cygwin (скорее всего она находится в каталоге c:\cygwin\bin).

[Ссылки]

1. Макетная плата AVR-USB32U4.
2. AVR: отладочный вывод через UART (RS232 debug).
3. Макетная плата metaboard (AVR микроконтроллер ATmega168PA или ATmega328P).
4. AVR-USB-MEGA16, V-USB, FAQ: переписка по вопросам программирования.
5. veroduino: самодельный дешевый Arduino.
6. Загрузчики (bootloader) для микроконтроллеров AVR.
7. Engbedded Atmel AVR® Fuse Calculator site:engbedded.com.
8. 150117arduino-bootloaders.zip - исходный код и готовые прошивки загрузчиков Arduino.
9. Программаторы для AVR.
10. Arduino: описание процесса сборки скетча.
11. Arduino-Loop-Analysis site:github.com.
12. ArduinoDroid - Arduino IDE site:play.google.com - среда разработки Arduino, работающая на Android.
13. Arduino Uno Port Control site:play.google.com - управление ножками платы Arduino из операционной системы Android.
14Arduino: как поделить скетч на модули.

 

Комментарии  

 
-1 #1 Александр 31.01.2017 21:42
:sigh:
Почему у вас нет описания проблемы кракозябр при смене английского на русский язык в шапке IDE??? Я УСТАЛ ИСКАТЬ РЕШЕНИЕ. ГОДА ДВА ИЩУ! А как-то один раз решил. Просто нашел и все! А теперь один МУСОР в интернете. И не найти ничего! А решение простое, Настройки -> Язык редактора -> Русский.
Цитировать
 

Добавить комментарий


Защитный код
Обновить

Top of Page