Как изменить скетч для ардуино

Это второй урок из цикла «Знакомство с Arduino». В этом уроке Вы научитесь работать со средой Arduino IDE. Для урока Вам понадобится компьютер с доступом в Интернет и любой модуль Arduino. Многие слышали о таких модулях как Arduino. Появляется вопрос: с чего же начать его изучение? Театр начинается с вешалки, а знакомство с Arduino начинается …

Это второй урок из цикла «Знакомство с Arduino». В этом уроке Вы научитесь работать со средой Arduino IDE.

Для урока Вам понадобится компьютер с доступом в Интернет и любой модуль Arduino.

Многие слышали о таких модулях как Arduino. Появляется вопрос: с чего же начать его изучение? Театр начинается с вешалки, а знакомство с Arduino начинается со среды разработки Arduino IDE.

Давайте найдём ответ на вопрос: зачем нам всё таки нужна эта IDE? Ответ достаточно прост. Среда Arduino IDE необходима для разработки программ и их записи в модули Arduino (и не только).

С предназначением IDE разобрались, теперь давайте изучим, что же она из себя представляет.

Чтобы подробнее разобраться со средой Arduino IDE, дорогой читатель, её нужно скачать и установить (если её нет на компьютере).

Среда разработки Arduino IDE состоит из следующих компонентов:

  • Текстовый редактор кода программы (1);
  • Область сообщений (2);
  • Консоль (3);
  • Панель инструментов (4);
  • Панель с часто используемыми командами (5).

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

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

Язык программирования Arduino:

Фактически нет особого языка программирования Arduino. Модули Arduino программируются на C/C++. Особенности программирования сводятся к тому, что существует набор библиотек, включающий некоторые функции (pinMode, digitalWrite и т.д.) и объекты (Serial), которые значительно облегчают процесс написания программы.

Настройка среды Arduino IDE:

Открыть настройки среды можно из пункта меню Файл -> Настройки или с помощью комбинации клавиш Ctrl + ,

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

Различные примеры:

Одной из особенностей Arduino IDE является довольно обширная база различных примеров, что очень удобно для начинающих. Открыть пример можно из пункта меню Файл -> Примеры.

Создание новой программы:

Итак, с настройками среды мы разобрались. Что теперь? А сейчас нужно создать новую программу. Это можно сделать несколькими способами:

  • из пункта меню Файл -> Новый;

  • при помощи комбинации клавиш Ctrl + N;
  • из панели с часто используемыми командами 

Сохранение программы:

Допустим мы написали программу. Далее нужно сохранить. Сделать это можно несколькими способами:

  • из пункта меню Файл -> Сохранить;

  • при помощи комбинации клавиш Ctrl + S;
  • из панели с часто используемыми командами 

Теперь нужно только ввести имя вашей программы (оно не должно содержать русских символов!) и выбрать место, куда её сохранить. Сохранённая программа автоматически помещается в одноимённую папку, которая создаёт сама Arduino IDE.

Открытие программы:

Теперь мы научились создавать и сохранять программу. Но как теперь открыть сохранённую программу? Для этого в Arduino IDE предусмотрено несколько способов:

  • из пункта меню Файл -> Открыть;

  • при помощи комбинации клавиш Ctrl + O;
  • из панели с часто используемыми командами 

В открывшимся окошке нужно выбрать папку, в которой находится нужная программа.

Редактирование текста программы:

Удобный редактор текста программы очень важен при разработке какой-либо программы. В Arduino IDE он довольно неплох, однако уступает конкурентам, таким как Eclipse, Visual Studio и т.д. Однако, его вполне достаточно. В редакторе присутствуют все основные команды, необходимые при редактировании кода. Они находятся в меню Правка. Для самых часто используемых команд (копировать, ставить и т.д.) существуют комбинации, способствующие быстрому доступу к нужной команде правки, что очень удобно. Другими отличительными особенностями встроенного редактора кода являются возможность копирования кода для форумов и в html формате, что позволяет делится Вашими программами, сохраняя наглядность разметки в виде BB кодов или html разметки соответственно.

Давайте остановимся на основных командах, необходимых для редактирования программы:

  • Копировать. Пункт меню Правка -> Копировать или комбинация клавиш Ctrl + C;
  • Вставить. Пункт меню Правка -> Вставить или комбинация клавиш Ctrl + V;
  • Вырезать. Пункт меню Правка -> Вырезать или комбинация клавиш Ctrl + X;
  • Выделить всё. Пункт меню Правка -> Выделить всё или комбинация клавиш Ctrl + A;
  • Найти. Пункт меню Правка -> Найти или комбинация клавиш Ctrl + F;
  • Отменить. Пункт меню Правка -> Отменить или комбинация клавиш Ctrl + Z;
  • Вернуть. Пункт меню Правка -> Вернуть или комбинация клавиш Ctrl + Y;
  • Форматировать текст программы. Пункт меню Инструменты -> АвтоФорматирование или комбинация клавиш Ctrl + T. Эта команда позволяет исправить неточности в разметке программы и привести её в более читабельный вид.

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

Подключение библиотеки:

Давайте разберёмся, что же такое библиотека. Библиотека — это набор функций, предназначенных для того, чтобы максимально упростить работу с различными модулями, датчиками и т.д. Например, библиотека LowPower позволяет легко управлять режимами энергосбережения модулей Arduino. Существует огромное количество различных модулей и датчиков. Но как ими управлять? Для этого разработаны специальные библиотеки, которые значительно облегчают работу. Но перед тем, как использовать дополнительные библиотеки, необходимо установить и подключить их. А как подключить библиотеку, спросите Вы? Есть несколько способов:

  • Предварительно скачав нужную библиотеку её также можно подключить к своей программе. Если она находится в zip архиве, то её можно подключить следующим способом. Для этого нужно перейти в меню Скетч -> Подключить библиотеку -> Подключить .ZIP библиотеку и в открывшемся окошке выбрать zip архив с библиотекой. Теперь эта библиотека появится в списке установленных и её можно подключить через меню Скетч -> Подключить библиотеку. Если у Вас открыта Arduino IDE, то её нужно перезапустить, чтобы изменения были применены.
  • Подключить библиотеку можно и без использования Arduino IDE. Для этого необходимо её скачать и скопировать папку с библиотекой по следующему пути: X:Пользователи<Имя пользователя>ДокументыArduinolibraries. Если у Вас открыта Arduino IDE, то её нужно перезапустить, чтобы изменения были применены. Теперь эта библиотека появится в списке установленных и её можно подключить через меню
    Скетч -> Подключить библиотеку. Однако можно и вручную в программе подключить библиотеку. Для этого перед функцией setup() нужно прописать следующую конструкцию #include <имя заголовочного файла.h> или #include «имя заголовочного файла.h».

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

Выбор платы:

Существует довольно большое количество модулей Arduino. Загружать написанную программу нужно именно в тот тип модуля, который подключён к компьютеру. Выбрать модуль можно в меню Инструменты -> Плата.

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

Далее необходимо выбрать тип контроллера, который установлен на модуле Arduino (на каждом контроллере есть маркировка). Это можно сделать в меню Инструменты -> Процессор.

Компиляция программы:

Теперь, когда выбран конкретный модуль Arduino, можно переходить к компиляции написанной программы. Давайте разберёмся, что же такое компиляция. Если говорить простым языком и касательно среды Arduino IDE, то компиляция — это перевод написанной в IDE программы в эквивалентную, но в машинных кодах. Программа записывается в микроконтроллер именно в машинных кодах, а не в том виде, в котором она написана в IDE. Компиляция также помогает найти ошибки в программе, т.к. компиляция не будет выполнена, если в программе есть ошибки.

С понятием компиляции мы разобрались. А как теперь открыть скомпилировать написанную программу? Для этого в Arduino IDE предусмотрено несколько способов:

  • из пункта меню Скетч -> Проверить/Компилировать;

  • при помощи комбинации клавиш Ctrl + R;
  • из панели с часто используемыми командами 

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

Выбор программатора:

Пункт меню Инструменты -> Программатор используется для выбора аппаратного программатора, если программирование модуля или микроконтроллера осуществляется не при помощи встроенного USB-последовательного соединения. Как правило, эта команда используется довольно редко, однако может пригодиться, например, при записи загрузчика в новый микроконтроллер.

Т.к. в модулях Arduino уже есть свой встроенный программатор, то в качестве программатора в меню Инструменты -> Программатор нужно оставить стандартный AVRISP mkII.

Запись загрузчика:

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

Загрузка программы:

Теперь, когда почти со всеми элементами среды Arduino IDE мы разобрались, можно приступать к финальному этапу — загрузке программы в модуль Arduino.

Прежде чем загружать программу, нужно выбрать порт, к которому подключён Ваш модуль Arduino. Выбрать его можно в меню Инструменты -> Порт.

Это не обязательно должен быть COM5, как на рисунке. Имя порта у Вас, скорее всего, будет другим (COM3, COM 10 и т.д.).

Когда выбран соответствующий модуль Arduino, нужный порт, процессор и программатор, можно приступать к загрузке программы.

Для этого в Arduino IDE предусмотрено несколько способов:

  • из пункта меню Скетч -> Загрузка;

  • при помощи комбинации клавиш Ctrl + U;
  • из панели с часто используемыми командами 

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

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

Монитор последовательного порта:

Между Arduino и компьютером можно обмениваться данными через последовательный порт (он же интерфейс UART). Монитор последовательного порта может использоваться как для вывода отладочной информации от модуля Arduino, так и для других целей. Через него можно как отправлять данные в модуль Arduino, так и получать данные от него. Не забудьте выбрать порт, к которому подключён модуль Arduino, иначе монитор последовательного порта не откроется! При его открытии модуль Arduino перезагрузится!

Открыть окно монитора последовательного порта можно несколькими способами:

  • из пункта меню Инструменты -> Монитор порта;

  • при помощи комбинации клавиш Ctrl + Shift + M;
  • из панели с часто используемыми командами (в правом верхнем углу) 

После открытия монитора последовательного порта появится следующее окошко:

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

Пример полного цикла разработки программы в Arduino IDE:

А теперь, дорогой читатель, давайте полностью пройдём все этапы разработки программы в Arduino IDE.

Начнём мы не со стандартного мигания светодиодом, а с классического примера из программирования — вывода на экран «Hello World!».

Запускаем Arduino IDE 

Откроется следующее окошко:

Ждём открытия среды. Когда она открылась, создаём новую программу путём нажатия на комбинацию клавиш Ctrl + N.

Теперь давайте сохраним эту программу под именем Hello_World, для этого нажимаем на комбинацию клавиш Ctrl + S, вводим путь, куда сохраним программу и её имя.

В указанной директории появится папка с программой Hello_World.

Теперь давайте напишем сам код. Мы хотим с периодичностью в 5 секунд выводить сообщение Hello World! на экран, т.е. в монитор последовательного порта. Никаких сторонних библиотек для этого нам не понадобится. Скопируйте следующий код в IDE.

Текст программы:

/*————————————————*/

void setup() {

  Serial.begin(9600); // конфигурируем последовательный порт на скорость 9600 бод

}

/*————————————————*/

void loop() {

  Serial.println(«Hello World!»); // выводим в каждый раз в новую строку Hello World!

  delay(5000); // ждём 5 секунд (1 с = 1000 мс)

}

/*————————————————*/

Пояснение программы »

Функция setup() запускается однократно при запуске программы. В ней инициализируется последовательный порт и его скорость (9600 бод).  Функция loop() вызывается после функции setup(). Функция представляет собой бесконечный цикл, в котором выполняется пользовательская программа. В ней при помощи функции  Serial.println(«Hello World!») мы каждый раз в новую строку выводим сообщение Hello World! она порт. Функция delay (5000) устанавливает задержку при выполнении программы на 5000 мс, т.е. сообщение выводится раз в 5 секунд. Таким образом, мы выводим наше сообщение с периодичностью 5 секунд.

Теперь сохраните его при помощи комбинации клавиш Ctrl + S.

Когда программа написана, подключите модуль Arduino к компьютеру (в данном примере используется Arduino Nano).

В меню  Инструменты -> Плата выберите ваш модуль Arduino (у нас — Arduino Nano).

Далее в меню Инструменты -> Процессор выберите процессор (микроконтроллер), который установлен на модуле Arduino. В нашем примере в модуле Nano стоит микроконтроллер Atmega328.

Теперь, проверьте, какой программатор установлен в меню Инструменты -> Программатор, он должен быть AVRISP mkII.

Давайте скомпилируем нашу программу и узнаем, сколько же она занимает места в памяти микроконтроллера. Для этого нажмём комбинацию клавиш  Ctrl + R.

Наша программа занимает 5% памяти программ (флеш памяти) и 9% оперативной памяти.

Всё готово к загрузке программы. Для этого нажмите комбинацию клавиш Ctrl + U и наша программа загрузится в модуль. После успешной загрузки появится сообщение об этом.

Теперь давайте откроем монитор последовательного порта (в правом верхнем углу IDE) 

После загрузки программы в модуль Arduino, в монитор последовательного порта с периодом в 5 секунд будет выводиться сообщение Hello World!.

Уважаемый читатель, мы предлагаем Вам обратиться к разделу «Программирование» на нашем сайте. Там Вы найдёте описание и примеры работы с различными функциями программирования модулей Arduino.

