Циклы for и while в arduino

random — генерация случайных чисел Ардуино

Функция random (min, max) позволяет вернуть псевдослучайное число в диапазоне, заданном значениями min и max. Разберем примеры с разными типами данных.

Arduino random int

В представленном примере выбран тип данных byte, хранящий целые числа в диапазоне от 0 до 250. Можно использовать и другие типы данных: int, long, unsigned long, unsigned int и другие. Соответственно задается нужный диапазон (min, max).

byte data;

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

void loop() {
   data = random(100, 200); // ардуино рандомное число в диапазоне
   Serial.println(data);
   delay(250);
}

Arduino random float

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

float data;
float data1;
float data2;

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

void loop() {
   data1 = random(0, 10);        // генерируем целые числа
   data1 = random(0, 100);      // генерируем числа после запятой
   data = data1 + data2 / 100; // складываем полученные значения
   Serial.println(data);
   delay(250);
}

Arduino random bool

Если нужна случайная переменная boolean, которая может принимать только два значения true или false. То можно генерировать случайное true/false с заданной вероятностью. Просто присваиваем переменной bool результат функции random, в которой указываем число, обратное вероятности получения false. Пример:

bool data;

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

void loop() {
   data = random(5); // переменная data получит значение 0 с вероятностью 1/5
   Serial.println(data);
   delay(250);
}

Аппаратная часть Arduino

Существует множество версий этого микроконтроллера. Они отличаются друг от друга размерами, фирмой производителем, частотой процессора, количеством встроенной памяти, количеством контактов вывода/ввода. Так например есть самая популярная ардуинка — Arduino UNO.

Она подходит практически для всех целей, в том числе и для освоения микроконтроллеров. Есть более мощная версия Arduino MEGA, обладающая большей тактовой частотой процессора, увеличенной памятью, бОльшим количеством контактов и более внушительным размером.

Есть и более маленькие версии такие как Arduino Mini и Arduino Pro.

Описание самых популярных плат вы найдете на странице «Платы»

Что можно подключить к Arduino

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

Переферийные устройства

  • Кнопки, переключатели, сенсорные панели
  • Светодиоды
  • Динамики и микрофоны
  • Коллекторные, безколлекторные и шаговые электродвигатели
  • Сервоприводы
  • ЖК и LCD дисплеи.
  • Устройства считывающие радиометки RFID и NFC
  • Ультразвуковые и лазерные датчики расстояния
  • Модули Ethernet, WiFi и Bluetooth
  • Кардридеры SD
  • Модули GSM для совершения звонков и приема/отправки SMS
  • GPS для получения точных координат местоположения

Датчики

  • Освещенности
  • Магнитного поля
  • Температуры
  • Влажности воздуха и почвы
  • Уровня шума
  • Вибрации
  • Огня и дыма
  • Электронные компасы, гироскопы и акселерометры для определения положения в пространстве.

Датчики для Arduino

О точках с запятыми

Вы могли заинтересоваться: зачем в конце каждого выражения ставится точка с запятой? Таковы правила C++.
Подобные правила называются синтаксисом языка. По символу компилятор понимает где заканчивается
выражение.

Как уже говорилось, переносы строк для него — пустой звук, поэтому ориентируется он на этот знак препинания.
Это позволяет записывать сразу несколько выражений в одной строке:

void loop()
{
    digitalWrite(5, HIGH); delay(100); digitalWrite(5, LOW); delay(900);
}

Программа корректна и эквивалентна тому, что мы уже видели. Однако писать так — это дурной тон. Код
гораздо сложнее читается. Поэтому если у вас нет 100% веских причин писать в одной строке несколько
выражений, не делайте этого.

Приложение. Готовые каркасы и роботы Arduino

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

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

Обзор готовых игрушек-роботов Arduino.

Еще один обзор готовых ардуино-роботов.

Еще один вариант — покупка каркаса или корпуса робота: платформы на колесиках или гусенице, гуманоида, паука и т.п. В этом случае начинку робота придется делать самостоятельно.

