Arduino для начинающих. Часть 1
Предисловие
Доброго времени суток, Хабр. Запускаю цикл статей, которые помогут Вам в знакомстве с Arduino. Но это не значит, что, если Вы не новичок в этом деле – Вы не найдёте ничего для себя интересного.
Введение
Было бы не плохо начать со знакомства с Arduino. Arduino – аппаратно-программные средства для построения систем автоматики и робототехники. Главным достоинством есть то, что платформа ориентирована на непрофессиональных пользователей. То есть любой может создать своего робота вне зависимости от знаний программирования и собственных навыков.
Начало
Создание проекта на Arduino состоит из 3 главных этапов: написание кода, прототипирование (макетирование) и прошивка. Для того, чтоб написать код а потом прошить плату нам необходима среда разработки. На самом деле их есть немало, но мы будем программировать в оригинальной среде – Arduino IDE. Сам код будем писать на С++, адаптированным под Arduino. Скачать можно на официальном сайте. Скетч (набросок) – программа, написанная на Arduino. Давайте посмотрим на структуру кода:
Важно заметить, что обязательную в С++ функцию main() процессор Arduino создаёт сам. И результатом того, что видит программист есть:
Давайте разберёмся с двумя обязательными функциями. Функция setup() вызывается только один раз при старте микроконтроллера. Именно она выставляет все базовые настройки. Функция loop() — циклическая. Она вызывается в бесконечном цикле на протяжении всего времени работы микроконтроллера.
Первая программа
Для того, чтоб лучше понять принцип работы платформы, давайте напишем первую программу. Эту простейшую программу (Blink) мы выполним в двух вариантах. Разница между ними только в сборке.
Принцип работы этой программы достаточно простой: светодиод загорается на 1 секунду и тухнет на 1 секунду. Для первого варианта нам не понадобиться собирать макет. Так как в платформе Arduino к 13 пину подключён встроенный светодиод.
Прошивка Arduino
Для того, чтоб залить скетч на Arduino нам необходимо сначала просто сохранить его. Далее, во избежание проблем при загрузке, необходимо проверить настройки программатора. Для этого на верхней панели выбираем вкладку «Инструменты». В разделе «Плата», выберете Вашу плату. Это может быть Arduino Uno, Arduino Nano, Arduino Mega, Arduino Leonardo или другие. Также в разделе «Порт» необходимо выбрать Ваш порт подключения (тот порт, к которому вы подключили Вашу платформу). После этих действий, можете загружать скетч. Для этого нажмите на стрелочку или во вкладке «Скетч» выберете «Загрузка» (также можно воспользоваться сочетанием клавиш “Ctrl + U”). Прошивка платы завершена успешно.
Прототипирование/макетирование
Для сборки макета нам необходимы следующие элементы: светодиод, резистор, проводки (перемычки), макетная плата(Breadboard). Для того, чтоб ничего не спалить, и для того, чтоб всё успешно работало, надо разобраться со светодиодом. У него есть две «лапки». Короткая – минус, длинная – плюс. На короткую мы будем подключать «землю» (GND) и резистор (для того, чтоб уменьшить силу тока, которая поступает на светодиод, чтоб не спалить его), а на длинную мы будем подавать питание (подключим к 13 пину). После подключения, загрузите на плату скетч, если вы ранее этого не сделали. Код остаётся тот же самый.
На этом у нас конец первой части. Спасибо за внимание.
Как программируют Arduino
Многие думают, что на языке Wiring, но на самом деле…
Arduino — это программируемый микроконтроллер, который можно использовать в робототехнике, умном доме и вообще запрограммировать его как угодно: чтобы он кормил кота, поливал растения, предупреждал вас о приближении врагов или открывал двери с помощью магнитного ключа. У нас есть подборка 10 интересных вещей, которые можно сделать на этой платформе. Теперь время разобраться, как программисты с ней работают.
Язык Arduino
Если опытный программист посмотрит на код для Arduino, он скажет, что это код на C++. Это недалеко от истины: основная логика Ардуино реализована на C++, а сверху на неё надет фреймворк Wiring, который отвечает за общение с железом.
На это есть несколько причин:
- У С++ слава «слишком сложного языка». Arduino позиционируется как микроконтроллеры и робототехника для начинающих, а начинающим иногда трудно объяснить, что С++ не такой уж сложный для старта. Проще сделать фреймворк и назвать его отдельным языком.
- В чистом С++ нет удобных команд для AVR-контроллеров, поэтому нужен был инструмент, который возьмёт на себя все сложные функции, а на выходе даст программисту часто используемые команды.
- Разработчики дали программистам просто писать нужные им программы, а все служебные команды, необходимые для правильного оформления кода на С++, взяла на себя специальная среда разработки.
Подготовка и бесконечность
В любой программе для Arduino есть две принципиальные части: подготовительная часть и основной цикл.
В подготовительной части вы говорите железу, чего от вас ожидать: какие порты настроить на вход, какие на выход, что у вас как называется. Например, если у вас датчик подключён ко входу 10, а лампочка к выходу 3, то вы можете обозвать эти входы и выходы как вам удобно, а дальше в коде обращаться не к десятому входу и третьему выходу, а по-человечески: к датчику или лампочке. Вся часть с подготовкой выполняется один раз при старте контроллера. Контроллер всё запоминает и переходит в основной цикл.
Основной цикл — это то, что происходит в функции loop(). Ардуино берёт оттуда команды и выполняет их подряд. Как только команды закончились, он возвращается в начало цикла и повторяет всё. И так до бесконечности.
В основном цикле мы описываем все полезные вещи, которые должен делать контроллер: считывать данные, мигать лампами, включать-выключать моторы, кормить кота и т. д.
Что можно и чего нельзя
Ардуино работает на одноядерном и не шибко шустром процессоре. Его тактовая частота — 16 мегагерц, то есть 16 миллионов процессорных операций в секунду. Это не очень быстро, плюс ядро только одно, и оно исполняет одну команду за другой.
Вот какие ограничения это на нас накладывает.
Нет настоящей многозадачности. Можно симулировать многозадачность с помощью приёма Protothreading, но это скорее костыль. Нельзя, например, сказать: «Когда нажмётся такая-то кнопка — сделай так». Вместо этого придётся в основном цикле писать проверку: «А эта кнопка нажата? Если да, то. »
Нет понятия файлов (без дополнительных примочек, библиотек и железа). На контроллер нельзя ничего сохранить, кроме управляющей им программы. К счастью, есть платы расширения, которые позволяют немножко работать с файлами на SD-карточках.
Аналогично с сетью: без дополнительных плат и библиотек Ардуино не может ни с чем общаться (кроме как включать-выключать электричество на своих выходах).
Полегче со сложной математикой: если вам нужно что-то сложное типа тригонометрических функций, будьте готовы к тому, что Ардуино будет считать их довольно медленно. Для вас это одна строчка кода, а для Ардуино это тысячи операций под капотом. Пощадите.
Отчёты? Ошибки? Только при компиляции. У Ардуино нет встроенных средств сообщить вам, что ему нехорошо. Если он завис, он не покажет окно ошибки: во-первых, у него нет графического интерфейса, во-вторых — экрана. Если хотите систему ошибок или отчётность, пишите её 🙂
Если серьёзно, то перед заливом программы на контроллер компилятор проверит код и найдёт в нём опечатки или проблемы с типами данных. Но на этом всё: если у вас случайно получилась бесконечная петля в коде или при каких-то обстоятельствах вы повесите процессор делением на ноль — жмите перезагрузку и исправляйте код.
И всё же
Ардуино — это кайф: вы с помощью кода можете управлять физическим миром, моторами, лампами и электродеталями. Можно создать умную розетку; можно собрать умный замок для сейфа; можно сделать детектор влажности почвы, который будет включать автоматический полив. И всё это — на довольно понятном, читаемом и компактном языке C++, на который сверху ещё надета удобная библиотека для железа. Прекрасный способ провести выходные.
Какие ещё языки используют для Arduino
Но чу! Под Arduino можно писать и на других языках!
С. Как и С++, Си легко можно использовать для программирования микроконтроллеров Arduino. Только если С++ не требует никаких дополнительных программ, то для С вам понадобится WinAVR, чтобы правильно перевести код в язык, понятный контроллерам AVR.
Python. Было бы странно, если бы такому универсальному языку не нашлось применения в робототехнике. Берёте библиотеки PySerial и vPython, прикручиваете их к Python и готово!
Java. Принцип такой же, как в Python: берёте библиотеки для работы с портами и контроллерами и можно начинать программировать.
А вообще Arduino работает на контроллерах AVR, и прошить их можно любым кодом, который скомпилирован под это железо. Всё, что вам нужно — найти библиотеку для вашего любимого языка, которая преобразует нужные команды в машинный код для AVR.
Почему многие не любят Arduino
Не задумывались ли вы, почему специалисты/профессионалы в области микроконтроллеров и автоматизации относятся к тем, кто работает с Arduino примерно так, как будто они занимаются чем-то не серьёзным, вроде игры в песочнице?
Примерно так же к ардуино относится и мой кот Вася.
Собственно для этого я и сделал видео, где наглядно, при помощи осциллографа, покажу и расскажу, с моей точки зрения, почему так. Постараюсь высветлить явные плюсы и минусы темы Arduino:
Для начала следует сказать, что Arduino это не так уж плохо как может показаться. Именно благодаря ардуино появилось на свет множество самых разных проектов, которые бы так и не воплотились в жизнь, из-за очень большого количества информации, которую нужно «переварить» чтобы их реализовать. Ни для кого не секрет, что на ардуино делать какие-то устройства значительно проще, да и к тому же быстрее. Именно из-за этого я и начал увлекаться темой микроконтроллеров. И постепенно я начал перерастать всякие digitalWrite(13, HIGH); и переходить на PORTB = 32;, так как желание повышения производительности моих девайсов возрастало.
Вот так выглядит код обычной «мигалки» на привычном для «ардуинщика» языке:
Я думаю многим знаком этот пример, потому что это классическое упражнение «здравствуй мир», которое призвано максимально снизить порог вхождения в тему программирования микроконтроллеров Arduino.
Давайте посмотрим как бы это выглядело если мы пошли путём не наименьшего сопротивления используя регистры микроконтроллера:
Данные примеры, как видите, потребляют 1030 и 176 байт в Flash, то есть проигрыш в этом плане у ардуиншиков почти в 6 раз. Я специально во втором примере добавил комментарии что какая строчка делает, чтобы упростить понимание происходящего. Да, можно было полностью расписать что да как работает, но моя статья не об этом, так что задаю вам вектор для развития, ардуинщики.
Сейчас речь пойдёт о использовании ресурсов микроконтроллера, которые не безграничны, и если их бездумно расходовать то они приведут, в лучшем случае, к непонятным ругательствам среды разработки, а в худшем — дней разбирательств почему оно корректно не работает, сотни итераций кода в уме, строчка за строчкой, а причиной этого может оказаться мистика срыв стека микроконтроллера.
Но давайте вернёмся к нашим баранам среде разработки Arduino IDE.
Обратите внимание на использование памяти в двух примерах, чтобы вам не метаться по страничке вверх вниз, вот два кода на одном скрине:
Первое что бросается в глаза — размер кода, если писать на обычном языке Arduino IDE то он выглядит немного компактнее. А если бы я взял какой-то более сложный код, например ReadAnalogVoltage который считывает напряжение на нулевом аналоговом порте пине, преобразует его в вольты и выводит в сериал, если всё это прописать используя регистры микроконтроллера, то получится в несколько раз больше кода. Но в данном случае больше не всегда значит хуже, я бы даже сказал наоборот. Почему так? Об этом я расскажу ниже.
Так же обратите внимание на то, сколько памяти потребляют оба примера, код на языке ардуино «съедает» значительно больше памяти и давайте сейчас разберёмся почему так.
В папке среды разработки по пути \hardware\arduino\avr\cores\arduino лежит ядро Arduino, там есть файл wiring_digital.c, где собственно и прописана наша «прожорливая» функция digitalWrite, мы встретим там следующие строчки:
Вы только посмотрите, сколько работы она делает вместо того чтобы просто задать состояние порта(как например вот так PORTB = 32;). А сделано это неспроста, так как у ардуино низкий порог вхождения, как я высказался выше, тут присутствуют разные проверки аля «защита от дурака». Например, если новичок по глупости забыл задать порт пин как выход, чтобы тот не перешёл в состояние Hi-Z(о котором ещё новичок не подозревает, скорее всего) и таким образом отпугнул его при первой же ошибке. Но за это приходиться платить повышенным потреблением ресурсов, как вы сами видите.
А теперь давайте перейдём к осциллографу, как я и обещал в начале статьи.
У меня есть две идентичные китайские Arduino Pro Mini которые размещены на одной и той же макетной плате, то есть у них будут одинаковые условия. Давайте прошьём одну из них «мигалку» только без задержек и посмотрим что будет на экране осциллографа:
Один пример написан на языке ардуино, а второй работает непосредственно с регистрами:
Синий луч осциллографа(КАН2) — это обычный ардуиновский код, как можно видеть, частота переключений из логической единицы в логический ноль у жёлтого луча(КАН1) больше:
2.67 против 0.094 МГц, разумеется что емкость порта микроконтроллера не даёт получить чистый меандр как в случае кода ардуино, но если присмотреться, то и там фронты далеко не чистые:
Получается проигрыш производительности в данном случае — 28 раз. Разумеется что это не значит, что ардуино работает в 28 раз медленнее, но я считаю, что для наглядности, это лучший пример того, за что не любят ардуино.
Ещё, я не люблю тему ардуино, за все эти красивые разноцветные модули, которые по большей части можно изготовить самостоятельно, а продают их втридорога, будто там золотые проводники вместо медных.
Вот пример того, как можно самостоятельно, за копейки, создать полезный модуль. Но порой меня лень преодолевает и тоже покупаю, потому что не всегда есть время или желание на это.
Должен признаться я и сам «ардуиншик», и работаю по большей с Arduino платами, например копия Pro Mini у китайцев стоит не так уж дорого, разумеется что дешевле «голого» микроконтроллера, но как я уже сказал выше, не всегда находиться время и желание заниматься разводкой платы с нуля, лично мне проще интегрировать в проект Arduino плату, особенно недорогие Arduino Pro Mini или немного более продвинутую Arduino Nano.
Так же, я люблю работать из средой разработки Arduino IDE, не взирая на её ограничения и неудобства, она может запуститься сразу, без каких либо настроек, просто скачал ZIP архив, распаковал куда нужно и всё, можно приступать к работе, да и к тому же занимает не особо много места если сравнивать с более профессиональным софтом, например Atmel Studio. И ещё, тут есть одна полезная фишка — автоформатирование(комбинация клавиш Ctrl+T):
Разумеется есть такое понятие как «правило хорошего тона», и себя нужно приучивать к этому с самого начала, но если есть такая фитча то почему бы её не пользоваться?
Ещё из удобств в Arduino IDE появилась возможность в настройках включать нумерацию строк и сворачивание кода:
Последний пункт заметно улучшает навигацию кода и уже немного, но приближает, к более профессиональным решениям.
К тому же Arduino IDE, как вы заметили, умеет «переваривать» не только свой язык но и Си и даже ассемблер.