Спасибо за то, что учитесь познавать удивительный мир радиоэлектроники вместе с нами.

Верьте в себя, учитесь и у Вас всё обязательно получится!

Удачи в дальнейших проектах!

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

  • Начало работы
  • Работа с Arduino IDE
  • Первая прошивка, ошибки, FAQ
  • Питание платы

Arduino  IDE


Arduino IDE – программа для написания и загрузки прошивки в плату, скачать можно с официального сайта вот здесь. Внимание! Перевод языка страницы в браузере ломает кнопки! На данный момент называется Legacy IDE (1.8.X), так как вышла новая IDE v2. Новичкам рекомендуется начать с версии 1.8.X.

Перед загрузкой вам предложат пожертвовать на развитие проекта, можно отказаться и нажать JUST DOWNLOAD (только скачать). Либо открываем прямую ссылку на загрузку версии 1.8.19 и сразу качаем файл.

Для работы рекомендуется компьютер с Winodws 7 или выше, либо Linux/MacOS

  • Если у вас Windows XP, придётся установить версию 1.6.13, более свежие версии будут очень сильно тормозить или не будут работать вообще. Есть ещё одна проблема: некоторые библиотеки не будут работать на старых версиях Arduino IDE, также не будет работать поддержка плат семейства esp8266, поэтому крайне рекомендуется обновить свой компьютер до Windows 7 или выше
  • Установка на Linux из системного репозитория – читать тут
  • Установка на MacOS – читать тут

Arduino Windows app
Не рекомендуется устанавливать Arduino Windows app из магазина приложений Windows, так как с ней бывают проблемы

Другие версии
Не устанавливайте старые версии IDE, если нет на то весомых причин, а также beta и hourly-билды

Java


Для старых версий Arduino IDE, а также для некоторых других программ, понадобится пакет Java JRE. Скачать можно с официального сайта для своей операционной системы.

Установка


Arduino IDE устанавливается как обычная программа, запускам и жмём далее далее далее…

Драйвер


Во время установки Arduino IDE программа попросит разрешения установить драйвера от неизвестного производителя, нужно согласиться на установку всего предложенного.

Обновление


Перед установкой новой версии нужно удалить старую. Ни в коем случае не удаляйте папку установленной IDE из Program Files, удалять нужно через “Установка и удаление программ“, либо запустив файл uninstall.exe из папки с установленной программой. Иначе установщик откажется устанавливать новую программу, так как в системе остались следы от старой. Решение этой проблемы описано в видео ниже. Вкратце о том, как удалить IDE вручную:

Удаление остатков IDE

Удаляем папки:

  • Папка с программой
    • C:Program Files (x86)Arduino (64-битная версия Windows)
    • C:Program FilesArduino (32-битная версия Windows)
  • Папка со скетчами и библиотеками
    • ДокументыArduino
  • Папка с настройками и дополнительными “ядрами” плат
    • C:Пользователи (или Users)Ваш_пользовательAppDataLocalArduino15

Удаляем следы из реестра:

  • Открыть редактор системного реестра:
    • Windows 10: Пуск/regedit
    • Предыдущие: Пуск/Выполнить/regedit
    • Инструкция для всех Windows
  • В открывшемся окне: Правка/Найти…
    • В окне поиска пишем arduinouninstall
    • Поиск
  • Удаляем найденный параметр (см. скриншот ниже)
  • На всякий случай Правка/Найти далее
  • Удаляем и так далее, пока не удалим все найденные параметры с arduinouninstall
  • После этого можно запускать установщик и устанавливать новую программу

Другие проблемы


  • Если перестала запускаться Arduino IDE – удаляем файлик preferences.txt из C:Пользователи (или Users)Ваш_пользовательAppDataLocalArduino15

Портативная версия


Вместо полной установки программы можно скачать архив с уже “установленной”, на странице загрузки он называется Windows ZIP file. Вот прямая ссылка на 1.8.19. Распаковав архив, получим портативную версию Arduino IDE, которую можно скинуть на флешку и использовать на любом компьютере без установки программы. Но понадобится установить драйвер CH341 для китайских плат, а также драйверы из папки с программой Arduino IDE (подробнее в следующем уроке). Возможно понадобится установить Java.

Работа на смартфоне


Писать и загружать прошивку через смартфон тоже можно, понадобится смартфон на Android и приложение ArduinoDroid. Также для тренировки и удобного редактирования скетчей можно использовать CppDroid, но загружать в плату она не умеет.

Первое подключение

Осмотр платы


Перед подключением к компьютеру рекомендуется провести визуальный осмотр платы на предмет дефектов пайки компонентов. Что можно встретить (в порядке фотографий):

  • Замкнутые пины (вроде бы паяются китайцами вручную)
  • Неприпаянная нога компонента
  • “Торчащие” вверх или под углом компоненты типа резисторов и конденсаторов, припаянные только с одной стороны
  • Компоненты со смещением
  • “Сопля” между ногами компонента

blank

blank

Плату с обнаруженным дефектом не рекомендуется подключать к компьютеру! Всё можно исправить паяльником, если не умеете сами – попросите того, кто умеет.

Реакция на подключение питания


Как понять, что плата работает корректно? На примере Nano/Uno:

  • При подключении USB загорается и горит светодиод PWR
  • Если плата новая и на ней прошит загрузчик (он обязан быть прошит) – однократно мигает светодиод L
  • Примечание: светодиоды могут быть любого цвета
  • На новой плате прошито “мигание светодиодом”, поэтому светодиод L продолжит мигать один или два раза в секунду в зависимости от версии загрузчика
  • При нажатии на кнопку сброса (RESET, единственная кнопка на плате) должен однократно мигнуть светодиод L, сигнализируя о завершении работы загрузчика.

Если ваша плата ведёт себя иначе – скорее всего это заводской брак, если плата новая, или кривые руки – если плата уже паялась и или куда то подключалась =)

Драйвер USB контроллера

CH341


В своих проектах я использую “Ардуино-совместимые” китайские платы, у которой для подключения по USB используется контроллер CH340/CH341. Чтобы он распознавался компьютером, нужно установить драйвер.

Windows

Скачать драйвер можно по ссылке:

  • FTP сайта
  • Яндекс.Диск
  • Сайт driverslab

Запускаем и в появившемся окошке нажимаем INSTALL. Готово!

Если во время установки Arduino IDE вы по какой-то причине пропустили установку драйверов, то их можно установить вручную из папки с программой, расположенной по пути

  • C/Program Files/Arduino/drivers (для 32-х разрядной системы)
  • C/Program Files (x86)/Arduino/drivers (для 64-х разрядной системы).

Запустить файл

  • dpinst-x86.exe (для 32-х разрядной системы)
  • dpinst-amd64.exe (для 64-х разрядной системы)

blank

Linux Mint

В Linux уже встроен необходимый драйвер, но Arduino IDE может отказаться с ним работать: Linux определяет ардуинку как устройство ttyUSB*, обычно это ttyUSB0 (это можно узнать командой dmesg в терминале), то есть в системе появляется интерфейс /dev/ttyUSB0. Чтобы с ним работать, нужны права доступа. Читать и писать на устройство /dev/ttyUSB0 имеет пользователь root и пользователи группы dialout. Работы с правами суперпользователя лучше избегать, поэтому следует занести своего пользователя в группу dialout. Это можно сделать следующей командой (обратите внимание, команда whoami в обратных кавычках)

sudo usermod -a -G dialout `whoami`

После этого нужно перелогиниться. Дальше запускаем Arduino IDE и в меню «Инструменты/Порт» ставим галочку напротив /dev/ttyUSB0.

Linux Arch

Вся информация по работе с IDE на данной ОСи есть вот в этой статье

FT232


На оригинальных Arduino Nano стоит USB контроллер производства FTDI – FT232, драйвер для всех версий ОС можно скачать с официального сайта (прямая ссылка на инсталлятор для Windows). Некоторые очень редкие китайцы паяют на свои Наны поддельные FTDI контроллеры, которые буквально выходят из строя после некоторых обновлений Windows. Если вам достался такой экземпляр (я никогда не даю ссылки на такие поделки) – подробности по ситуации читайте здесь. Как восстановить контроллер и сделать рабочий драйвер – читайте здесь.

CP2102


На некоторые Arduino-совместимые платы китайцы ставят контроллер USB CP2102. Драйвер на него в большинстве случаев уже есть в системе (на Linux точно есть), если не работает – скачать можно с официального сайта.

  • Прямая ссылка на драйвер для Windows всех версий
  • Прямая ссылка на драйвер для Mac OS

На Windows установка производится следующим образом: достаём из архива и

Настройка и прошивка

Подключение платы


Плата подключается к компьютеру по USB, на ней должны замигать светодиоды. Если этого не произошло:

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

Компьютер издаст характерный сигнал подключения нового оборудования, а при первом подключении появится окошко “Установка нового оборудования”. Если этого не произошло:

  • См. предыдущий список неисправностей
  • Кабель должен быть data-кабелем, а не “зарядным”
  • Кабель желательно втыкать напрямую в компьютер, а не через USB-хаб
  • Не установлены драйверы Arduino (во время установки IDE или из папки с программой), вернитесь к установке.

В списке портов (Arduino IDE/Инструменты/Порт) появится новый порт, обычно COM3. Если этого не произошло:

  • См. предыдущий список неисправностей
  • Некорректно установлен драйвер на USB контроллер Arduino
    • Переверните плату и найдите “узкую” микросхему. Если на ней написано CH341 – ставим драйвер по инструкции выше
    • Если написано FT232R – опять же инструкция выше
    • Если ничего не написано – открываем “Диспетчер устройств”, смотрим блок “Другие устройства”. Если при подключении платы к компьютеру там появляется FT232R USB UART – смотрим инструкцию выше
  • Если список портов вообще неактивен – драйвер Arduino установлен некорректно, вернитесь к установке
  • Возникла системная ошибка, обратитесь к знакомому компьютерщику или экзорцисту

Выбор и настройка платы (Arduino NANO)


  • Выбираем соответствующую плату в ИнструментыПлата Большинство моих проектов сделаны на Arduino Nano. Если вы используете Nano:
    •  В микроконтроллер китайских плат зашит “старый” загрузчик, поэтому выбираем ИнструментыПроцессорATmega328p (Old Bootloader). Если вам по какой-то причине пришлют платы с новым загрузчиком – прошивка не загрузится (будет минутная загрузка и ошибка), можно попробовать сменить пункт Процессор на ATmega328p
  • Теперь выбираем порт, к которому подключена плата. COM1 – в большинстве случаев системный порт, у вас должен появиться ещё один (обычно COM3)

Загрузка прошивки


“Загрузка” прошивки происходит в два этапа – компиляция и непосредственно загрузка в микроконтроллер. Компиляция – проверка кода на наличие ошибок, её можно запустить, нажав кнопку с символом галочки в верхнем меню программы. Компилировать код можно даже не подключая плату к компьютеру! При нажатии на кнопку с символом стрелочки начнётся компиляция, а затем загрузка скомпилированного кода в плату.

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

Примечание: данный код является универсальным для всех Arduino-совместимых плат

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
  digitalWrite(LED_BUILTIN, 0);
  delay(300);
  digitalWrite(LED_BUILTIN, 1);
  delay(300);
}

ESP8266 (Wemos, NodeMCU)


ESP8266  – микроконтроллер с WiFi на борту, на его базе сделаны платы Wemos D1 mini, NodeMCU и другие.

  • Читайте вводный урок по esp8266.
  • На популярных платах Wemos и NodeMCU стоит бортовой USB и CH340 или CP2102 (обычно это указано на странице товара).
  • Установка драйверов описана выше на этой странице.

Для работы с esp8266 нужно добавить поддержку плат в Arduino IDE:

  • Arduino IDE/Файл/Настройки/
  • В окошко “Дополнительные ссылки…” Вставить
  • http://arduino.esp8266.com/stable/package_esp8266com_index.json
  • Нажать ОК
  • Arduino IDE/Инструменты/Плата/Менеджер плат… Начать вводить в поиске “esp”. Выбрать и установить ESP8266 boards
    • Рекомендуемая версия – 2.7.4, на более высоких пока что наблюдаются проблемы с совместимостью
  • В списке плат Инструменты/Плата/ появится семейство плат на esp8266. Выбираем плату
    • NodeMCU – NodeMCU 1.0
    • Wemos Mini – LOLIN Wemos D1 R2 & mini
    • Или другую согласно своей конфигурации
  • Выбираем порт, к которому подключена плата
  • На четвёртом скриншоте ниже показаны настройки платы по умолчанию, изменены только выделенные красным (плата и порт)

Заметка для NodeMCU. Перед началом загрузки нужно ввести плату в режим прошивки. Подключить к компьютеру, выбрать появившийся порт для загрузки. Зажать кнопку Flash. Кликнуть по кнопке Reset. Отпустить кнопку Flash. И только после этого нажать стрелочку в программе для загрузки прошивки.

ESP32


ESP32  – мощный микроконтроллер с WiFi на борту

  • На плате стоит бортовой USB и CH340 или CP2102 (обычно это указано на странице товара).
  • Установка драйверов описана выше на этой странице.