Обзор каркасов для роботов Arduino и других плат.

Настройка Arduino IDE для работы

Для тонкой настройки Arduino IDE 1.8.5 в Windows или Linux следует через панель инструментов «Файл -> Настройки» В новом окне будет доступно несколько пунктов, которые можно настроить под себя (смотри картинку ниже). После настройки приложения, для вступления изменений в силу следует нажать кнопку «ОК» и перезапустить программу. Настройки можно изменить по своему усмотрению.

Настройка Arduino IDE для работы в Windows / Linux

  1. выбор места для хранения скетчей и библиотек;
  2. выбор языка интерфейса в программе Arduino IDE 1.8
  3. выбор размера шрифта текстового редактора и масштаба;
  4. показ подробных сообщений при компиляции / загрузке;
  5. показывать номера строк в текстовом редакторе;
  6. проверка обновлений в сети при запуске Arduino IDE;
  7. сохранение скетчей перед компиляцией / загрузкой.

Настройка Arduino IDE для Nano / Mega 2560 / Uno

При первом подключении микроконтроллера, следует убедиться, что программа Arduino IDE 1.8 определила плату Arduino Nano, подключенную к USB порту. При подключении любой платы Ардуино к компьютеру создается виртуальный COM порт. Проверить подключение можно через диспетчер устройств или через панель Arduino IDE «Инструменты -> Порт» — кроме COM1 должен появиться дополнительный порт.

Настройка порта программы Arduino IDE для Mega 2560

При подключении микроконтроллера Arduino к разным USB портам компьютера, номер COM порта будет меняться. Если у вас «неофициальный» микроконтроллер с microUSB, то необходимо дополнительно установить драйвера для CH340G. Если порт определился, то перед загрузкой скетча следует выбрать плату, которую вы используете в панели инструментов Arduino IDE «Инструменты -> Менеджер плат»

Выбор процессора микроконтроллера Mega 2560 в Arduino IDE

При подключении к компьютеру Arduino Uno следует выбрать в Менеджере плат Arduino/Genuino Uno. В случае с платой Arduino Mega или Nano, следует дополнительно выбрать процессор микроконтроллера. У Nano это может быть ATmega168 или ATmega328, у платы Mega процессор ATmega2560 или ATmega1280. Узнать тип можно по характеристикам, которые обычно производитель указывает на печатной плате.

Видео. Arduino IDE подключение Nano / Uno / Mega

После выполнения всех операций следует проверить подключение микроконтроллера и загрузить пустой скетч в плату или скетч для мигания светодиодом на Arduino. Для этого на панели инструментов есть соответствующие иконки: смотри картинку с обозначением функций Arduino IDE выше. При неправильном подключении или отсутствии драйверов программа сообщит ошибку — programmer is not responding.

Справочник языка Ардуино

Операторы

  • setup()
  • loop()

Синтаксис

  • ; (точка с запятой)
  • {} (фигурные скобки)
  • // (одностроковый коментарий)
  • /* */ (многостроковый коментарий)
  • #define
  • #include

Битовые операторы

  • & (побитовое И)
  • | (побитовое ИЛИ)
  • ^ (побитовое XOR или исключающее ИЛИ)
  • ~ (побитовое НЕ)
  • << (побитовый сдвиг влево)
  • >> (побитовый сдвиг вправо)
  • ++ (инкремент)
  • — (декремент)
  • += (составное сложение)
  • -= (составное вычитание)
  • *= (составное умножение)
  • /= (составное деление)

  • &= (составное побитовое И)
  • |= (составное побитовое ИЛИ)

Данные

Типы данных

  • void
  • boolean
  • char
  • unsigned char
  • byte
  • int
  • unsigned int
  • word
  • long
  • unsigned long
  • short
  • float
  • double
  • string — массив символов
  • String — объект
  • массивы

sizeof()

Библиотеки

  • EEPROM
  • SD
  • SPI
  • SoftwareSerial
  • Wire

