Программирование Ардуино – это задание определённых алгоритмов, переведённых на компьютерный язык, с целью выполнения машиной конкретной задачи, поставленной пользователем.
Мы предлагаем вам самый полный и дополняемый справочник программиста Arduino. Справочник постоянно дополняется и обновляется.
Операторы |
ФункцииЦифровой ввод/вывод
Аналоговый ввод/вывод
Только для Due
Расширенный ввод/вывод
Время
Математические вычисления
Тригонометрия
Случайные числа
Биты и байты
Внешние прерывания
Прерывания
|
Ардуино – платформа, позволяющая множеству инженеров со всего мира создавать свои проекты с минимальными вложениями. В первую очередь – это специальный микроконтроллер с одноимённой системой управления и библиотеками, построенными на языке С++. Соответственно, если вы планируете создавать что-то уникальное, вам следует изучить все нюансы, которые имеет программирование Arduino.
Давайте же составим краткое описание программирования Arduino и уточним моменты, на которые стоит обратить внимание, если вы впервые занимаетесь подобным.
Основы Arduino
Прежде чем приступать к решению конкретной задачи на Ардуино, лучше всего иметь базис в сфере программирования. Поэтому давайте рассмотрим, что вообще обозначает этот термин. Абсолютно любой проект построен на поэтапной блок-модели, в которой описывается, что необходимо сделать вашему микроконтроллеру и как это сделать.
Для упрощения работы пользователей в Ардуино созданы готовые библиотеки функций, вам достаточно лишь вводить команды из них, чтобы добиться какой-то цели. Естественно, таким образом вы многого не добьётесь, но для создания собственных библиотек потребуется знание языка С++ на котором и построена прошивка чипа.
Ключевая особенность системы в том, что характеристики Arduino могут быть улучшены с помощью докупаемых компонентов, и вы всегда можете их подстроить под конкретный проект. Соответственно, единственным вашим ограничением является знание языка и его возможностей, а также собственная фантазия.
Все функции строятся из простейших операнд, которые характерны для С++. Этими операндами являются переменные различных типов и способы их применения. Поэтому любая функция, используемая в микроконтроллере для получения сведений или отправки сигнала, – это набор простейших операций, который записан в главной библиотеке. И вы будете ограничены до тех пор, пока не получите достаточно опыта и практики, чтобы понимать, какую библиотеку и для какой цели вам стоит написать.
Главный же недостаток конструирования с Arduino сложных проектов в том, что вам придётся с нуля писать код и подбирать компоненты для системы, поэтому лучше сначала попрактиковаться на простейших задачах.
Также, учитывайте, что язык написания библиотек системы – низкоуровневый, а соответственно, состоит из простейших команд, в отличие от высокоуровневых python или pascal, удобных для пользователей. С другой стороны, он также является мультипарадигмальным, поэтому подходит для решения любой задачи с помощью удобной вам парадигмы программирования.
Чаще всего применяется ООП. Сам С++ имеет ядро из многочисленных библиотек и дополнительных функций или методов, поэтому, если вы собираетесь разобраться во всём кардинально, стоит начинать с освоения языка с нуля.
Особенности Arduino программирования
Именно язык, на котором базируется система, и является главной особенностью Ардуино программирования. Ведь при том, что сама плата и работа с ней достаточно просты, с низким порогом вхождения, чтобы освоить низкоуровневый язык программирования и в совершенстве владеть им, потребуется несколько лет.
У программирования на Ардуино имеются как свои достоинства, так и недостатки, и вам стоит изучить обе стороны вопроса, чтобы понимать, с чем вы имеете дело и чего ожидать от микроконтроллера в принципе, во время работы с ним. Среди достоинств Ардуино, пользователи отмечают:
- Низкий порог вхождения. Этот пункт будет и в недостатках, так как из-за простоты системы и отсутствия требований к базису по программированию в сети гуляет множество библиотек, написанных ужасным образом. На то, чтобы разобраться, как они работают, уйдёт больше времени, чем на создание своей собственной. А стандартных функций от разработчиков не хватает для серьёзных задач.
- Обширное комьюнити. Это главное достоинство Ардуино перед его конкурентами, ведь вы найдёте пользователей, занимающихся созданием проектов на нём, как русскоязычных, так и англоязычных. Но если вы хотите получать действительно ценные советы и погрузиться в работу комьюнити, следует всё же изучить английский язык. Так как большая часть проблем, что вам встретятся, уже давно решены в Гугле, но, зачастую, ответы на английском.
- Большое количество библиотек, под разные случаи. Но, как уже описано чуть выше, у этого есть и свои недостатки.
Имеется у программирования на Ардуино и ряд весомых минусов:
- Низкая планка для вхождения превращает большую часть библиотек, коими наполнена сеть, в полностью бесполезный мусор. Ведь какие-то из них работают просто медленно и написаны без каких-либо знаний основ алгоритмизации, а часть – вовсе не работает, и непонятно, зачем авторы их создавали. Чтобы найти подспорье под конкретный проект, необходимо перелопатить несколько англоязычных форумов или же самостоятельно создать функции с нуля.
- Сложности программирования на С++. На деле – это один из сложнейших языков мультипарадигмального программирования, для создания прошивок и низкоуровневых задач. Однако, если вы имели опыт работы с ним и знаете хотя бы основные алгоритмы, а также работали хоть с одним другим мультипарадигмальным ЯП, тем более используя объектно-ориентированное программирование, вам будет значительно проще освоиться.
- Низкая скорость отклика самих чипов и их слабые характеристики. Да, микроконтроллеры Ардуино можно подстраивать под конкретную задачу, докупать компоненты и датчики, но это играет с ними злую шутку. Так как разработчики не знают, для чего будут использовать их детище, они усредняют все показатели, чтобы значительно уменьшить стоимость конечного продукта. В результате люди, создающие простейшие поделки, переплачивают за ненужную мощность, а тем, кто занимается робототехникой или автоматизацией каких-то процессов, приходится докупать и паять множество дополнительных плат.
Как вы можете заметить, Ардуино имеет множество нюансов, и не столь дружелюбна для новичков, как выглядит на первый взгляд. С другой стороны, если вы имеете малейший опыт работы с языками программирования, вам будет куда проще освоиться.
Как начать правильно пользоваться Arduino
Если вы никогда ранее не программировали, и это ваш первый опыт, то программирование микроконтроллеров Arduino пойдёт куда проще, если вы начнёте с основ. Конечно, когда в планах у вас нет никаких сложных проектов, можете работать на готовых библиотеках и параллельно разбирать, из чего состоят их функции. Это один из хороших способов обучения, но тогда стоит искать наборы функций, которые писались профессионалами, чтобы быть уверенным в их правильности. Иначе вы можете увидеть неправильное решение задачи и, в результате, применять те в своих проектах.
Но куда лучше начать с основ и посвятить хотя бы неделю освоению алгоритмизации и научиться разбивать свои проекты на блоки, а те – уже на конкретные шаги. Подобное построение блок-схем вам не раз пригодится в будущем. Когда вы изучите весь базис, можно переходить к практике и самообучению на С++, подойдут любые простейшие проекты или заготовленные в интернете задачи. На этом этапе вашей целью станет понять основные парадигмы и научиться их использовать, а также изучить возможности языка, чтобы вы чётко знали, что он может, и могли здраво оценить реализуемость ваших проектов.
Программирование микроконтроллеров
Само программирование Ардуино делится на три этапа:
- Создание или скачивание готовой библиотеки функций.
- Загрузка этих библиотек в постоянную память чипа. Это ещё называют прошивкой.
- Ввод этих функций в командную строку, например, АТ, чтобы плата выполнила те или иные действия.
Если вы делаете что-то простое, и вам хватает базовой прошивки, можете пропустить первые два пункта.
Самые простые проекты с использованием Arduino
Примеров простых проектов с Ардуино множество, например, вы можете:
- Создать датчик освещённости, который будет подстраивать специальные LED лампы под ту яркость, которая необходима в комнате.
- Автоматизация любых вещей в вашем доме. Например, включения-выключения света, открытия дверей и прочее.
- Автоматизация оранжереи.
Хотя это и звучит достаточно страшно, на большую часть этих проектов, благодаря обилию информации по ним в интернете, вы не потратите много времени и сил.
Этот урок дает минимальные знания, необходимые для программирования систем Ардуино на языке C. Можно только просмотреть его и в дальнейшем использовать как справочную информацию. Тем, кто программировал на C в других системах можно пропустить статью.
Предыдущий урок Список уроков Следующий урок
Повторю, что это минимальная информация. Описание указателей, классов, строковых переменных и т.п. будет дано в последующих уроках. Если что-то окажется непонятным, не беспокойтесь. В дальнейших уроках будет много примеров и пояснений.
Структура программы Ардуино достаточно проста и в минимальном варианте состоит из двух частей setup() и loop().
void setup() {
// код выполняется один раз при запуске программы
}
void loop() {
// основной код, выполняется в цикле
}
Функция setup() выполняется один раз, при включении питания или сбросе контроллера. Обычно в ней происходят начальные установки переменных, регистров. Функция должна присутствовать в программе, даже если в ней ничего нет.
После завершения setup() управление переходит к функции loop(). Она в бесконечном цикле выполняет команды, записанные в ее теле (между фигурными скобками). Собственно эти команды и совершают все алгоритмические действия контроллера.
; точка с запятой Выражения могут содержать сколь угодно много пробелов, переносов строк. Признаком завершения выражения является символ ”точка с запятой ”.
z = x + y; z= x + y ;
{ } фигурные скобки определяют блок функции или выражений. Например, в функциях setup() и loop().
/* … */ блок комментария, обязательно закрыть.
/* это блок комментария */
// однострочный комментарий, закрывать не надо, действует до конца строки.
// это одна строка комментария
Переменная это ячейка оперативной памяти, в которой хранится информация. Программа использует переменные для хранения промежуточных данных вычислений. Для вычислений могут быть использованы данные разных форматов, разной разрядности, поэтому у переменных в языке C есть следующие типы.
Тип данных | Разрядность, бит | Диапазон чисел |
boolean | 8 | true, false |
char | 8 | -128 … 127 |
unsigned char | 8 | 0 … 255 |
byte | 8 | 0 … 255 |
int | 16 | -32768 … 32767 |
unsigned int | 16 | 0 … 65535 |
word | 16 | 0 … 65535 |
long | 32 | -2147483648 … 2147483647 |
unsigned long | 32 | 0 … 4294967295 |
short | 16 | -32768 … 32767 |
float | 32 | -3.4028235+38 … 3.4028235+38 |
double | 32 | -3.4028235+38 … 3.4028235+38 |
Типы данных выбираются исходя из требуемой точности вычислений, форматов данных и т.п. Не стоит, например, для счетчика, считающего до 100, выбирать тип long. Работать будет, но операция займет больше памяти данных и программ, потребует больше времени.
Объявление переменных.
Указывается тип данных, а затем имя переменной.
int x; // объявление переменной с именем x типа int float widthBox; // объявление переменной с именем widthBox типа float
Все переменные должны быть объявлены до того как будут использоваться.
Переменная может быть объявлена в любой части программы, но от этого зависит, какие блоки программы могут ее использовать. Т.е. у переменных есть области видимости.
- Переменные, объявленные в начале программы, до функции void setup(), считаются глобальными и доступны в любом месте программы.
- Локальные переменные объявляются внутри функций или таких блоков, как цикл for, и могут использоваться только в объявленных блоках. Возможны несколько переменных с одним именем, но разными областями видимости.
int mode; // переменная доступна всем функциям
}
void loop() {
long count; // переменная count доступна только в функции loop()
for ( int i=0; i < 10;) // переменная i доступна только внутри цикла { i++; } }
При объявлении переменной можно задать ее начальное значение (проинициализировать).
int x = 0; // объявляется переменная x с начальным значением 0 char d = ‘a’; // объявляется переменная d с начальным значением равным коду символа ”a”
При арифметических операциях с разными типами данных происходит автоматическое преобразование типов данных. Но лучше всегда использовать явное преобразование.
int x; // переменная int char y; // переменная char int z; // переменная int
z = x + (int) y; // переменная y явно преобразована в int
= | присваиваниее |
+ | сложение |
— | вычитание |
* | произведение |
/ | деление |
% | остаток от деления |
== | равно |
!= | не равно |
< | меньше |
> | больше |
<= | меньше или равно |
>= | больше или равно |
&& | логическое И |
|| | логическое ИЛИ |
! | логическое НЕ |
* | косвенная адресация |
& | получение адреса переменной |
& | И |
| | ИЛИ |
^ | ИСКЛЮЧАЮЩЕЕ ИЛИ |
~ | ИНВЕРСИЯ |
<< | СДВИГ ВЛЕВО |
>> | СДВИГ ВПРАВО |
++ | + 1 к переменной |
— | — 1 к переменной |
+= | сложение |
-= | вычитание |
*= | умножение |
/= | деление |
%= | остаток от деления |
&= | битовое И |
|= | битовое ИЛИ |
Оператор IF проверяет условие в скобках и выполняет последующее выражение или блок в фигурных скобках, если условие истинно.
if (x == 5) // если x=5, то выполняется z=0 z=0;
if (x > 5) // если x > 5, то выполняется блок z=0, y=8; { z=0; y=8; }
IF … ELSE позволяет сделать выбор между двух вариантов.
if (x > 5) // если x > 5, то выполняется блок z=0, y=8; { z=0; y=8; } else // в противном случае выполняется этот блок { z=0; y=0; }
ELSE IF – позволяет сделать множественный выбор
if (x > 5) // если x > 5, то выполняется блок z=0, y=8; { z=0; y=8; }
else if (x > 20) // если x > 20, выполняется этот блок { }
else // в противном случае выполняется этот блок { z=0; y=0; }
SWITCH CASE — множественный выбор. Позволяет сравнить переменную (в примере это x) с несколькими константами (в примере 5 и 10) и выполнить блок, в котором переменная равна константе.
switch (x) {
case 5 : // код выполняется если x = 5 break;
case 10 : // код выполняется если x = 10 break;
default : // код выполняется если не совпало ни одно предыдущее значение break; }
Цикл FOR. Конструкция позволяет организовывать циклы с заданным количеством итераций. Синтаксис выглядит так:
for ( действие до начала цикла; условие продолжения цикла; действие в конце каждой итерации ) {
// код тела цикла
}
Пример цикла из 100 итераций.
for ( i=0; i < 100; i++ ) // начальное значение 0, конечное 99, шаг 1
{ sum = sum + I; }
Цикл WHILE. Оператор позволяет организовывать циклы с конструкцией:
while ( выражение ) { // код тела цикла }
Цикл выполняется до тех пор, пока выражение в скобках истинно. Пример цикла на 10 итераций.
x = 0; while ( x < 10 ) { // код тела цикла x++; }
DO WHILE – цикл с условием на выходе.
do { // код тела цикла } while ( выражение );
Цикл выполняется пока выражение истинно.BREAK – оператор выхода из цикла. Используется для того, чтобы прервать выполнение циклов for, while, do while.
x = 0; while ( x < 10 ) { if ( z > 20 ) break; // если z > 20, то выйти из цикла // код тела цикла x++; }
GOTO – оператор безусловного перехода.
goto metka1; // переход на metka1 ……………… metka1:
CONTINUE — пропуск операторов до конца тела цикла.
x = 0; while ( x < 10 ) { // код тела цикла if ( z > 20 ) continue; // если z > 20, то вернуться на начало тела цикла // код тела цикла x++; }
Массив это область памяти, где последовательно хранятся несколько переменных.
Объявляется массив так.
int ages[10]; // массив из 10 переменных типа int
float weight[100]; // массив из 100 переменных типа float
При объявлении массивы можно инициализировать:
int ages[10] = { 23, 54, 34, 24, 45, 56, 23, 23, 27, 28};
Обращаются к переменным массивов так:
x = ages[5]; // x присваивается значение из 5 элемента массива. ages[9] = 32; // 9 элементу массива задается значение 32
Нумерация элементов массивов всегда с нуля.
Функции позволяют выполнять одни и те же действия с разными данными. У функции есть:
- имя, по которому ее вызывают;
- аргументы – данные, которые функция использует для вычисления;
- тип данных, возвращаемый функцией.
Описывается пользовательская функция вне функций setup() и loop().
void setup() { // код выполняется один раз при запуске программы }
void loop() { // основной код, выполняется в цикле }
// объявление пользовательской функции с именем functionName type functionName( type argument1, type argument1, … , type argument) { // тело функции return(); }
Пример функции, вычисляющей сумму квадратов двух аргументов.
int sumQwadr (int x, int y) { return( x* x + y*y); }
Вызов функции происходит так:
d= 2; b= 3; z= sumQwadr(d, b); // в z будет сумма квадратов переменных d и b
Функции бывают встроенные, пользовательские, подключаемые.
Очень коротко, но этих данных должно хватить для того, чтобы начать писать программы на C для систем Ардуино.
Последнее, что я хочу рассказать в этом уроке, как принято оформлять программы на C. Думаю, если вы читаете этот урок в первый раз, стоит пропустить этот раздел и вернутся к нему позже, когда будет что оформлять.
Главная цель внешнего оформления программ это улучшить читаемость программ, уменьшить число формальных ошибок. Поэтому для достижения этой цели можно смело нарушать все рекомендации.
Имена в языке C.
Имена, представляющие типы данных, должны быть написаны в смешанном регистре. Первая буква имени должна быть заглавная (верхний регистр).
Signal, TimeCount
Переменные должны быть записаны именами в смешанном регистре, первая буква строчная (нижний регистр).
signal, timeCount
Константы должны быть записаны в верхнем регистре. В качестве разделителя нижнее подчеркивание.
MAX_TEMP, RED
Методы и функции должны быть названы глаголами, записанными в смешанном регистре, первая буква в нижнем регистре.
getTime, setTime
Об остальных формальностях в следующих уроках, по мере необходимости.
В следующем уроке напишем первую программу, научимся считывать данные с цифровых портов и управлять их состоянием.
Предыдущий урок Список уроков Следующий урок
Поддержать проект
Arduino — это программируемый микроконтроллер, который можно использовать в робототехнике, умном доме и вообще запрограммировать его как угодно: чтобы он кормил кота, поливал растения, предупреждал вас о приближении врагов или открывал двери с помощью магнитного ключа. У нас есть подборка 10 интересных вещей, которые можно сделать на этой платформе. Теперь время разобраться, как программисты с ней работают.
Язык Arduino
Если опытный программист посмотрит на код для Arduino, он скажет, что это код на C++. Это недалеко от истины: основная логика Ардуино реализована на C++, а сверху на неё надет фреймворк Wiring, который отвечает за общение с железом.
На это есть несколько причин:
- У С++ слава «слишком сложного языка». Arduino позиционируется как микроконтроллеры и робототехника для начинающих, а начинающим иногда трудно объяснить, что С++ не такой уж сложный для старта. Проще сделать фреймворк и назвать его отдельным языком.
- В чистом С++ нет удобных команд для AVR-контроллеров, поэтому нужен был инструмент, который возьмёт на себя все сложные функции, а на выходе даст программисту часто используемые команды.
- Разработчики дали программистам просто писать нужные им программы, а все служебные команды, необходимые для правильного оформления кода на С++, взяла на себя специальная среда разработки.
Среда разработки (IDE) Arduino.
Подготовка и бесконечность
В любой программе для Arduino есть две принципиальные части: подготовительная часть и основной цикл.
В подготовительной части вы говорите железу, чего от вас ожидать: какие порты настроить на вход, какие на выход, что у вас как называется. Например, если у вас датчик подключён ко входу 10, а лампочка к выходу 3, то вы можете обозвать эти входы и выходы как вам удобно, а дальше в коде обращаться не к десятому входу и третьему выходу, а по-человечески: к датчику или лампочке. Вся часть с подготовкой выполняется один раз при старте контроллера. Контроллер всё запоминает и переходит в основной цикл.
Основной цикл — это то, что происходит в функции loop(). Ардуино берёт оттуда команды и выполняет их подряд. Как только команды закончились, он возвращается в начало цикла и повторяет всё. И так до бесконечности.
В основном цикле мы описываем все полезные вещи, которые должен делать контроллер: считывать данные, мигать лампами, включать-выключать моторы, кормить кота и т. д.
Что можно и чего нельзя
Ардуино работает на одноядерном и не шибко шустром процессоре. Его тактовая частота — 16 мегагерц, то есть 16 миллионов процессорных операций в секунду. Это не очень быстро, плюс ядро только одно, и оно исполняет одну команду за другой.
Вот какие ограничения это на нас накладывает.
Нет настоящей многозадачности. Можно симулировать многозадачность с помощью приёма Protothreading, но это скорее костыль. Нельзя, например, сказать: «Когда нажмётся такая-то кнопка — сделай так». Вместо этого придётся в основном цикле писать проверку: «А эта кнопка нажата? Если да, то…»
Нет понятия файлов (без дополнительных примочек, библиотек и железа). На контроллер нельзя ничего сохранить, кроме управляющей им программы. К счастью, есть платы расширения, которые позволяют немножко работать с файлами на SD-карточках.
Аналогично с сетью: без дополнительных плат и библиотек Ардуино не может ни с чем общаться (кроме как включать-выключать электричество на своих выходах).
Полегче со сложной математикой: если вам нужно что-то сложное типа тригонометрических функций, будьте готовы к тому, что Ардуино будет считать их довольно медленно. Для вас это одна строчка кода, а для Ардуино это тысячи операций под капотом. Пощадите.
Отчёты? Ошибки? Только при компиляции. У Ардуино нет встроенных средств сообщить вам, что ему нехорошо. Если он завис, он не покажет окно ошибки: во-первых, у него нет графического интерфейса, во-вторых — экрана. Если хотите систему ошибок или отчётность, пишите её 🙂
Если серьёзно, то перед заливом программы на контроллер компилятор проверит код и найдёт в нём опечатки или проблемы с типами данных. Но на этом всё: если у вас случайно получилась бесконечная петля в коде или при каких-то обстоятельствах вы повесите процессор делением на ноль — жмите перезагрузку и исправляйте код.
И всё же
Ардуино — это кайф: вы с помощью кода можете управлять физическим миром, моторами, лампами и электродеталями. Можно создать умную розетку; можно собрать умный замок для сейфа; можно сделать детектор влажности почвы, который будет включать автоматический полив. И всё это — на довольно понятном, читаемом и компактном языке C++, на который сверху ещё надета удобная библиотека для железа. Прекрасный способ провести выходные.
Какие ещё языки используют для Arduino
Но чу! Под Arduino можно писать и на других языках!
С. Как и С++, Си легко можно использовать для программирования микроконтроллеров Arduino. Только если С++ не требует никаких дополнительных программ, то для С вам понадобится WinAVR, чтобы правильно перевести код в язык, понятный контроллерам AVR.
Python. Было бы странно, если бы такому универсальному языку не нашлось применения в робототехнике. Берёте библиотеки PySerial и vPython, прикручиваете их к Python и готово!
Java. Принцип такой же, как в Python: берёте библиотеки для работы с портами и контроллерами и можно начинать программировать.
HTML. Это, конечно, совсем экзотика, но есть проекты, которые заставляют HTML-код работать на Arduino.
А вообще Arduino работает на контроллерах AVR, и прошить их можно любым кодом, который скомпилирован под это железо. Всё, что вам нужно — найти библиотеку для вашего любимого языка, которая преобразует нужные команды в машинный код для AVR.
Главное — алгоритмы Любой робот — это один большой алгоритм. Чтобы научиться думать как программист и писать свои алгоритмы с нуля, приходите в Практикум. Используемые источники:
- https://arduinoplus.ru/coding-arduino/
- http://mypractic.ru/urok-4-osnovy-programmirovaniya-arduino-na-yazyke-c.html
- https://thecode.media/arduino-code/