Для работы с ESP32 нужно добавить поддержку плат в Arduino IDE:

  • Arduino IDE/Файл/Настройки/
  • В окошко “Дополнительные ссылки…” Вставить
  • https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  • Нажать ОК
  • Arduino IDE/Инструменты/Плата/Менеджер плат… Начать вводить в поиске “esp”. Выбрать и установить esp32
  • В списке плат Инструменты/Плата/ появится семейство плат на esp32. Выбираем плату согласно купленной модификации
  • Выбираем порт, к которому подключена плата

У некоторых плат не работает автоматический запуск в режиме прошивки, поэтому в самом начале процесса загрузки прошивки нужно зажать кнопку Flash (BOOT) на плате

Digispark


Digispark – плата на базе ATtiny85.

  • Читайте вводный урок по Digispark.
  • Подключение к ПК по USB (реализован программно)
  • Нужно установить специальный драйвер, скачать можно на официальном GitHub проекта (в разделе Релизы, вот прямая ссылка на архив), либо с моего FTP. Драйвера есть для Win, MacOS и Linux.
  • Пользователям Linux читать здесь

Для работы с Digispark нужно добавить поддержку плат в Arduino IDE:

  • Arduino IDE/Файл/Настройки/
  • В окошко “Дополнительные ссылки…” Вставить
    • http://digistump.com/package_digistump_index.json
    • или https://raw.githubusercontent.com/digistump/arduino-boards-index/master/package_digistump_index.json
  • Нажать ОК
  • Arduino IDE/Инструменты/Плата/Менеджер плат… Начать вводить в поиске “Digispark”. Выбрать и установить Digistump AVR Boards
  • В списке плат Arduino IDE/Инструменты/Плата/ появится семейство плат Digispark. Выбираем Digispark (Default – 16.5mhz)

Прошивка загружается следующим образом: ПЛАТУ НЕ ПОДКЛЮЧАЕМ, ПОРТ НЕ ВЫБИРАЕМ, нажимаем загрузка, ждём компиляции. Появится надпись “подключите плату”. Втыкаем плату в USB и прошивка загружается.

LGT8F328


LGT8F328 – китайский клон ATmega328

  • Читайте вводный урок по lgt8f328.
  • Может понадобиться драйвер (прямая ссылка на архив)

Для работы с LGT8F328 нужно добавить поддержку плат в Arduino IDE:

  • Запустить Arduino IDE, перейти в Файл/Настройки/
  • В окошко “Дополнительные ссылки…” Вставить
  • https://raw.githubusercontent.com/dbuezas/lgt8fx/master/package_lgt8fx_index.json
  • Нажать ОК
  • Перейти в Инструменты/Плата/Менеджер плат… Начать вводить в поиске “lgt8”. Выбрать и установить LGT8fx Boards
  • Теперь в списке плат Инструменты/Плата/ появится семейство плат Logic Green… Выбираем свою плату

“Голые” МК


Для начала рекомендуется изучить вот эти два урока: первый и второй. У проектов на базе голого микроконтроллера есть два варианта:

  • Если проект основан на ATmega328 (Arduino Nano/Mini) и на плате есть источник тактирования на 16 МГц (резонатор), то микроконтроллер можно просто перепаять с Arduino и загружать прошивку через внешний USB-TTL переходник, как на Arduino Pro Mini. Либо загрузить прошивку, и потом перепаивать – всё будет работать.
    • Если источника тактирования нет – так делать нельзя! Сначала нужно настроить МК на внутреннее тактирование, подключив ISP программатор к плате Arduino и выбрав внутренний источник тактирования в настройках ядра. Подробнее читайте в уроке.
  • Если используется новый микроконтроллер (или припаянный китайцами) – он по умолчанию настроен на внутреннее тактирование и его можно паять на плату в любом случае. Загрузить прошивку можно только при помощи ISP программатора. Также можно прошить загрузчик и в дальнейшем загружать прошивку через USB-TTL преобразователь.

Установка библиотек


Библиотека – несколько файлов с кодом, облегчающим работу с датчиками и другими модулями. К моим проектам библиотеки идут в архиве (об этом ниже). Рассмотрим все способы загрузки и установки библиотек.

Менеджер библиотек


Большинство Ардуино-библиотек можно установить автоматически из встроенного в программу менеджера библиотек:

  • Скетч/Подключить библиотеку/Управлять библиотеками…
  • Комбинация клавиш Ctrl+Shift+I

Нужную библиотеку можно найти в поиске по названию и нажать Установка, библиотека будет автоматически установлена в папку с библиотеками. Arduino IDE проверяет обновления библиотек при запуске и предложит обновиться, если найдёт обновления.

Скачивание с GitHub


Не все существующие библиотеки есть в менеджере библиотек и скачать их можно только с GitHub. Есть два способа: скачать весь репозиторий и скачать релиз. Весь репозиторий со всеми “лишними” служебными файлами можно скачать одним архивом вот так, нажав Code/Download ZIP

Если у библиотеки есть релизы – справа будет отмечен последний (свежий) релиз. Нажимаем на него:

И в новом окне нажимаем Source code (zip) – начнётся загрузка архива. Скачивание релиза более предпочтительно, так как содержит только файлы библиотеки.

blank

В обоих случаях библиотека скачается как .zip архив.

Автоматическая установка


Скачанный .zip архив можно установить в автоматическом режиме через Скетч/Подключить библиотеку/Добавить .ZIP библиотеку… В открывшемся окне выбрать скачанный архив, библиотека будет установлена по указанному в настройках пути.

Ручная установка


Для начала нужно распаковать архив (стандартный архиватор Windows или WinRAR). Чтобы Arduino IDE смогла использовать библиотеку, нам нужно положить её туда, где программа будет её искать. Таких мест три (на примере Windows):

  • Документы/Arduino/libraries/
  • Папка с программой/libraries/
    • C/Program Files/Arduino/libraries/ (Windows 32)
    • C/Program Files (x86)/Arduino/libraries/ (Windows 64)
    • В портативной версии IDE желательно держать библиотеки в Папка с программой/libraries

Рекомендуется держать все библиотеки в одном месте, чтобы не было путаницы. Лично я устанавливаю все библиотеки в папку с программой (в Program Files), но для этого могут потребоваться права администратора (зависит от версии и настроек Windows). Если у вас возникли с этим проблемы – устанавливайте в Документы/Arduino/libraries/. На скриншотах показана установка скачанной с GitHub библиотеки в папку с программой и в документы. Ставить нужно в одно место, я просто показываю оба варианта.

Ошибки компиляции


Возникает на этапе сборки и компиляции прошивки. Ошибки компиляции вызваны проблемами в коде прошивки, то есть проблема сугубо программная. Слева от кнопки “загрузить” есть кнопка с галочкой – проверка. Во время проверки производится компиляция прошивки и выявляются ошибки, если таковые имеются. Ардуино в этом случае может быть вообще не подключена к компьютеру.

  • В некоторых случаях ошибка возникает при наличии кириллицы (русских букв) в пути к папке со скетчем. Решение: завести для скетчей отдельную папочку в корне диска с английским названием.
  • В чёрном окошке в самом низу Arduino IDE можно прочитать полный текст ошибки и понять, куда копать
  • В скачанных с интернета готовых скетчах часто возникает ошибка с описанием <название файла>.h no such file or directory. Это означает, что в скетче используется библиотека <название файла>, и нужно положить её в Program Files/Arduino/libraries/. Ко всем моим проектам всегда идёт папочка с использованными библиотеками, которые нужно установить. Также библиотеки всегда можно поискать в гугле по <название файла>.
  • При использовании каких-то особых библиотек, методов или функций, ошибкой может стать неправильно выбранная плата в “Инструменты/плата“. Пример: прошивки с библиотекой Mouse.h или Keyboard.h компилируются только для Leonardo и Micro.
  • Если прошивку пишете вы, то любые синтаксические ошибки в коде будут подсвечены, а снизу в чёрном окошке можно прочитать более детальное описание, в чём собственно косяк. Обычно указывается строка, в которой сделана ошибка, также эта строка подсвечивается красным.
  • Иногда причиной ошибки бывает слишком старая, или слишком новая версия Arduino IDE. Читайте комментарии разработчика скетча.
  • Ошибка недостаточно свободного места возникает по вполне понятным причинам. Оптимизация: статическая память – память, занимаемая кодом (циклы, функции). Динамическая память занята переменными.

Частые ошибки в коде, приводящие к ошибке компиляции

  • …no such file or directory – компилятор не может найти файл, который используется в коде. Чаще всего это библиотека, которую не установили или установили неправильно
  • expected ‘,’ or ‘;’ – пропущена запятая или точка запятой на предыдущей строке
  • stray ‘320’ in program – русские символы в коде
  • expected unqualified-id before numeric constant – имя переменной не может начинаться с цифры
  • … was not declared in this scope – переменная или функция используется, но не объявлена. Компилятор не может её найти
  • redefinition of … – повторное объявление функции или переменной
  • storage size of … isn’t known – массив задан без указания размера

Ошибки загрузки


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

  • Если неправильно выбран COM порт – прошивка не загрузится с ошибкой avrdude: ser_open(): can’t open device. Вернитесь к пункту “Выбор и настройка платы” этого урока и убедитесь в том, что выбор порта активен и при подключении платы появляется новый.
  • Большинство проблем при загрузке, вызванных “зависанием” ардуины или загрузчика, лечатся полным отключением Ардуины от питания. Потом вставляем USB и по новой прошиваем.
  • Причиной ошибки загрузки может быть неправильно выбранная плата в “Инструменты/Плата”, а также неправильно выбранный процессор в “Инструменты/Процессор”.
    • Если это Arduino Nano – попробуйте оба, Old и не Old.
  • Если у вас открыт монитор COM порта в другом окне Arduino IDE или плата общается через СОМ порт с другой программой (Ambibox, HWmonitor, SerialPortPlotter и т.д.), то вы получите ошибку загрузки, потому что порт занят. Отключитесь от порта или закройте другие окна и программы.
  • Если у вас задействованы пины RX или TX – отключите от них всё! По этим пинам Arduino общается с компьютером, в том числе для загрузки прошивки.
  • Если в описании ошибки встречается bootloader is not responding и not in sync, из-за ошибок записи мог “слететь” загрузчик, его можно попробовать прошить заново.
  • Если все пункты из этого списка проверены, а загрузчик прошить не удаётся – микроконтроллер скорее всего необратимо повреждён, то есть сгорел.

Предупреждения


Помимо ошибок, по причине которых проект вообще не загрузится в плату и не будет работать, есть ещё предупреждения, которые выводятся оранжевым текстом в чёрной области лога ошибок. Предупреждения могут появиться даже тогда, когда выше лога ошибок появилась надпись “Загрузка завершена“. Это означает, что в прошивке нет несовместимых с жизнью ошибок, она скомпилировалась и загрузилась в плату. Что же тогда означают предупреждения? Чаще всего можно увидеть такие:

  • # Pragma message……. – сообщения с директивой Pragma обычно выводят библиотеки, сообщая о своей версии или каких-то настройках. Это даже не предупреждение, а просто вывод текста в лог.
  • Недостаточно памяти, программа может работать нестабильно – чуть выше этого предупреждения обычно идёт информация о задействованной памяти. Память устройства можно добивать до 99%, ничего страшного не случится. Это флэш память и во время работы она не изменяется. А вот динамическую память желательно забивать не более 85-90%, иначе реально могут быть непонятные глюки в работе, так как память постоянно “бурлит” во время работы. НО. Это зависит от скетча и в первую очередь от количества локальных переменных. Можно написать такой код, который будет стабильно работать при 99% занятой SRAM памяти.
  • Предупреждения о несовместимых типах данных. Компилятор не смог привести один тип к другому и сообщает о потенциальных ошибках в ходе выполнения программы. В большинстве случаев ничего плохого не случится, но лучше найти проблемную строку и помочь компилятору преобразовать тип.

Частые вопросы


  • Ардуину можно прошить только один раз? Нет, несколько десятков тысяч раз, всё упирается в ресурс flash памяти. А он довольно большой.
  • Как стереть/нужно ли стирать старую прошивку при загрузке новой? Память автоматически очищается при прошивке, старая прошивка автоматически удаляется.
  • Можно ли записать две прошивки, чтобы они работали вместе? Нет, при прошивке удаляются абсолютно все старые данные. Из двух прошивок нужно сделать одну, причём так, чтобы не было конфликтов.
  • Можно ли “вытащить” прошивку с уже прошитой Ардуины? Теоретически можно, но только в виде нечитаемого машинного кода, в который преобразуется прошивка на С++ при компиляции, т.е. вам это НИКАК не поможет, если вы не имеете диплом по низкоуровневому программированию.
    • Зачем это нужно? Например есть у нас прошитый девайс, и мы хотим его “клонировать”. В этом случае да, есть вариант сделать дамп прошивки и загрузить его в другую плату на таком же микроконтроллере.
    • Если есть желание почитать код – увы, прошивка считывается в виде бинарного машинного кода, превратить который обратно в читаемый Си-подобный код обычному человеку не под силу
    • Вытащить прошивку, выражаясь более научно – сделать дамп прошивки, можно при помощи ISP программатора, об этом можно почитать здесь
    • Снять дамп прошивки можно только в том случае, если разработчик не ограничил такую возможность, например записав лок-биты, запрещающие считывание Flash памяти, или вообще отключив SPI шину. Если же разработчик – вы, и есть желание максимально защитить своё устройство от копирования – гуглите про лок-биты и отключение SPI