Функции

Цифровой ввод/вывод

  • pinMode()
  • digitalWrite()
  • digitalRead()

Аналоговый ввод/вывод

  • analogReference()
  • analogRead()
  • analogWrite() — PWM

Только для Due

  • analogReadResolution()
  • analogWriteResolution()

Расширенный ввод/вывод

  • tone()
  • noTone()
  • shiftOut()
  • shiftIn()
  • pulseIn()

Время

  • millis()
  • micros()
  • delay()
  • delayMicroseconds()

Математические вычисления

  • min()
  • max()
  • abs()
  • constrain()
  • map()
  • pow()
  • sqrt()
  • sq()

Тригонометрия

  • sin()
  • cos()
  • tan()

Случайные числа

  • randomSeed()
  • random()

Биты и байты

  • lowByte()
  • highByte()
  • bitRead()
  • bitWrite()
  • bitSet()
  • bitClear()
  • bit()

Внешние прерывания

  • attachInterrupt()
  • detachInterrupt()

Прерывания

  • interrupts()
  • noInterrupts()

volatile

volatilevolatile

byte A = ;
byte B;

void loop() {
  A++;
  B = A + 1;
}
  1. Загрузить из памяти значение A в регистр Р1
  2. Загрузить в регистр Р2 константу 1
  3. Сложить значение Р2 с Р1 (результат в Р2)
  4. Сохранить значение регистра Р2 в памяти по адресу A
  5. Сложить содержимое регистра Р1 с константой 2
  6. Сохранить значение регистра Р1 в памяти по адресу B

loopvolatilevolatilevolatilevolatile

#define interruptPin 2
volatile byte f = ;

void setup() {
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), buttonPressed, FALLING);
}

void loop() {
  while (f == ) {
    
  }
  
}

void buttonPressed() {
  f = 1;
}

loopvolatilevolatileinterruptsnoInterruptsатомарно исполняемый блок кода

shiftOut()

В качестве третьего аргумента передаётся параметр bitOrder (порядок битов), который определяет в какой последовательности подаваемые биты будут интерпретироваться регистром — в прямом или обратном.
LSBFIRST (Least Significant Bit First) — означает, что вывод в регистр начнётся с последнего бита. Например, при передаче байта 00010111 на выходах регистра окажутся значения (с 1 по 8 пины) — 00010111.
MSBFIRST (Most Significant Bit First) — означает, что вывод в регистр начнётся с первого бита. При передаче байта 00010111 на выходах регистра окажутся значения в обратном порядке (с 1 по 8 пины) — 11101000.

О комментариях

Одно из правил качественного программирования: «пишите код так, чтобы он был настолько понятным, что не
нуждался бы в пояснениях». Это возможно, но не всегда. Для того, чтобы пояснить какие-то не очевидные
моменты в коде его читателям: вашим коллегам или вам самому через месяц, существуют так называемые
комментарии.

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

/*
   Функция setup вызывается самой первой,
   при подаче питания на Arduino
 
   А это многострочный комментарий
 */
void setup()
{
    // устанавливаем 13-й пин в режим вывода
    pinMode(13, OUTPUT);
}
 
void loop()
{
    digitalWrite(13, HIGH);
    delay(100); // спим 100 мс
    digitalWrite(13, LOW);
    delay(900);
}

Как видите, между символами и можно писать сколько угодно строк комментариев.
А после последовательности комментарием считается всё, что следует до конца строки.

Итак, надеемся самые основные принципы составления написания программ стали понятны.
Полученные знания позволяют программно управлять подачей питания на пины Arduino по
определённым временны́м схемам. Это не так уж много, но всё же достаточно для первых
экспериментов.

Оператор switch case

Оператор if позволяет проверить только одно условие. Иногда необходимо выполнить одно из действий в зависимости от возвращаемого или прочитанного значения. Для этого идеально подходит оператор множественного выбора switch. Ниже показан синтаксис команды switch:

switch (var)
{
case 1:
//инструкция для var=1
break;
case 2:
// инструкция для var=2
break;
default:
// инструкция по умолчанию (если var отличается от 1 и 2)
}

В зависимости от значения переменной var выполняются инструкции в определенных блоках. Метка case означает начало блока для указанного значения. Например, case 1: означает, что данный блок будет выполнен для значения переменной var, равной один.

Каждый блок должен быть завершен с помощью команды break. Он прерывает дальнейшее выполнение оператора switch. Если команду break пропустить, то инструкции будут выполняться и в последующих блоках до команды break. Метка default не является обязательной, как и else в команде if. Инструкции, расположенные в блоке default выполняются только тогда, когда значение переменной var не подходит ни к одному шаблону.

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

switch (x)
{
case 1:
//инструкция для x=1
break;
case 2:
case 3:
case 5:
// инструкция для x=2 или 3 или 4
break;
case 4:
// инструкция для x=4
break;
case 6:
// инструкция для x=6
break;
default:
// инструкция по умолчанию (если х отличается от 1,2,3,4,5,6)
}

В зависимости от значения переменной x будет выполнен соответствующий блок инструкций. Повторение case 2: case 3: case 5: информирует компилятор о том, что если переменная x имеет значение 2 или 3 или 5, то будет выполнен один и тот же фрагмент кода.

Что делают выражения

Теперь давайте попробуем понять почему написанная программа приводит в итоге к миганию светодиода.

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

Это делается выражением в функции :

pinMode(13, OUTPUT);

Выражения бывают разными: арифметическими, декларациями, определениями, условными и т.д. В данном
случае мы в выражении осуществляем вызов функции. Помните? У нас есть свои функции и
, которые вызываются чем-то, что мы назвали «нечто». Так вот теперь мы вызываем функции,
которые уже написаны где-то.

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

Уточняющие значения, такие как и называются аргументами функции. Совершенно не обязательно,
что у всех функций должно быть по 2 аргумента. Сколько у функции аргументов зависит от сути функции,
от того как её написал автор. Могут быть функции с одним аргументом, тремя, двадцатью; функции могут
быть без аргументов вовсе. Тогда для их вызова круглые скобка открывается и тут же закрывается:

noInterrupts();

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

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

Перейдём к функции :

void loop()
{
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(900);
}

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

Пройдёмся по выражениям по порядку. Итак, первое выражение — это вызов встроенной функции .
Она предназначена для подачи на заданный пин логического нуля (, 0 вольт) или логической единицы (, 5 вольт)
В функцию передаётся 2 аргумента: номер пина и логическое значение. В итоге, первым делом
мы зажигаем светодиод на 13-м пине, подавая на него 5 вольт.

Как только это сделано процессор моментально приступает к следующему выражению. У нас это вызов функции .
Функция — это, опять же, встроенная функция, которая заставляет процессор уснуть на определённое время.
Она принимает всего один аргумент: время в миллисекундах, которое следует спать. В нашем случае это 100 мс.

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

После того, как светодиод погашен мы приступаем к следующему выражению. И снова это вызов функции .
На этот раз мы засыпаем на 900 мс.

Как только сон окончен, функция завершается. По факту завершения «нечто» тут же вызывает её ещё раз
и всё происходит снова: светодиод поджигается, горит, гаснет, ждёт и т.д.

Если перевести написанное на русский, получится следующий алгоритм:

  1. Поджигаем светодиод
  2. Спим 100 миллисекунд
  3. Гасим светодиод
  4. Спим 900 миллисекунд
  5. Переходим к пункту 1

Таким образом мы получили Arduino с маячком, мигающим каждые 100 + 900 мс = 1000 мс = 1 сек.

Знакомство с интерфейсом Ардуино

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

Ниже расположена панель с иконками, которые отображают наиболее используемые функции Arduino IDE:

  • загрузка программы;
  • проверка на наличие ошибок;
  • создание нового скетча;
  • сохранение скетча;
  • загрузка сохранения;
  • открытие окна порта микроконтроллера;