▶Проекты AlexGyver◀


ВНИМАТЕЛЬНО ЧИТАЙ ИНСТРУКЦИЮ
Если это твой первый опыт работы с Arduino — внимательно изучи каждый пункт инструкции выше, здесь всё написано!!!

Все мои проекты имеют одинаковую структуру и устанавливаются/прошиваются одинаково, поэтому вот финальная общая инструкция:

1. Установить Arduino IDE и драйверы, как написано в гайде выше. Если это ваш первый раз – желательно не подключать ничего к новой плате, а загрузить пробную прошивку из гайда и убедиться, что всё загружается и работает. Если после сборки схемы прошивка перестанет загружаться – увы, схема собрана с ошибками и плата уже могла сгореть. Но она работала, мы это проверили =)

  • Если проект основан не на стандартной Arduino плате, а например на esp8266, ESP32, Digispark, lgt8f328 – устанавливаем поддержку этих плат, как описано выше.

2. Скачать архив со страницы проекта. Ссылка всегда одна, она ведёт на прямую загрузку архива с хранилища GitHub. Когда проект обновляется (об этом может быть написано на странице проекта), ссылка на архив остаётся той же, но в нём будут уже какие-то изменённые файлы, добавлены новые версии прошивки и т.д. Все обновления указаны на странице проекта.

3. Распаковать архив. Архив имеет формат .zip, для его распаковки можно использовать встроенные инструменты операционной системы, либо популярный WinRAR. Если не распаковать архив – прошивка откроется неправильно. Я не отличаюсь буйной фантазией и всегда называю папки одинаково, вот что может быть в архиве проекта:

  • firmware – прошивки для Arduino
  • software – программы для ПК
  • libraries – библиотеки
  • schemes – схемы
  • PCB – gerber файлы печатных плат
  • docs – всякие документы
  • Android – исходники приложения
  • 3Dprint – модели для печати
  • processing – программа на Processing

Извлечение WinRAR

Извлечение Windows

Распакованная папка

4. Установить библиотеки. К прошивкам моих проектов всегда идут библиотеки, необходимые для работы кода. Библиотеки в проектах часто пересекаются, но рекомендуется ставить именно идущую в комплекте с проектом версию, так как более старые или новые могут быть несовместимы.

Содержимое папки libraries из архива помещаем в

  • С/Program Files/Arduino/libraries/ (Windows x32)
  • C/Program Files (x86)/Arduino/libraries/ (Windows x64)

Установка в libraries

Если возникнут проблемы с доступом к этой папке (на Windows 10), то библиотеки можно положить в

  • Документы/Arduino/libraries/

Установка в документы

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

5. Открыть скетч (так называется файл с программой). При запуске файла скетча автоматически откроется Arduino IDE. Важно: если в папке со скетчем есть несколько файлов – запускаем любой с логотипом Arduino. Остальные файлы должны подтянуться автоматически и образовать вкладки в окне программы. Если запускать скетч прямо из архива – вкладки не откроются и скомпилировать/загрузить программу будет невозможно.

Вкладки в Arduino IDE

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

  • Для проектов на Arduino Nano выбираем Arduino Nano, а также ИнструментыПроцессорATmega328p (Old Bootloader). Если вам по какой-то причине пришлют платы с новым загрузчиком – прошивка не загрузится (будет минутная загрузка и ошибка), можно попробовать сменить пункт Процессор на ATmega328p
  • Для проектов на Wemos выбираем (LOLIN)Wemos D1 R2 & mini
  • Для проектов на NodeMCU выбираем NodeMCU 1.0
  • В некоторых проектах, например GyverLamp2 (второй версии) для прошивки в esp8266 нужно выбрать плату Generic esp8266, читайте особенности загрузки на странице проекта!
  • Для проектов на Digispark порт выбирать не надо, читай инструкцию выше

blank

blank

7. Настроить программу. Очень часто в начале кода моих программ можно встретить блок настроек. Настройки обычно имеют вид

#define SOME_SETTING 1  // 1 включено, 0 выключено

где цифра отвечает за значение настройки, менять нужно только цифру согласно комментарию.

8. Загрузить прошивку. Нажимаем стрелочку в левом верхнем углу окна программы и прошивка загружается. Не загружается? Читаем гайд выше, там описаны все возможные причины.

Загружать прошивку желательно до подключения компонентов, чтобы убедиться в том, что плата рабочая. После сборки можно прошить ещё раз, плата должна спокойно прошиться. В проектах с мощными потребителями в цепи питания платы 5V (адресная светодиодная лента, сервоприводы, моторы и проч.) необходимо подать на схему внешнее питание 5V перед подключением Arduino к компьютеру, потому что USB не обеспечит нужный ток, если потребитель его потребует – это может привести к выгоранию защитного диода на плате Arduino.

9. Если что-то не работает – читай инструкцию, в ней описан каждый шаг и решение всех проблем. Также в самом начале есть видео, где всё показано ещё более подробно.

Заметка для тех, кто не читал инструкцию и получил какую-то ошибку. Вот список самых частых причин:

  • Не распаковал архив и запустил скетч прямо из него, получил ошибку компиляции в стиле not declared in this scope. РАСПАКУЙ АРХИВ
  • В логе ошибок встречается фраза no such file or directory – не установил библиотеки. УСТАНОВИ БИБЛИОТЕКИ
  • Происходит ошибка загрузки. ВЕРНИСЬ К ИНСТРУКЦИИ ПО НАСТРОЙКЕ IDE
  • На плате что-то греется и прошивка не грузится. ДОПУСТИЛ ОШИБКУ ПРИ СБОРКЕ, ВСЁ СГОРЕЛО
  • Установил старую или кривую версию Arduino IDE и получил непонятные ошибки – удали старую и УСТАНОВИ СВЕЖУЮ ВЕРСИЮ
  • Некоторые проекты будут работать только на тех платах, что показаны в видео и описаны на странице проекта. Под другие платы прошивка компилироваться не будет!

На этом уроке Вы научитесь программировать свою плату Arduino на примере мигания встроенным светодиодом.

Необходимые элементы

Для данного примера Вам понадобится плата Arduino (в данном случае – Arduino Uno R3, но Вы сможете проработать данный пример, имея в наличии и другую плату) и кабель USB (типа A (4х12 мм) – B (7х8 мм) – более подробно можно почитать на Вики).

Что такое ” L” светодиод

01

На Arduino Uno присутствуют ряды коннекторов типа мама по бокам платы, которые используются для подключения периферийных электронных устройств или “шилдов”.

Кроме того, на плате присутствует встроенный светодиод (англ. – LED), которым Вы можете управлять с помощью скетчей. Этот встроенный светодиод условно назовем “L” светодиод, как это принято на многих англоязычных ресурсах.

Расположение данного светодиода на плате отмечено на фото снизу.

Загрузка примера “Blink” (мигание) в Arduino IDE

При подключении новой платы к персональному компьютеру, обратите внимание, что светодиод начинает мигать, так как все платы от производителей поступают с уже “залитым” скетчем “Blink”.

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

Пришло время проверить Ваше подключение и запрограммировать плату.

В оболочке Arduino IDE существует большая коллекция скетчей, которые уже готовы к использованию. Среди них находится и пример, который заставляет мигать “L” светодиод.

Откройте пример “Blink”, который находится в пункте меню File – Examples – 01.Basics

После открытия, расширьте окно оболочки Arduino IDE, чтобы Вы могли весь скетч в одно окне.

Скетчи из примеров, включенные в Arduino IDE предусматривают режим “только чтение” (“read only”). То есть, загрузить их на плату Вы сможете, но после изменения кода, Вы не сможете их сохранить в том же файле.

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

Из меню “File” выберите опцию “Сохранить как” (“Save As..”) и сохраните скетч под подходящим Вам названием, например, “MyBlink”.

Вы сохранили копию скетча “Blink” в Вашей библиотеке. Теперь открыть этот файл Вы можете в любой момент, перейдя по вкладке File – Scetchbook.

Загрузка примера “Blink” (мигание) на плату

Подключите свою плату Arduino к компьютеру с помощью USB и проверьте тип платы (“Board type”) и серийный порт (“Serial Port”), по которому она подключена.

Текущие настройки отображаются внизу окна оболочки Arduino IDE

Кликните на кнопку “Загрузить” (“Upload”)

Во время загрузки в нижней части окна IDE появятся ползунок загрузки и сообщения. Вначале появляется фраза “Компилирование” (“Compiling scetch..”), что означает процесс конвертирования Вашего скетча в формат, подходящий для загрузки на плату Arduino.

Дальше статус сменится на “Загрузка” (“Uploading”). В этот момент светодиоды на плате начнут мигать, так как начнется перенос скетча в микропроцессор.

В конце статус сменится на ”Загрузка завершена” (“Done uploading”). В сообщении, которое появится в текстовой строке отобразится информация о том, что загруженный скетч занимает 1,084 байта из 32,256 доступных.

Иногда при компиляции у Вас может возникнуть подобная ошибка:

Причин может быть несколько: Вы не подключили плату к компьютеру; Вы не установили необходимые драйвера; Вы выбрали некорректный серийный порт.

Если же загрузка прошла корректно, плата Arduino перезагрузится и “L” светодиод начнет мигать.

Пояснения к скетчу “Blink”

Ниже представлен код скетча “Blink”.

/*

Blink

Turns on an LED on for one second, then off for one second, repeatedly.

This example code is in the public domain.

*/

// Pin 13 has an LED connected on most Arduino boards.

// give it a name:

int led = 13;

// the setup routine runs once when you press reset:

void setup() {

// initialize the digital pin as an output.

pinMode(led, OUTPUT);

}

// the loop routine runs over and over again forever:

void loop() {

digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)

delay(1000); // wait for a second

digitalWrite(led, LOW); // turn the LED off by making the voltage LOW

delay(1000); // wait for a second

}

Первое, на что стоит обратить внимание: в данном скетче множество “комментариев”. Обратите внимание, что комментарии не являются инструкцией по работе программы. Это исключительно пояснения отдельных функций и задач, которые выполняются на определенном этапе кода. Это не обязательная часть кода.
Все между символами /* и */ в верхней части скетча – это комментарии, в которых описаны задачи программы.
Так же есть комментарии, которые ограничиваются одной строкой. Они начинаются с символов // и заканчиваются по умолчанию в конце строки.
Первая важная, по сути, часть данного кода это строка:

int led = 13;

В комментариях над строкой указано, что мы присваиваем имя пину, к которому подключен светодиод. На большинстве плат Arduino это будет 13 пин.
Дальше используется функция “Setup”. Опять-таки, в комментариях указано, что функция срабатывает после нажатия кнопки “reset”. Также эта функция срабатывает, когда плата перезагрузится по каким-либо другим причинам. Например, подача питания или после загрузки скетча.

// the setup routine runs once when you press reset:

void setup() {

// initialize the digital pin as an output.

pinMode(led, OUTPUT);

}

Каждый скетч Arduino обязан включать в себя функцию “setup” и часть, в которую вы можете добавлять собственные инструкции, заключенные между { }.
В нашем примере в функции присутствует только одна команда, в которой указано, что пин, который мы используем, настраивается на “вывод” (“Output”).
Также обязательным для любого скетча является функция цикла “Loop”. В отличие от функции “Setup ”, которая отрабатывает один раз после перезагрузки, функция “Loop” после окончания работы команд, вновь запустится.

// the loop routine runs over and over again forever:

void loop() {

digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)

delay(1000); // wait for a second

digitalWrite(led, LOW); // turn the LED off by making the voltage LOW

delay(1000); // wait for a second

}

В теле функции “Loop” светодиод включается (HIGH), данное значение задерживается на 1000 миллисекунд (1 секунда), светодиод отключается (LOW) и остается выключенным на 1 секунду, после чего цикл повторится.

Изменение частоты мигания светодиода

Для того, чтобы обеспечить более частое мигание светодиода, необходимо изменить параметр, указываемый в скобках ( ) в команде “delay”.

Как уже было указано, период задержки указывается в миллисекундах. То есть, для того, чтобы заставить светодиод мигать в два раза чаще, необходимо изменить значение с 1000 на 500. В результате, пауза между включением/выключением светодиода составит половину секунды и светодиод будет мигать быстрее.

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

Время прочтения
13 мин

Просмотры 8.7K

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

Как известно, язык Wiring на самом деле является полноценным C++, из которого убрана поддержка исключений ввиду их тяжеловесности для среды выполнения и спрятаны некоторые тонкости, связанные со структурой программы, такие как реализация функции main, а разработчику отданы функции setup и loop, которые вызываются из main.

А это означает, что можно пользоваться плюшками C++, даже если о них никто не рассказал.

Всё описанное в статье относится к версиям среды Arduino как минимум от 1.6. Я делал всё под Windows, но для для Linux/MacOS подходы остаются теми же, просто меняются технические детали.

Итак, приступаем.

В среде версии 1.6 по умолчанию используется компилятор GCC версии 4.8, в котором по умолчанию не включена поддержка С++11, но нам же хочется auto, varadic templates и прочие плюшки, не правда ли? А в среде версии 1.8 компилятор уже версии 4.9, поддерживающий С++11 по умолчанию, но и его можно заставить использовать С++14 с его rvalue reference, константными выражениями, разделителями разрядов, двоичными литералами и прочими радостями.

Чтобы добавить поддержку более новых стандартов, чем включены по умолчанию, надо в каталоге установки Arduino открыть файл hardwarearduinoavrplatform.txt, содержащий настройки компиляции, найти там параметр compiler.cpp.flags и указать желаемый стандарт языка: -std=gnu++11 заменить на -std=gnu++14. Если параметра нету — добавить, например в конце строки.

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

Здесь же можно изменить настройки оптимизации, например вместо более компактного кода изменением опции -Os на -Ofast включить генерацию более быстрого кода.

Эти настройки глобальные, поэтому применимы в рамках всех проектов.

Дальше я решил получить более детальный контроль над результатом работы компилятора и добавил некоторый аналог postbuild-событий. Для этого в тот же файл надо добавить параметр recipe.hooks.postbuild.0.pattern, значение которого должно содержать имя файла, который будет запущен после сборки, и аргументы командной строки. Я присвоил ему значение "{compiler.path}stat.bat" "{build.path}/{build.project_name}". Поскольку такого файла пока нет, его надо создать в каталоге hardwaretoolsavrbin (с именем, очевидно, stat.bat).

Напишем туда следующие строки:

"%~dp0avr-objdump.exe" -d -C %1.elf > %1.SX
"%~dp0avr-nm.exe" %1.elf -nCS > %1.names

Первая строка запускает декомпиляцию уже собранной и оптимизированной программы с помощью objdump, создавая выходной файл с именем проекта и дополнительным расширением .SX (выбор произвольный, но будем считать, что S — традиционно ассемблер, а X указывает на факт некоторого преобразования).

Вторая строка извлекает символьные имена областей памяти запуском команды nm и формирует отчёта в файле с дополнительным расширением .names, при этом сортировка выполняется по адресам.

Здесь надо ещё добавить, что сборка ведётся во временном каталоге, и чтобы его посмотреть, нужно зайти в настройки Arduino и включить чекбокс «Показать подробный вывод» -> «Компиляция», после чего запустить эту самую компиляцию и посмотреть, где идёт сборка. В моём случае (IDE версии 1.8.5) это был каталог вида %TEMP%arduino_build_[random].

Читать дизассемблированный код в обычной жизни — удовольствие сомнительное, но может кому-то понадобится (мне доводилось).

Файл имён же в целом более полезен. В спойлере — тестовый скетч, с которым выполнялись опыты:

Тестовый скетч

int counter = 1;

void test(auto&& x) {
  static unsigned long time;
  
  long t = millis();
  Serial.print(F("Counter: "));
  Serial.println(counter);
  Serial.print(F(" At "));
  Serial.print(t);
  Serial.print(F(" value is "));
  Serial.println(x);
  Serial.print(F("Time between iterations: "));
  Serial.println(t - time);
  Serial.println();
  time = t;
}

void setup() {
  Serial.begin(9600);
}

void loop() {  
  delay(100);
  test(digitalRead(A0));
}

Получившийся файл имён целиком тоже под спойлером:

Файл имён целиком


w serialEvent()
00000000 W __heap_end
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 W __vector_default
00000000 T __vectors
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
00000068 T __trampolines_end
00000068 T __trampolines_start
00000068 0000001a t test(int)::__c
00000082 0000000b t test(int)::__c
0000008d 00000005 t test(int)::__c
00000092 0000000a t test(int)::__c
0000009c 00000014 T digital_pin_to_timer_PGM
000000b0 00000014 T digital_pin_to_bit_mask_PGM
000000c4 00000014 T digital_pin_to_port_PGM
000000d8 0000000a T port_to_input_PGM
000000e2 T __ctors_start
000000e4 T __ctors_end
000000e4 T __dtors_end
000000e4 T __dtors_start
000000e4 W __init
000000f0 00000016 T __do_copy_data
00000106 00000010 T __do_clear_bss
0000010e t .do_clear_bss_loop
00000110 t .do_clear_bss_start
00000116 00000016 T __do_global_ctors
00000134 T __bad_interrupt
00000134 W __vector_1
00000134 W __vector_10
00000134 W __vector_11
00000134 W __vector_12
00000134 W __vector_13
00000134 W __vector_14
00000134 W __vector_15
00000134 W __vector_17
00000134 W __vector_2
00000134 W __vector_20
00000134 W __vector_21
00000134 W __vector_22
00000134 W __vector_23
00000134 W __vector_24
00000134 W __vector_25
00000134 W __vector_3
00000134 W __vector_4
00000134 W __vector_5
00000134 W __vector_6
00000134 W __vector_7
00000134 W __vector_8
00000134 W __vector_9
00000138 00000012 T setup
0000014a 000000d8 T loop
00000222 00000094 T __vector_16
000002b6 00000018 T millis
000002ce 00000046 T micros
00000314 00000050 T delay
00000364 00000076 T init
000003da 00000052 t turnOffPWM
0000042c 00000052 T digitalRead
0000047e 00000016 T HardwareSerial::available()
00000494 0000001c T HardwareSerial::peek()
000004b0 00000028 T HardwareSerial::read()
000004d8 000000b8 T HardwareSerial::write(unsigned char)
00000590 000000a4 T HardwareSerial::flush()
00000634 0000001c W serialEventRun()
00000650 00000042 T HardwareSerial::_tx_udr_empty_irq()
00000692 000000d0 T HardwareSerial::begin(unsigned long, unsigned char)
00000762 00000064 T __vector_18
000007c6 0000004c T __vector_19
00000812 00000014 T Serial0_available()
00000826 00000086 t _GLOBAL__sub_I___vector_18
000008ac 00000002 W initVariant
000008ae 00000028 T main
000008d6 00000058 T Print::write(unsigned char const*, unsigned int)
000008ff W __stack
0000092e 0000004a T Print::print(__FlashStringHelper const*)
00000978 00000242 T Print::print(long, int)
00000bba 00000016 T Print::println()
00000bd0 0000029a T Print::println(int, int)
00000e6a 0000013a T Print::println(unsigned long, int)
00000fa4 00000002 t __empty
00000fa4 00000002 W yield
00000fa6 00000044 T __udivmodsi4
00000fb2 t __udivmodsi4_loop
00000fcc t __udivmodsi4_ep
00000fea 00000004 T __tablejump2__
00000fee 00000008 T __tablejump__
00000ff6 T _exit
00000ff6 W exit
00000ff8 t __stop_program
00000ffa A __data_load_start
00000ffa T _etext
00001016 A __data_load_end
00800100 D __data_start
00800100 00000002 D counter
00800102 00000010 V vtable for HardwareSerial
0080011c B __bss_start
0080011c D __data_end
0080011c D _edata
0080011c 00000004 b test(int)::time
00800120 00000001 b timer0_fract
00800121 00000004 B timer0_millis
00800125 00000004 B timer0_overflow_count
00800129 0000009d B Serial
008001c6 B __bss_end
008001c6 N _end
00810000 N __eeprom_end

Как это читать? Давайте разбираться.

В контроллерах AVR две независимые области памяти: память программы и память данных. Соотвественно, указатель на код и указатель на данные — это не одно и то же. Про EEPROM пока молчу, там отдельный разговор про адресацию. В дампе память программы расположена по смещению 0 и с него начинается выполнение, и там же располагается таблица векторов прерываний, по 4 байта на элемент. В отличие от x86, каждый вектор прерываний содержит не адрес обработчика, а инструкцию, которую надо выполнить. Обычно (я не видел других вариантов) — jmp, то есть переход в нужный адрес. К векторам прерываний мы ещё потом ненадолго вернёмся, а пока смотрим дальше.

Память данных состоит из двух частей: регистровый файл со смещения 0 и данные в оперативной памяти (SRAM) со смещения 0x100. Когда выводится дамп памяти, то к адресам SRAM добавляется смещение 0x00800000, которое ничего не значит по сути, но просто удобно. Отмечу также, что смещение EEPROM имеет значение 0x00810000, но нам это не нужно.

Давайте начнём с данных, тут всё немного проще и привычнее, а потом вернёмся к коду. Первый столбец — смещение, второй — размер, дальше тип (пока не обращаем внимание), дальше до конца строки — имя.

Идём на смещение 0x00800100 и видим там записи:

00800100 D __data_start
00800100 00000002 D counter
00800102 00000010 V vtable for HardwareSerial
0080011c D __data_end

Это аналог секции .data и содержит инициализированные глобальные и статические переменные, а также таблицы виртуальных методов. Эти переменные будут проинициализированы bootstrap-кодом, что займёт некоторое время.

Дальше идём (пускай вас не смущает, что __bss_start и __data_end идут в произвольном порядке — они имеют общий адрес).

0080011c B __bss_start
0080011c 00000004 b test(int)::time
00800120 00000001 b timer0_fract
00800121 00000004 B timer0_millis
00800125 00000004 B timer0_overflow_count
00800129 0000009d B Serial
008001c6 B __bss_end

Это секция неинициализированных данных (аналог .bss). Она даётся даром, поскольку заполнена нулевыми байтами. Здесь несколько вспомогательных переменных, имена который начинаются с timer0_, глобальный объект Serial и наша статическая локальная переменная.

Маленькое лирическое отступление: обратите внимание, что объект Serial изначально пуст, и он будет проинициализирован, когда на нём будет вызван метод begin. Для этого есть несколько причин. Во-первых, он может вообще не использоваться (тогда он вообще не будет создан и место под него выделяться не будет), а во-вторых, мы же знаем, что порядок инициализации глобальных объектов не определён, и до входа в main строго говоря контроллер не инициализирован корректно.

По более высоким адресам располагается стек. Если объём памяти контроллера 2 килобайта (платы на базе процессора atmega328), то последний адрес будет 0x008008FF. С этого адреса начинается стек и растёт он в сторону уменьшения адресов. Нет никаких барьеров, и в принципе стек может наползти на переменные, испортив их. Или данные могут испортить стек — как повезёт. В этом случае ничего хорошего не произойдёт. Можно это назвать неопределённым поведением, но лучше всегда в памяти оставлять достаточно места для стека. Сколько — сложно сказать. Чтобы хватило на локальные переменные и кадры стека всех вызовов плюс для самого тяжёлого обработчика прерывания со всеми вложенными вызовами. Я, честно говоря, более-менее честного решения относительно того, как диагностировать использование стека, не нашёл.

Давайте вернёмся к коду. Когда я говорил, что там хранится код, я немного лукавил. На самом деле там могут храниться и данные, доступные только для чтения, но извлекаются они оттуда специальной инструкцией процессора LPM. Так вот, константные данные можно размещать там и размещать даром, потому как на их инициализацию не тратится время. Обратите внимание на макросы F(…) в коде. Они как раз объявляют строки размещёнными в программной памяти и дальше делает немножко магии. Не будем вдаваться в подробности магии, а поищем их в памяти. Такие макросы идут в функции test, и в дампе мы их увидим как

00000068 0000001a t test(int)::__c
00000082 0000000b t test(int)::__c
0000008d 00000005 t test(int)::__c
00000092 0000000a t test(int)::__c

Несмотря на то, что они имеют одинаковые имена, они находятся по разным адресам. Потому что макрос F(…) создаёт область видимости в фигурных скобках, и переменные (точнее константы) друг другу не мешают. Если посмотреть дизассемблерный дамп, то это и будут адреса строк в программной памяти.

И напоследок обещанное о прерываниях. Библиотеки используют некоторые ресурсы контроллера для поддержки работы периферии: таймеры, коммуникационные интерфейсы и т.п. Они регистрируют свои обработчики прерывания, хранят в памяти свои переменные, а в программной памяти — константы. Если скомпилировать пустой скетч, то дамп памяти будет такой:

Дамп памяти пустого скетча

w serialEventRun()
00000000 W __heap_end
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 W __vector_default
00000000 T __vectors
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
00000068 T __ctors_end
00000068 T __ctors_start
00000068 T __dtors_end
00000068 T __dtors_start
00000068 W __init
00000068 T __trampolines_end
00000068 T __trampolines_start
00000074 00000010 T __do_clear_bss
0000007c t .do_clear_bss_loop
0000007e t .do_clear_bss_start
0000008c T __bad_interrupt
0000008c W __vector_1
0000008c W __vector_10
0000008c W __vector_11
0000008c W __vector_12
0000008c W __vector_13
0000008c W __vector_14
0000008c W __vector_15
0000008c W __vector_17
0000008c W __vector_18
0000008c W __vector_19
0000008c W __vector_2
0000008c W __vector_20
0000008c W __vector_21
0000008c W __vector_22
0000008c W __vector_23
0000008c W __vector_24
0000008c W __vector_25
0000008c W __vector_3
0000008c W __vector_4
0000008c W __vector_5
0000008c W __vector_6
0000008c W __vector_7
0000008c W __vector_8
0000008c W __vector_9
00000090 00000002 T setup
00000092 00000002 T loop
00000094 00000002 W initVariant
00000096 00000028 T main
000000be 00000094 T __vector_16
00000152 00000076 T init
000001c8 T _exit
000001c8 W exit
000001ca t __stop_program
000001cc A __data_load_end
000001cc a __data_load_start
000001cc T _etext
000008ff W __stack
00800100 B __bss_start
00800100 D _edata
00800100 00000001 b timer0_fract
00800101 00000004 B timer0_millis
00800105 00000004 B timer0_overflow_count
00800109 B __bss_end
00800109 N _end
00810000 N __eeprom_end