Следующим по важности элементом является вкладка с файлами проекта. Если это простой скетч, то файл будет всего один

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

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

Компиляция – преобразование исходного кода языка высокого уровня в машинный код или на язык ассемблера.

Начало работы с Ардуино

Говоря бытовым языком, Ардуино – это электронная плата, в которую можно воткнуть множество разных устройств и заставить их работать вместе с помощью программы, написанной на языке Ардуино в специальной среде программирования.

Чаще всего плата выглядит вот так:

На рисунке показана одна из плат Ардуино – Arduino Uno. Мы изучим ее подробнее на следующих уроках.

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

Вся работа над проектом разбивается на следующие этапы:

  1. Придумываем идею и проектируем.
  2. Собираем электрическую схему. Тут нам пригодится макетная плата, упрощающая монтаж элементов. Безусловно, понадобятся навыки работы с электронными приборами и умение пользоваться мультиметром.
  3. Подключаем плату Arduino к компьютеру через USB.
  4. Пишем программу и записываем ее в плату буквально нажатием одной кнопки на экране в специальной среде программирования Arduino.
  5. Отсоединяем от компьютера.  Теперь устройство будет работать автономно – при включении питания оно будет управляться той программой, которую мы в него записали.

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

На экране показана программа (на сленге ардуинщиков текст программы называется “скетч”), которая будет мигать лампочкой, подсоединенной к 13 входу на плате Ардуино UNO. Как видим, программа вполне проста и состоит из понятных для знающих английский язык инструкций. В языке программирования Arduino используется свой диалект языка C++, но все возможности C++ поддерживаются.

Есть и другой вариант написания кода – визуальный редактор. Тут не нужно ничего писать – можно просто перемещать блоки и складывать из них нужный алгоритм. Программа загрузится в подключенную плату одним нажатием кнопки мыши!

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

В целом все выглядит довольно понятно, не так ли? Осталось разобраться в деталях.

Структура функции

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

void DashedLine()
{
Serial.println(«—————-«);
}

1
2
3
4

voidDashedLine()

{

Serial.println(«—————-«);

}

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

Имя функции

Когда мы создаем функцию, ей нужно дать имя. Соглашение об именах для функций такое же, как и для переменных:

  • Имя функции может состоять из буквенно-цифровых символов (от A до Z; от a до z; от 0 до 9) и символа подчеркивания (_).
  • Имя функции не может начинаться с цифры, т.е. цифр от 0 до 9.
  • Имя функции не должно совпадать с ключевым словом языка или существующей функцией.

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

Тип возврата

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

Тело функции

Тело функции состоит из операторов, заключенных в фигурные скобки {}. Операторы составляют функциональность функции (что функция будет делать при ее вызове).

Когда функция используется, она называется «вызванной». Далее мы рассмотрим, как вызвать функцию.

A Shorter Version of the Sketch

The sketch above can be written in a shorter way without using some of the intermediate variables as shown below.

void setup() {
    Serial.begin(9600);
    Serial.print("Area of circle is: ");
    // print area to 4 decimal places
    Serial.println(CircleArea(9.2), 4);
}

void loop() {
}

// calculate the area of a circle
float CircleArea(float radius)
{
    return (3.141592654 * radius * radius);
}

In this sketch, the CircleArea() function returns the result of the calculation on one line without first assigning it to a variable.

return (3.141592654 * radius * radius);

This method of doing the calculation and returning the value is fine, although it may not be as easy to read the code as the first example.

When the CircleArea() function is called in the sketch, it is passed to Serial.println() as if it were a variable. This is possible because when a function returns a variable, it takes on the value of the variable. The sketch therefore works the same way as the first sketch, although again, it is more difficult to read the code.

Serial.println(CircleArea(9.2), 4);

The size of the binary output file (the file that gets loaded to the Arduino after compiling) from the Arduino compiler is 4,040 bytes for both sketches in Arduino IDE version 1.0.6.

← Go back to Part 15Go to Part 17 →