Немало, неправда ли?

А вот код:

Дизассемблированный код

/empty.cpp.elf:     file format elf32-avr

Disassembly of section .text:

00000000 <__vectors>:
   0:	0c 94 34 00 	jmp	0x68	; 0x68 <__ctors_end>
   4:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
   8:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
   c:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  10:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  14:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  18:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  1c:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  20:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  24:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  28:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  2c:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  30:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  34:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  38:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  3c:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  40:	0c 94 5f 00 	jmp	0xbe	; 0xbe <__vector_16>
  44:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  48:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  4c:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  50:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  54:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  58:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  5c:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  60:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>
  64:	0c 94 46 00 	jmp	0x8c	; 0x8c <__bad_interrupt>

00000068 <__ctors_end>:
  68:	11 24       	eor	r1, r1
  6a:	1f be       	out	0x3f, r1	; 63
  6c:	cf ef       	ldi	r28, 0xFF	; 255
  6e:	d8 e0       	ldi	r29, 0x08	; 8
  70:	de bf       	out	0x3e, r29	; 62
  72:	cd bf       	out	0x3d, r28	; 61

00000074 <__do_clear_bss>:
  74:	21 e0       	ldi	r18, 0x01	; 1
  76:	a0 e0       	ldi	r26, 0x00	; 0
  78:	b1 e0       	ldi	r27, 0x01	; 1
  7a:	01 c0       	rjmp	.+2      	; 0x7e <.do_clear_bss_start>

0000007c <.do_clear_bss_loop>:
  7c:	1d 92       	st	X+, r1

0000007e <.do_clear_bss_start>:
  7e:	a9 30       	cpi	r26, 0x09	; 9
  80:	b2 07       	cpc	r27, r18
  82:	e1 f7       	brne	.-8      	; 0x7c <.do_clear_bss_loop>
  84:	0e 94 4b 00 	call	0x96	; 0x96 <main>
  88:	0c 94 e4 00 	jmp	0x1c8	; 0x1c8 <_exit>

0000008c <__bad_interrupt>:
  8c:	0c 94 00 00 	jmp	0	; 0x0 <__vectors>

00000090 <setup>:
  90:	08 95       	ret

00000092 <loop>:
  92:	08 95       	ret

00000094 <initVariant>:
  94:	08 95       	ret

00000096 <main>:
  96:	0e 94 a9 00 	call	0x152	; 0x152 <init>
  9a:	0e 94 4a 00 	call	0x94	; 0x94 <initVariant>
  9e:	0e 94 48 00 	call	0x90	; 0x90 <setup>
  a2:	80 e0       	ldi	r24, 0x00	; 0
  a4:	90 e0       	ldi	r25, 0x00	; 0
  a6:	89 2b       	or	r24, r25
  a8:	29 f0       	breq	.+10     	; 0xb4 <main+0x1e>
  aa:	0e 94 49 00 	call	0x92	; 0x92 <loop>
  ae:	0e 94 00 00 	call	0	; 0x0 <__vectors>
  b2:	fb cf       	rjmp	.-10     	; 0xaa <main+0x14>
  b4:	0e 94 49 00 	call	0x92	; 0x92 <loop>
  b8:	0e 94 49 00 	call	0x92	; 0x92 <loop>
  bc:	fb cf       	rjmp	.-10     	; 0xb4 <main+0x1e>

000000be <__vector_16>:
  be:	1f 92       	push	r1
  c0:	0f 92       	push	r0
  c2:	0f b6       	in	r0, 0x3f	; 63
  c4:	0f 92       	push	r0
  c6:	11 24       	eor	r1, r1
  c8:	2f 93       	push	r18
  ca:	3f 93       	push	r19
  cc:	8f 93       	push	r24
  ce:	9f 93       	push	r25
  d0:	af 93       	push	r26
  d2:	bf 93       	push	r27
  d4:	80 91 01 01 	lds	r24, 0x0101
  d8:	90 91 02 01 	lds	r25, 0x0102
  dc:	a0 91 03 01 	lds	r26, 0x0103
  e0:	b0 91 04 01 	lds	r27, 0x0104
  e4:	30 91 00 01 	lds	r19, 0x0100
  e8:	23 e0       	ldi	r18, 0x03	; 3
  ea:	23 0f       	add	r18, r19
  ec:	2d 37       	cpi	r18, 0x7D	; 125
  ee:	20 f4       	brcc	.+8      	; 0xf8 <__vector_16+0x3a>
  f0:	01 96       	adiw	r24, 0x01	; 1
  f2:	a1 1d       	adc	r26, r1
  f4:	b1 1d       	adc	r27, r1
  f6:	05 c0       	rjmp	.+10     	; 0x102 <__vector_16+0x44>
  f8:	26 e8       	ldi	r18, 0x86	; 134
  fa:	23 0f       	add	r18, r19
  fc:	02 96       	adiw	r24, 0x02	; 2
  fe:	a1 1d       	adc	r26, r1
 100:	b1 1d       	adc	r27, r1
 102:	20 93 00 01 	sts	0x0100, r18
 106:	80 93 01 01 	sts	0x0101, r24
 10a:	90 93 02 01 	sts	0x0102, r25
 10e:	a0 93 03 01 	sts	0x0103, r26
 112:	b0 93 04 01 	sts	0x0104, r27
 116:	80 91 05 01 	lds	r24, 0x0105
 11a:	90 91 06 01 	lds	r25, 0x0106
 11e:	a0 91 07 01 	lds	r26, 0x0107
 122:	b0 91 08 01 	lds	r27, 0x0108
 126:	01 96       	adiw	r24, 0x01	; 1
 128:	a1 1d       	adc	r26, r1
 12a:	b1 1d       	adc	r27, r1
 12c:	80 93 05 01 	sts	0x0105, r24
 130:	90 93 06 01 	sts	0x0106, r25
 134:	a0 93 07 01 	sts	0x0107, r26
 138:	b0 93 08 01 	sts	0x0108, r27
 13c:	bf 91       	pop	r27
 13e:	af 91       	pop	r26
 140:	9f 91       	pop	r25
 142:	8f 91       	pop	r24
 144:	3f 91       	pop	r19
 146:	2f 91       	pop	r18
 148:	0f 90       	pop	r0
 14a:	0f be       	out	0x3f, r0	; 63
 14c:	0f 90       	pop	r0
 14e:	1f 90       	pop	r1
 150:	18 95       	reti

00000152 <init>:
 152:	78 94       	sei
 154:	84 b5       	in	r24, 0x24	; 36
 156:	82 60       	ori	r24, 0x02	; 2
 158:	84 bd       	out	0x24, r24	; 36
 15a:	84 b5       	in	r24, 0x24	; 36
 15c:	81 60       	ori	r24, 0x01	; 1
 15e:	84 bd       	out	0x24, r24	; 36
 160:	85 b5       	in	r24, 0x25	; 37
 162:	82 60       	ori	r24, 0x02	; 2
 164:	85 bd       	out	0x25, r24	; 37
 166:	85 b5       	in	r24, 0x25	; 37
 168:	81 60       	ori	r24, 0x01	; 1
 16a:	85 bd       	out	0x25, r24	; 37
 16c:	ee e6       	ldi	r30, 0x6E	; 110
 16e:	f0 e0       	ldi	r31, 0x00	; 0
 170:	80 81       	ld	r24, Z
 172:	81 60       	ori	r24, 0x01	; 1
 174:	80 83       	st	Z, r24
 176:	e1 e8       	ldi	r30, 0x81	; 129
 178:	f0 e0       	ldi	r31, 0x00	; 0
 17a:	10 82       	st	Z, r1
 17c:	80 81       	ld	r24, Z
 17e:	82 60       	ori	r24, 0x02	; 2
 180:	80 83       	st	Z, r24
 182:	80 81       	ld	r24, Z
 184:	81 60       	ori	r24, 0x01	; 1
 186:	80 83       	st	Z, r24
 188:	e0 e8       	ldi	r30, 0x80	; 128
 18a:	f0 e0       	ldi	r31, 0x00	; 0
 18c:	80 81       	ld	r24, Z
 18e:	81 60       	ori	r24, 0x01	; 1
 190:	80 83       	st	Z, r24
 192:	e1 eb       	ldi	r30, 0xB1	; 177
 194:	f0 e0       	ldi	r31, 0x00	; 0
 196:	80 81       	ld	r24, Z
 198:	84 60       	ori	r24, 0x04	; 4
 19a:	80 83       	st	Z, r24
 19c:	e0 eb       	ldi	r30, 0xB0	; 176
 19e:	f0 e0       	ldi	r31, 0x00	; 0
 1a0:	80 81       	ld	r24, Z
 1a2:	81 60       	ori	r24, 0x01	; 1
 1a4:	80 83       	st	Z, r24
 1a6:	ea e7       	ldi	r30, 0x7A	; 122
 1a8:	f0 e0       	ldi	r31, 0x00	; 0
 1aa:	80 81       	ld	r24, Z
 1ac:	84 60       	ori	r24, 0x04	; 4
 1ae:	80 83       	st	Z, r24
 1b0:	80 81       	ld	r24, Z
 1b2:	82 60       	ori	r24, 0x02	; 2
 1b4:	80 83       	st	Z, r24
 1b6:	80 81       	ld	r24, Z
 1b8:	81 60       	ori	r24, 0x01	; 1
 1ba:	80 83       	st	Z, r24
 1bc:	80 81       	ld	r24, Z
 1be:	80 68       	ori	r24, 0x80	; 128
 1c0:	80 83       	st	Z, r24
 1c2:	10 92 c1 00 	sts	0x00C1, r1
 1c6:	08 95       	ret

000001c8 <_exit>:
 1c8:	f8 94       	cli

000001ca <__stop_program>:
 1ca:	ff cf       	rjmp	.-2      	; 0x1ca <__stop_program>

Задействовано прерывание таймера, 9 байт на обслуживание этого таймера, и некоторое количество инфраструктурного кода.

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

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

И вот, наступает момент, когда стандартная Arduino IDE становится тесновата, а ее неудобство начинает просто выбешивать, особенно, если пользователь знаком с более продвинутыми средами разработки по другим платформам и языкам программирования. Кто-то начинает мигрировать на что-то более интересное, например, на Atom или VS.Code в смеси с PlatformIO, а кто-то старается выжать из Arduino IDE все, что только можно.

Сегодня я выступлю как раз в роли подобного «особо интересующегося персонажа» и попробую вместе с читателем разобраться чуть-чуть побольше в тонкостях Arduino IDE. Все ниженаписанное более-менее соответствует версии 1.8.9 Arduino IDE.

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

arduino ide, dark theme, темна тема, ардуино.

Вариант темной темы под Mac. Скриншот с GitHub.

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

Меню Sketch

Я, как и большинство других пользователей Arduino IDE, загружаю свои скетчи в платы при помощи панели инструментов. Щелкнул на кнопку загрузки и скетч начал заливать в плату. Удобно. Но, как оказывается, меню Sketch (здесь и далее я буду использовать английский вариант интерфейса Arduino) содержит не мало интересных и полезных новшеств. Итак, кратенько пробежимся по ним.

sketch, arduino ide, 1.8.9, veryfy/compile, Upload, Upload Using Programmer, Export compiled Binary, Show Sketch Folder, Include Library, Add File...

Меню Sketch Arduino IDE

Пункты меню Very/Compile и Upload стандартны и знакомы всем. Именно они используются для проверки правильности кода и последующей нормальной загрузки. А вот пункт Upload using programmer для меня до недавнего времени оставался Terra incognita. Как оказалась, данный пункт необходимо применять при загрузки скетча без использования загрузчика (bootloader), но с использованием полноценного программатора. О загрузчиках и программаторах поговорим немного позже, пока же просто запомним этот пункт.

В этом же меню присутствует весьма полезный пункт Export compiled Binary. Применяется он в том же направлении, что и Upload using programmer. По умолчанию Arduino IDE компилирует исходный код в файл, который сохраняется во временную директорию и после завершения загрузки она должна очищаться. Временная директория находится в каких-то дебрях файловой системы, а искать там скомпилированный файл с непонятным наименованием — то еще удовольствие. Так вот функция Export compiled Binary как раз и применяется для того, чтобы сохранить уже откомпилированный скетч в виде бинарных-файлов в папке самого скетча. В дальнейшем скомпилированные скетчи могут быть прошиты при помощи внешнего программатора или же USB-TTL преобразователя.

Кстати, просмотреть папку скетча можно все через тоже самое меню Sketch при помощи пункта Show Sketch Folder. Кстати, при вызове Export compiled Binary компилируется сразу два файла: с и без загрузчика. Для чего это нужно, опять же немного ниже. При компилировании при помощи Export compiled Binary следует учитывать, что примеры из поставки Arduino так откомпилировать не выйдет. Папки, в которых хранятся эти скетчи имеют режим только для чтения, а IDE необходимо куда-то записать скомпилированные файлы (обычно в таком случае возникает ошибка «Export canceled, changes must first be saved.»). Поэтому тренируемся на своих собственных скетчах или же пересохраняем скетч в новую папку.

Меню Tools

Меню Tools в Arduino IDE дает куда больше интересного и полезного, нежели Sketch. Более того, сам вид меню зависит от того, какую платформу вы выбрали в качестве целевой.

arduino, 1.8.9, tools, auto format, archive sketch, burn bootloader

Меню Tools Arduino IDE с выбранным микроконтроллером семейства AVR.

Начнем с общего и тех пунктов, которые есть в оригинальных платах, построенных на микроконтроллерах Atmel (ее все же купила Microchip).

Пункт Auto Format позволяет отформатировать ваш исходный текст по общепринятому в Arduino IDE стандарту. Отформатированный текст позволяет легче находить ошибки, да и сама программа выглядит опрятно. Так же, зачастую, при форматировании при помощи автоформата получается найти такие ошибки, как отсутствующие скобки, что при большом количестве вложений несколько затруднительно. Оная же функция вызывается и в самом редакторе в контекстном меню доступном по правой кнопке мышки.

Archive Sketch позволяет упростить навигацию по папке в которой хранятся все ваши скетчи. Напомню, что каждый скетч хранится в отдельной папке, куда складывается все, что к нему относится. Если скетчей у вас много, особенно если плодить версии в новых папках, то разобраться во всем этом нагромождении становится очень сложно. Для этого и можно применить функцию архивирования. Папка со скетчем будет сжата в архив ZIP, а затем стерта из каталога. Останется только архив.

Serial Plotter противовес Serial Monitor предназначен для вывода графика из данных выдаваемых в последовательный порт. Все, что от вас требуется для построения графика — выплевывать в порт цифры при помощи Serial.println(). Неплохой пример использования плоттера приведен на страницах проекта wikihandbk.

Приведенные выше пункты стандартны. Их использование, вкупе с Library Manager должны быть известны даже неопытным пользователям. А дальше попробуем погрузиться в чащобы Arduino IDE и мир программирования микроконтроллеров.

WiFi101 / WiFiNINA Firmware Updater

Сетевое взаимодействие для оригинальных плат Arduino всегда было ахиллесовой пятой. Их просто нет в стандартной поставке, а все решения в виде внешних плат настолько ди́ки, что просто пропадает всякое желание их использовать. По этой причине многие используют платы на основе ESP8266, которые дешевле, мощнее и сразу с WiFi на борту. Но итальянцы, да и ардуинщики вообще, ребята упорные, поэтому вместо того, чтобы переходить на нормальные платы, продолжают изобретать очередные ужасы, к которым и относятся WiFi101 и WiFiNINA.

WiFi 101 shield, arduino

WiFi 101 Shield. Взято откуда-то с просторов сети.

Собственно этот пункт меню предназначен для обновления прошивки и сертификатов соответствующих плат.

arduino, board, uno wifi, ublox, power, analog in

Arduino Uno с платой WiFi под библиотеку WiFiNINO

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

ESP Exception Decoder

Плагин для Arduino IDE под непонятным названием ESP Exception Decoder предназначен для более легкой отладки программ под платформу ESP8266. Exception или «исключение» обозначает возникновение ошибочной ситуации которая не была корректно обработана кодом. Например, деление на 0 однозначно вызовет исключение, и работа программы будет прервана. В языке, на котором программируют в Arduino IDE нет возможности использовать блоки try {} catch {}, соответственно работа с исключениями невозможна (точнее по синтаксису он есть, но компилятор его отвергнет, по крайней мере для плат на основе AVR). Программист обязан предусматривать и проверять данные и предупреждать возникновение подобных ситуаций. Иначе результат может быть непредсказуемым.

На первоначальной экосистеме Arduino, построенной на Atmel AVR (об этом опять же дальше) нет места исключениям. И даже несмотря на то, что язык, применяемый для программирования в Arduino IDE есть ни что иное как диалект C++, в нем так же нет исключений и они не поддерживаются компилятором, ибо в AVR нет исключений, слишком там мало места для еще и исключений. Сильно жизнь это не осложняет, просто программы пишутся куда более аккуратно. А вот в экосистеме ESP, в том числе и под Arduino, исключения присутствуют.

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

esp8266, reset reason, reset info

Вот такую вот информацию сохраняет esp8266 после перезагрузки. В этом случае произошла перезагрузка по питанию.

Система в чипах ESP более замороченная, чем в AVR и при возникновении нештатной ситуации выплевывает в последовательный порт некий стек адресов, по которым можно добраться до истинной причины возникновения ошибки. Но выдаются адреса в совсем нечитаемом человеком виде. Чтобы сопоставить строчку в исходном коде с конкретным адресом, выданным в стеке, и был придумал ESP Exception Decoder.

arduino ide, esp8266, exception, stack, soft wdt reset

Намеренный вызов исключения на WeMos Mini

После возникновения ошибки необходимо перенести стек в декодировщик и он выдаст «путь» по которому можно дойти до строки в годе где и возникла исключительная ситуация. В некоторых случаях функция исключительно удобная. Ознакомиться с подробной инструкцией по применению декодировщика можно на страничке проекта ESP Arduino Core.

Get Board Info

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

Burn Bootloader

Наконец-то мы начинаем подбираться к действительно интересным пунктам меню. Начнем с пункта загрузки загрузчика (Burn Bootloader). Но для начала попытаемся понять, что такое bootloader и для чего он нужен. В старые далекие ламповые времена тоже существовали программируемые микросхемы. Но программировались они весьма жестким способом. Использовался специальный программатор, в который вставлялась микросхема, происходило таинство, и микросхему можно было использовать в оборудовании.

Сей способ с одной стороны достаточно прост, но с другой он очень неудобен. Ведь чтобы сменить прошивку на уже прошитой микросхеме, если это вообще возможно, ее необходимо вытащить из устройства, установить в программатор и повторить процедуру. Что далеко не всегда возможно, так как микросхема может быть впаянной в плату и без специализированного оборудования достать ее оттуда нельзя или же само устройство летает на спутнике. Именно для этих целей была придумана методика ISP (In-System Programming), что в переводе означает ни что иное как «внутрисхемное программирование». ISP не стоит путать с SPI (Serial Peripheral Interface). ISP это именно внутрисхемная прошивка, а SPI это стандарт взаимодействия между устройствами. И пусть даже вас не вводят в заблуждения сильно похожие разъемы и наименования контактов. ISP и SPI это разные вещи.

В общем случае ISP позволяет программировать микроконтроллер через любой его интерфейс и даже программироваться самостоятельно с изменением своего кода посредством своего собственного же кода. Но для осуществления подобных фокусов требуется некая программа, которая будет сидеть в микроконтроллере и управлять этим программированием. Именно она и называется загрузчиком (bootloader). И именно благодаря ей есть возможность прошивать микроконтроллеры просто подключив их к USB-порту, или же применив простейший программатор на параллельном порту компьютера (у кого они еще остались), а в некоторых случаях обновление прошивки можно загружать вообще по воздуху применяя прием OTA (Over The Air).

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

Для Arduino существует несколько вариантов загрузчиков. Стандартный, который прошивается еще при изготовлении платы Arduino, многие не любят. Дескать он притормаживает при загрузке устройства в ожидании передачи данных для прошивки и только спустя десять секунд запускает ваш прошитый скетч. Дело в том, что некоторые платы Arduino, в которых не реализован механизм DTR (Data Terminal Ready) / RTS (Ready To Send) действительно нужно прошивать очень быстро иначе bootloader просто передаст управление той микропрограмме, что уже находится в микропроцессоре. Вот и начали все, кому не лень, модифицировать штатный загрузчик или же писать свой собственный.

arduino, hardware, bootlaoders

Стандартные загрузчики для плат Arduino

Где брать загрузчики? Вообще стандартный загрузчик можно загрузить прямо из Arduino. Для этих целей и предназначен пункт меню Burn Bootloader. А сами загрузчики из стандартной поставки можно найти в папке с установленным Arduino в поддиректории hardware. Если же вы используете платы отличные от Arduino AVR, например, ESP3288, то все дополнительные загрузчики и прочие инструменты можно найти в личном профиле пользователя (AppDataLocal).

esp, bootloader

Загрузчик для плат семейства ESP

Но если вы скачиваете дополнительные загрузчики и хотите установить их в Arduino IDE, то можно использовать папку hardware в вашем каталоге для скетчей. После перезагрузки IDE загрузчики из этой папки так же будут доступны, однако не следует забывать про файл boards.txt который должен присутствовать в подпапках папки hardware. Если у вас вдруг нет текстового редактора или же вы испытываете трудности с редактированием boards.txt то есть решение. Один энтузиаст создал специальную программу Arduino BOARDS.TXT Editor, которая позволяет с легкостью вносить изменения в указанный файл.

Так, где же брать эти самые альтернативные загрузчики? Искать в сети. Поисковики выдают просто немыслимое количество разнообразных вариантов. Для начала можно остановиться на OptiBoot, попробовать калькулятор «формирующий» загрузчик под конкретную плату или начать просматривать ссылки с официальной страницы загрузчиков Arduino.

И подводя промежуточный итог, если нам нужно загрузить прошивку без загрузчика (так для нее останется больше места) в микроконтроллер, то подключаем его к программатору и загружаем прошивку через Sketch – Upload Using Programmer. Если же хотим вернуться к обычной и удобной загрузке скетчей через среду Arduino по USB и без прочих танцев африканских народов, то прошиваем загрузчик обратно (или же мы купили микроконтроллер без загрузчика) уже посредством Tools – Burn Bootloader. В обоих случаях незабываем про корректный выбор платы, программатора и прочих настроек.

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

AVR и прочие

Для лучшего понимания дальнейшей информации я хочу привести некоторые сведения о самих микроконтроллерах с которых пошло-поехало Arduino. Мы уже знаем, что оригинальные Arduino построены на микроконтроллерах (больших интегральных схемах, которые можно программировать и которые могут работать и сами по себе без внешней обвязки, подавай только напряжение) от компании Atmel (нынче Microchip).

У компании Atmel наработано несколько линеек микроконтроллеров, но нас в первую очередь интересует линейка AVR (кстати, аббревиатура AVR официально никак не расшифровывается), так как именно на ней и построены оригинальные Arduino. Линейка появилась аж в 1996 году и, пожалуй, была одна из первых на рынке предложившей решение, где микроконтроллер и память (ОЗУ и ПЗУ) расположены в рамках одного единственного кристалла. Повторюсь, чтобы система работала достаточно только одной микросхемы AVR на которую подается питание. Все остальное у нее уже есть внутри.

AVR линейка делится на несколько основных групп:

  • tinyAVR – с уменьшенным количеством линий ввода-вывода, уменьшенным количеством памяти всех типов, обозначается как ATtinyxxx.
  • megaAVR – увеличенное количество памяти всех типов, увеличенное количество линий ввода-вывода, расширенный набор для периферии и тому подобное. Обозначается как ATmegaxxx.
  • XMEGA – ко всему увеличенному у megaAVR тут еще увеличили памяти и добавили встроенный контроллер для быстрой работы с памятью. Обозначается как ATxmegaxxx.

Именно микросхемы AVR обеспечивают поддержку таких функций как АЦП, ШИМ, SPI, I2C и прочих. Arduino же просто их использует (хотя с появлением более мощных микроконтроллеров, тех же esp8266, появилась возможность эмуляции вышеназванных функций программным способом).

И вопреки возможности прошивки AVR методом ISP посредством стандарта SPI через установленный загрузчик, для программирования микроконтроллеров применяется великое множество программаторов. Как простых и собираемых на коленке, так и сложных с внешним питанием и обилием всевозможных функций. Но прежде, чем мы перейдем к рассмотрению программаторов следует пояснить еще один момент. При программировании микроконтроллера с использованием внешнего программатора (без использования загрузчика) необходимо четко понимать, что такое fuses или не трогать настройки, связанные с ними, если такого понимания нет. Fuse/фьюзы/предохранительные биты — это настройки внутри микроконтроллера, в частности AVR. Они прошиваются точно так же, при помощи внешнего программатора (без применения ISP). И обычно применяются для настройки самого микроконтроллера, например, можно включить или отключить возможность самопрошивки контроллера, включение или отключение внешнего сброса устройства (и соответственно возможности его прошивки через bootloader), включение и отключение очистки памяти при перепрограммировании чипа и тому подобное. Подробнее ознакомиться с фьюзами можно (и нужно) в документации к конкретному контроллеру. К чипу ATmega328, одному из самых популярных чипов на Arduino, документация доступна на официальном сайте производителя.

Programmer:

Пожалуй, что пункт меню Tools под кодовым названием Programmer является самым таинственным местом всего Arduino IDE. Информации по данному пункту очень мало, и она настолько скудна что может привести к разочарованию даже самого стойкого прагматика. Очевидно, что данный пункт содержит выбор программаторов для программирования плат. И кажется, что одну и ту же плату можно запрограммировать кучей разных способов и программаторов. Но, а что же нам на этот счет говорит документация к Arduino IDE? А она нам вещает о том, что данный пункт меню Tools имеет смысл только при прошивке загрузчика. Во всех остальных случаях используемый «прошивальщик» зашит в тот самый boards.txt, что обсуждался немного ранее. Причем для микроконтроллеров AVR это всегда avrdude, а для ESP это всегда esptool. Кроме того, для плат AVR может применяться, в штатной поставке, целых два различных протокола «закачки» прошивки в микроконтроллер: avr109 и arduino. Разные протоколы, как не сложно догадаться, применяются для разных загрузчиков, установленных в конкретные микроконтроллеры.

В штатной поставке Arduino IDE с подключенной инфраструктурой ESP для прошивки загрузчика можно применить несколько типов программаторов. Кратко пройдемся по ним всем. По факту все AVR в Arduino IDE прошиваются посредством приблуды AVRDUDE (бывший AVRProg) и различия между «программаторами» только в используемом протоколе и настройках AVRDUDE. На текущий момент AVRDUDE поддерживает 39 программаторов, но в Arduino IDE используется только 14. Ознакомиться с настройками каждого из них можно в файле programmers.txt в той самой директории hardware, где складируется файлик boards.txt. Информация по настройкам для каждого из программатора доступна в файле avrdude.conf (располагается обычно в Arduinohardwaretoolsavretc) и в куцей документации к самому AVRDUDE.

AVR ISP

AVRISP есть ни что иное как фирменный программатор от Atmel. Он позволят программировать AVR. И похоже, что на этом все. Мне ну далось найти хоть сколько-нибудь достоверной информации про данный программатор, кажется, что он сошел со сцены и осел где-то в дебрях плат у аксакалов еще до появления Интернет.

atmel, skt500, v1

Отладочная плата Atmel STK500. Фото производителя.

Единственное, что хоть как-то проливает свет на данный программатор, так это то, что он по факту является частью STK500 (такая отладочная плата для AVR от Atmel) версии 1, которая подкачается к компьютеру посредством последовательно порта.

AVRISP mkII

А вот AVRISP mkii является актуальным программатором, подключаемым к USB. По крайней мере о нем есть информация на сайте производителя и большинство безродных программаторов, которые продаются бесчисленными компаниями как раз и являются клонами именно этого программатора.

avr, avrisp, ips, программатор

Фирменный программатор AVRISP mkII. Фото производителя.

Тем не менее, он так же является частью отладочной платы STK500, но уже версии 2, которая подключается к компьютеру уже по интерфейсу USB. Хотя, по отзывам очевидцев и версия 1 может использовать с USB посредством конвертера COM-USB.

USBtinyISP

Это один из программаторов, который можно собрать своими руками, он прост и дешев, а в качестве «сердца» у него используется чип tinyAVR. Вот только возникает вопрос – как же его прошивать, если он сам и предназначен для прошивки AVR?

Тем не менее, программатор поддерживается Arduino IDE и весьма популярен. Программатор был разработан в Нидерландах, но в настоящее время поддерживается AdaFruit.

ArduinoISP и ArduinoISP.org

Что подразумевали под этими двумя программаторами разработчики Arduino IDE остается только гадать, да угадывать. Сайт ArudinoISP.org дает перенаправление на туториал на сайте Arduino.cc по использованию Arduino as ISP. Единственное отличие этих двух от Arduino as ISP только лишь используемый протокол. Вероятно, что они были когда-то собраны в качестве поддержки особого загрузчика, а с течением времени исчезли с лица истории. По крайней мере в документации AVRDUDE никакого упоминания ни про arduinoisp ни про arduinoisporg просто нет.

USBasp

Еще один простой программатор, который можно собрать дома на коленке. И он тоже построен на чипе от Atmel. Проект был развернут немецкий программистом, а затем подхвачен всем миром. Как и с USBtinyISP чип от Atmel для программатора необходимо запрограммировать.

Parallel Programmer

Данный тип программатора считается одним из самый простых, если не самым простым. По сути «параллельный программатор» — распиновка параллельного порта компьютера и соответствующее программное обеспечение.

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

Arduino as ISP

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

Для этого в плату Arduino закачивается скетч из примеров под именем ArduinoISP, соединяются проводки (между платой, в которую залит скетч и платой, которую нужно прошить), и прошивается загрузчик (не забываем выбрать программатор Arduino as ISP). Подробная инструкция доступна опять же на странице официального сайта Arduino.

Arduino Gemma

Если подходить формально, то Gemma это не программатор. Это микроскопическая плата от AdaFruit предназначенная для вшивания/встраивания в одежду/обувь. Она лишь частично совместима с Arduino, так как содержит очень мало вводов/выводов. Чтобы подключить ее к USB разработчику пришлось выдумать отдельный загрузчик, и отдельный PID для USB устройства. По этой причине прошивается Gemma как отдельный программатор (в реальности там встроенный USBtiny), имеет отдельный конфиг для AVRDUDE с жестко прописанным bootloader. Другими словами, прошить этой платой ничего нельзя, но зато ее можно прошить саму загрузчиком.

BusPirate as ISP

BusPirate это не только программатор, скорее это не совсем и вовсе не программатор, а одноплатный компьютер специализированный для изучения и программирования новых и неизвестных микропроцессоров. Его конструкция такова, что на одной плате собраны все мыслимые и не очень интерфейсы для исследования того, что же попало к вам в руки. Штука интересная и если вы уж работаете с таким, то должны знать, что с AVRDUDE у компьютера могут быть определенные проблемы, связанные с прошивкой самого BusPirate. Обходятся они, естественно, настройками AVRDUDE и некоторым шаманством с железом.

Atmel STK500 development board

Та самая отладочная плата, что упоминается в AVR ISP и AVR ISP mkII. В Arduino IDE не делается различия между версиями и предполагается, что AVRDUDE самостоятельно определит версию протокола обмена и осуществит самонастройку. Если же этого не происходит, то в programmers.txt нужно четко прописать stk500v1 или stk500v2 в качестве применяемого протокола.

Atmel JTAGICE3 (ISP mode) и Atmel JTAGICE3 (JTAG mode)

JTAGICE3 — современное решение для отладки чипов семейств AVR, SAM и Cortex. Разумеется, только тех чипов, что поддерживают внутричиповую отладку. Попутно эта коробочка еще и программирует их всех.

atmel, jtag, jtagice, jtagice3

Atmel JTAGICE3 отладчик/программатор.

Продукт актуальный, у производителя имеется документация. Разница между программаторами только в применяемых протоколах. В ISP режиме применяется протокол JTAG3ISP, а в JTAG просто JTAG3.

Atmel-ICE (AVR)

Так же активный продукт Atmel и его можно купить. Как и JTAGICE3 он позволяет не только производить отладку у чипов, поддерживающих такую функцию, так и программировать их. Для прошивки используется протокол atmelice_isp. В общем использовать программаторы на подобие JTAGICE3 или Atmel-ICE только для прошивки 8-битных микроконтроллеров это как стрелять из пушки по клопам. Слишком уж мощные и дорогие решения для задачи, которая решается куда проще.

Обширное семейство ESP

Выше мы рассмотрели специфику прошивки контроллеров семейства AVR. Но при этом обойти не менее многочисленное и популярное семейство контроллеров ESP было бы просто некрасиво. Тем более, что при выборе одного из семейства, меню Tools значительно увеличивается в объеме. Пройдемся по меню и попробуем понять, что каждый из пунктов увеличенного меню означает. Здесь и далее я рассматриваю SDK ESP версии 2.5.0.

arduino ide, esp, tools

Меню Tools в Arduino IDE при выборе одной из плат семейства ESP.

Часть меню все же остается тем же самым, что и прежде, поэтому излишне повторяться не будем.

Upload speed

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

Поддерживаемые скорости прописываются для каждой из плат индивидуально.

CPU Frequency

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

Flash Size

Здесь указывается каким образом разделять всю доступную ПЗУ для хранения кода программы и для файлов. Микроконтроллеры ESP поддерживают память SPIFFS (Serial Peripheral Interface Flash File System). По сути, SPIFFS это файловая система для последовательного доступа. И у программиста есть возможность определить, сколько памяти отводить для файловой системы (туда можно записать, например, HTML-файлы или картинки) и сколько для своего скетча. Но тут есть некоторая тонкость. На текущий момент, насколько мне известно, как минимум платы EPS8266 не могут закачать скетч размерностью более 1 мегабайта. Есть обходные пути, но ведь еще нужно умудриться написать скетч, который в компилированном виде будет занимать более 1 мегабайта. Поэтому рекомендуется использовать как можно больший SPIFF, дабы уменьшить время загрузки скетча.

В тоже самое время есть сведения от потерпевших, что платы ESP32 могут испытывать проблемы связанные с «не хватает места для скетча». Но проблемы эти всего лишь из-за еще сырой поддержки плат EPS32 в инфраструктуре ESP для Arduino.

Debug port

Пункт может принимать значения Disabled, Serial и Serial1. Данная настройка предназначена для вывода отладочной информации в последовательный порт (хотя включить ее можно и программно, например, через Serial.setDebugOutput(true)). Если в скетче инициализируется соответствующий порт (Serial или Serial1), то в него могут выводиться отладочные сообщения, которые не мешают выводу в этот же порт другой информации.

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

У ESP обычно присутствует два последовательных порта. Первый, Serial использует UART0 и GPIO1 (TX) с GPIO3(RX). Второй, Serial1 использует UART1 и только GPIO2 (TX). Соответственно Serial1 не может быть использован на прием. Тем не менее, в обоих случаях есть возможность программного переназначения пинов, как и скорости, четности и прочих характеристик.

Debug Level

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

lwIP Variant

Настройка предназначена для выбора варианта реализации сетевого стека IP. Прошу обратить внимание, тут именно lwIP (lightweight IP), первая буква L, а не i.

iWIP

Вариант выбора IwIP

По умолчанию используется самый верхний вариант, уменьшающий использование памяти. Но если ваш микроконтроллер активно работает с сетью, то можно пожертвовать памятью и получить наивысшую скорость. Аналогично можно включить поддержку IPv6 или вернуться на стек версии 1.4, где такой поддержки не было вообще. Под features тут понимается всякого рода ICMP, IGMP и прочие навороты, без которых можно обойтись. Основная документация по версии ветки 2.х доступна на сайте разработчика. Постоянно растущий Wiki по теме lwIP доступен на страницах проекта FanDom.

VTables

Под VTables в IDE подразумевается механизм виртуальной таблицы для позднего связывания объектов. Не буду вдаваться в подробности, о них можно задумчиво почитать в Википедии. Остановлюсь лишь на самих доступных опциях, а их всего три:

  • Flash – постоянное запоминающее устройство, таблицы хранятся в файловой системе. Метод по умолчанию в репозитарии GitHub.
  • Heap – куча, оперативная память предназначенная для динамического выделения памяти.
  • IRAM – внутренняя память микроконтроллера.

Понятно, что самый быстрый способ хранения и обработки виртуальных таблиц это IRAM, а самый медленный Flash. Но тут следует так же смотреть на то, как активно работает программа с объектами, есть ли множественное наследование и как часто объекты создаются и уничтожаются. В обычных применениях такая таблица и вовсе может быть статической и отлично проживать на Flash, с другой стороны, она может быть весьма крупной и просто не влезать в IRAM (область ОЗУ для хранения кода программы).

Exceptions

Пункт меню позволяет включить или отключить использование исключительных ситуаций. О них мы уже рассуждали выше, в том числе и в разделе об ESP Exception Decoder. При включении исключений программист в коде уже может использовать структуры try {} catch {}, что увеличивает потребление памяти, но позволяет легче программировать сложные алгоритмы. Напомню, что try-catch будет работать только для плат семейства ESP. Отрадно замечать, что программисты работающие над библиотеками для семейства ESP для Arduino уже начали использовать механизм try {} catch {} в своем коде на GitHub.

Erase Flash

Пункт предлагает стирать внутреннюю память микроконтроллера в следующих пропорциях:

  • Only Sketch – стирает только пространство отведенное под скетч. Остальное остается нетронутым.
  • Sketch + WiFi Settings – пространство для скетча и настройки WiFi. Дело в том, что при подключении к точке доступа микроконтроллер запоминает параметры подключения и в следующий раз подключается к той же точке быстрее.
  • All Flash Contents – стирается все, включая файловую систему.

Прочее по ESP

В заключение статьи хотелось бы добавить, что при прошивке загрузчика в ESP всегда используется прошивальщик esptool. И всегда применяется один и тот же загрузчик eboot. Чтобы пользователь там не выставил в Programmer.

Итог

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

Однако, хочу надеться, что авторы Arduino IDE все же смогут удержать свое творение в приличных рамках и оставить его все таким же легким в освоении инструментом. Заодно хочу им напомнить, что документировать свое творение стоит постоянно иначе получается «не только лишь все, сегодня могут в завтра».

Update: разбираясь глубже с тем как настраивать свои собственные платы или же добавлять новые платы к Arduino IDE, наткнулся на исчерпывающую документацию по этому поводу.



Понравилась статья? Поделить с друзьями:

Читайте также:

  • Как изменить скачку файла на другой диск
  • Как изменить системный язык на компьютере
  • Как изменить скачивание файлов на другой диск
  • Как изменить системный язык клавиатуры
  • Как изменить скачанный скин майнкрафт

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии