Arduino программирование для начинающих

Класс

Класс является одним из самых крупных и важных понятий и инструментов языка C++, именно он делает язык объектно-ориентированным и очень мощным. Мы очень часто пользуемся объектами и методами, ведь 99% библиотек являются просто классами! Объекты, методы, что это? Я могу привести несколько официальных определений (хотя вы сами можете их загуглить), но не буду, потому что они очень абстрактные и ещё сильнее вас запутают. Давайте рассмотрим всё на примере библиотеки, пусть это будет стандартная и всем знакомая библиотека Servo. Возьмём из неё пример Knob и разберёмся, где кто и как называется.

#include <Servo.h>  // подключаем заголовочный ФАЙЛ библиотеки, Servo.h

Servo myservo;  // создаём ОБЪЕКТ myservo КЛАССА Servo

int potpin = 0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin

void setup() {
  myservo.attach(9);  // применяем МЕТОД attach к ОБЪЕКТУ myservo
}

void loop() {
  val = analogRead(potpin);
  val = map(val, 0, 1023, 0, 180);
  myservo.write(val);      // применяем МЕТОД write к ОБЪЕКТУ myservo
  delay(15);
}

Итак, мы можем создать объект класса, и применять к нему методы. Какую первую мысль вызывает использование объекта? Правильно, “ой, как удобно“! Ведь мы можем создать несколько объектов Servo, и управлять каждым в отдельности при помощи одинаковых методов, но каждый объект будет обладать индивидуальным набором настроек, которые хранятся где-то внутри него. Это и есть объектно-ориентированный подход, позволяющий создавать очень сложные многоуровневые программы, не испытывая особых трудностей.

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

ООП и процедурный подход

Порог вхождения

Мы начинаем мыслить и писать процедурно с самых первых уроков, потому что это просто. Работа с ООП требует гораздо более глубоких знаний С++, а эффективная работа – максимальных.

Объем кода

Оборачивание всего подряд в классы приводит к генерации огромного объема кода как текста: его просто приходится писать гораздо больше, соответственно читать тоже. Делать это в родной IDE к слову очень неприятно по сравнению со взрослыми средами разработки, в которых есть автоподстановка слов и членов классов, а также “дерево” проекта и его файлов.

Вес и скорость выполнения кода

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

Область определения и названия

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

Крупные проекты

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

Мелкие проекты и прототипы

Написание небольшой программы в процедурном стиле гораздо легче и быстрее классического оопшного программирования на C++, именно поэтому Ардуино IDE это просто блокнот, который сохраняет скетч в своём расширении .ino, вместо взрослых .h и .cpp: нам не нужно думать о файловой структуре проекта, мы просто пишем код и всё. Для быстрого прототипирования и отладки небольших алгоритмов это работает отлично, но с крупным проектом могут начаться проблемы и неудобства.

Библиотеки и совместимость

Если вы откроете любую библиотеку для Ардуино, то с 99.9% вероятностью увидите там класс. Сила ООП в том, что мы берём библиотеку (или просто какой то класс), добавляем в свой код и не получаем никаких конфликтов имён и вообще пересечения кода (в 99% случаев): класс работает сам по себе, это отдельная программа. Если вы возьмёте например какой то кусок “голого” кода и вставите в свой такой же голый код – будет довольно большой шанс пересечений и конфликтов, а самое страшное – когда компилятор не видит ошибок, а программа работает неадекватно.

Задержки

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

– “приостанавливает” выполнение кода на миллисекунд. Дальше функции выполнение кода не идёт, за исключением прерываний. Использовать рекомендуется только в самых крайних или тех случаях, когда delay не влияет на скорость работы устройства.  принимает тип данных и может приостановить выполнение на срок от 1 мс до ~50 суток (4 294 967 295 миллисекунд) с разрешением в 1 миллисекунду. Работает на системном таймере Timer 0, поэтому не работает внутри прерывания и при отключенных прерываниях.

– Аналог , приостанавливает выполнение кода на микросекунд. принимает тип данных и может приостановить выполнение на срок от 4 до 16383 мкс с разрешением 4 мкс

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

Задержки использовать очень просто:

void setup() {}

void loop() {
  // что-то выполнить
  delay(500); // подождать полсекунды
}

И вот мы можем делать какое-то действие два раза в секунду.

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

// самодельная функция мкс задержки
void myDelayMicroseconds(uint32_t us) {
  uint32_t tmr = micros();
  while (micros() - tmr < us);
}

А что делать, если нам нужно выполнять одно действие два раза в секунду, а другое – три? А третье – 10 раз в секунду например. Сразу привыкаем к той мысли, что задержки лучше вообще не использовать в реальном коде. Разве что , он бывает нужен для генерации каких-то протоколов связи. Нормальным инструментом для тайм-менеджмента своего кода являются функции, которые считают время со старта МК.

Как начать правильно пользоваться Arduino

Если вы никогда ранее не программировали, и это ваш первый опыт, то программирование микроконтроллеров Arduino пойдёт куда проще, если вы начнёте с основ.

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

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

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

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

С чего начать работу с Ардуино

Если вы делаете первые шаги в мире Ардуино, то советуем вам заранее приготовиться к двойному потоку знаний. Во-первых, вам придется разобраться с тем, что такое контроллер Arduino, какие устройства можно к нему подключить и как это сделать. Потребуется разобраться с основами электроники. Во-вторых, придется научиться навыкам программирования в Arduino. Для профессиональной работы нужны знания C++, для начинающих доступны многочисленные графические среды с блочным программированием. Например, mBlock или ArduBlock. При отсутствии реальной платы можно воспользоваться одним из эмуляторов ардуино.

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

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

Резюмируя

Теперь по сути дела: датчики, их куча кучная, измерять можно ну просто всё, что вообще измеряется. Электроника: напряжение, ток, сопротивление, работа с переменным током, поля. Параметры микроклимата: температура, влажность, давление, содержание газов, скорость ветра, освещенность, что угодно. Интересных модулей тоже очень много: Bluetooth, сотовая связь, GPS, дисплеи различных типов и размеров, датчики присутствия, как ИК, так и микроволновые, модули для беспроводной связи ардуинок и многое другое.

Можно управлять абсолютно любой железкой, которая выполняет свою функцию просто при подаче питания: лампочка, светодиодная лента, электронагреватель, мотор или любой электропривод, электромагнит, соленоид-толкатель, и это все с любым напряжением питания. Но тут нужно кое что понять: Ардуино (точнее микроконтроллер) – логическое устройство, то есть по-хорошему она должна только отдавать команды другим устройствам, или принимать их от них. Это я к тому, что напрямую от ардуино не работают ни лампочки, ни моторчики, ни нагреватели, ни-хуче-го. Максимум – светодиод. С пониманием этого идём дальше. Чтобы ардуино включила или выключила (подала питание) на другое устройство, нужно устройство – посредник, например реле или транзистор. Ардуино управляет реле, а реле в свою очередь включает любую нужную нагрузку с любым напряжением питания и все такое, подробнее об этом поговорим отдельно.

Как суть всего выше написанного – возможности Ардуино по подключению и управлению различными железками практически безграничны, можно воплотить любую идею, даже самую безумную. Датчики что то измеряют, исполнительные устройства что то контролируют, в это же время ведётся отсылка данных куда-нибудь, что-то отображается на дисплее и контролируется при помощи кнопок. Романтика!

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

Помехи и защита от них

Если в одной цепи питания с Ардуино стоят мощные потребители, такие как сервоприводы, адресные светодиодные ленты, модули реле и прочее, на линии питания могут возникать помехи, приводящие к сильным шумам измерений с АЦП, а более мощные помехи могут дергать прерывания и даже менять состояния пинов, нарушая связь по различным интерфейсам связи и внося ошибки в показания датчиков, выводя чушь на дисплеи, а иногда дело может доходить до перезагрузки контроллера или его зависания. Некоторые модули также могут зависать, перезагружаться и сбоить при плохом питании, например bluetooth модуль спокойно может зависнуть и висеть до полной перезагрузки системы, а радиомодули rf24 вообще не будут работать при “шумном” питании.

Более того, помеха может прийти откуда не ждали – по воздуху, например от электродвигателя, индуктивный выброс ловится проводами и делает с системой всякое. Что же делать? “Большие дяди” в реальных промышленных устройствах делают очень много для защиты от помех, этому посвящены целые книги и диссертации. Мы с вами рассмотрим самое простое, что можно сделать дома на коленке.

  • Питать логическую часть (Ардуино, слаботочные датчики и модули) от отдельного малошумящего блока питания 5V, то есть разделить питание логической и силовой частей, а ещё лучше питаться в пин Vin от блока питания на 7-12V, так как линейный стабилизатор даёт очень хорошее ровное напряжение. Для корректной работы устройств, питающихся отдельно (драйверы моторов, приводы) нужно соединить земли Ардуино и всех внешних устройств;
  • Поставить конденсаторы по питанию платы, максимально близко к пинам 5V и GND: электролит 6.3V 100-470 uF (мкФ, ёмкость зависит от качества питания: при сильных просадках напряжения ставить ёмкость больше, при небольших помехах хватит и 10-47 мкФ) и керамический на 0.1-1 uF. Это сгладит помехи даже от сервоприводов;
  • У “выносных” на проводах элементах системы (кнопки, крутилки, датчики) скручивать провода в косичку, преимущественно с землёй. А ещё лучше использовать экранированные провода, экран естественно будет GND. Таким образом защищаемся от электромагнитных наводок;
  • Соединять все земли одним толстым проводом и по возможности заземлять на центральное заземление;
  • Металлический и заземленный корпус устройства (или просто обернутый фольгой ), на который заземлены все компоненты схемы – залог полного отсутствия помех и наводок по воздуху.

Ещё лучше с фильтрацией помех справится LC фильтр, состоящий из индуктивности и конденсатора. Индуктивность нужно брать с номиналом в районе 100-300 мкГн и с током насыщения больше, чем ток нагрузки после фильтра. Конденсатор – электролит с ёмкостью 100-1000 uF в зависимости опять же от тока потребления нагрузки после фильтра. Подключается вот так, чем ближе к нагрузке – тем лучше:

Подробнее о расчёте фильтров можно почитать здесь.

Индуктивные выбросы

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

  • Для цепей постоянного тока обязательно ставить мощный диод обратно-параллельно нагрузке, максимально близко к клеммам реле. Диод примет (замкнёт) на себя индуктивный выброс от мотора/катушки;
  • Туда же, на клеммы реле, можно поставить RC цепочку, называемую в этом случае искрогасящей: резистор 39 Ом 0.5 Вт, конденсатор 0.1 мкФ 400V (для цепи 220В);
  • Для сетей переменного тока использовать твердотельное (SSR) реле с детектором нуля (Zero-cross detector), они же называются “бесшумные” реле. Если в цепи переменного тока вместо реле стоит симистор с оптопарой, то оптопару нужно использовать опять же с детектором нуля, такая оптопара, как и SSR zero-cross будут отключать нагрузку в тот момент, когда напряжение в сети переходит через ноль, это максимально уменьшает все выбросы.

Подробнее об искрогасящих цепях можно почитать вот в этой методичке.

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

// ========= МАТЕМАТИКА =========
// полный урок тут: https://alexgyver.ru/lessons/compute/

+ , — , * , / , % ; // сложить, вычесть, умножить, разделить, остаток от деления
a = b + c / d;

++ , — , += , -= , *= , /= ; // прибавить 1, вычесть 1, прибавить, вычесть, умножить, разделить
a++; // ~ a = a + 1;
a /= 10; // ~ a = a / 10;

// === БОЛЬШИЕ ВЫЧИСЛЕНИЯ ===
// ВАЖНО! Для арифметических вычислений по умолчанию используется ячейка long (4 байта)
// но при умножении и делении используется int (2 байта)
// Если при умножении чисел результат превышает 32’768, он будет посчитан некорректно.
// Для исправления ситуации нужно писать (long) перед умножением, что заставит МК выделить дополнительную память
long val;
val = 2000000000 + 6000000; // посчитает корректно (т.к. сложение)
val = 25 * 1000; // посчитает корректно (умножение, меньше 32’768)
val = 35 * 1000; // посчитает НЕКОРРЕКТНО! (умножение, больше 32’768)
val = (long)35 * 1000; // посчитает корректно (выделяем память (long) )
val = 1000 + 35 * 10 * 100; // посчитает НЕКОРРЕКТНО! (в умножении больше 32’768)
val = 1000 + 35 * 10 * 100L; // посчитает корректно! (модификатор L)
val = (long)35 * 1000 + 35 * 1000; // посчитает НЕКОРРЕКТНО! Второе умножение всё портит
val = (long)35 * 1000 + (long)35 * 1000; // посчитает корректно (выделяем память (long) )

// === ВЫЧИСЛЕНИЯ FLOAT ===
// если при вычислении двух целочисленных нужен дробный результат — пишем (float)
float val;
val = 100 / 3; // посчитает НЕПРАВИЛЬНО (результат 3.0)
val = (float)100 / 3; // посчитает правильно (указываем (float))
val = 100.0 / 3; // посчитает правильно (есть число float)

// при присваивании float числа целочисленному типу данных дробная часть отсекается
int val;
val = 3.25; // val принимает 3
val = 3.92; // val принимает 3
val = round(3.25); // val принимает 3
val = round(3.92); // val принимает 4

// === МАТЕМАТИЧЕСКИЕ ФУНКЦИИ ===
// Ограничить диапазон числа val между low и high
val = constrain(val, low, high);

// Перевести диапазон числа val (от inMin до inMax) в новый диапазон (от outMin до outMax)
val = map(val, inMin, inMax, outMin, outMax);

min(a, b); // Возвращает меньшее из чисел a и b
max(a, b); // Возвращает большее из чисел
abs(x); // Модуль числа
round(x); // Математическое округление
radians(deg); // Перевод градусов в радианы
degrees(rad); // Перевод радиан в градусы
sq(x); // Квадрат числа
cos(x) // Косинус (радианы)
sin(x) // Синус (радианы)
tan(x) // Тангенс (радианы)
fabs(x) // Модуль для float чисел
fmod(x, y) // Остаток деления x на у для float
sqrt(x) // Корень квадратный
sqrtf(x) // Корень квадратный для float чисел
cbrt(x) // Кубический корень
hypot(x, y) // Гипотенуза ( корень(x*x + y*y) )
square(x) // Квадрат ( x*x )
floor(x) // Округление до целого вниз
ceil(x) // Округление до целого вверх
exp(x) // Экспонента (e^x)
cosh(x) // Косинус гиперболический (радианы)
sinh(x) // Синус гиперболический (радианы)
tanh(x) // Тангенс гиперболический (радианы)
acos(x) // Арккосинус (радианы)
asin(x) // Арксинус (радианы)
atan(x) // Арктангенс (радианы)
atan2(y, x) // Арктангенс (y / x) (позволяет найти квадрант, в котором находится точка)
log(x) // Натуральный логарифм х ( ln(x) )
log10(x) // Десятичный логарифм x ( log_10 x)
pow(x, y) // Степень ( x^y )
fma(x, y, z) // Возвращает x*y + z
fmax(x, y) // Возвращает большее из чисел
fmin(x, y) // Возвращает меньшее из чисел
trunc(x) // Возвращает целую часть числа с дробной точкой
round(x) // Математическое округление

// === КОНСТАНТЫ ===
F_CPU // частота тактирования в Гц (16000000 для 16 МГц)
INT8_MAX // 127 Максимальное значение для char, int8_t
UINT8_MAX // 255 Максимальное значение для byte, uint8_t
INT16_MAX // 32767 Максимальное значение для int, int16_t
UINT16_MAX // 65535 Максимальное значение для unsigned int, uint16_t
INT32_MAX // 2147483647 Максимальное значение для long, int32_t
UINT32_MAX // 4294967295 Максимальное значение для unsigned long, uint32_t
M_E // 2.718281828 Число e
M_LOG2E // 1.442695041 log_2 e
M_LOG10E // 0.434294482 log_10 e
M_LN2 // 0.693147181 log_e 2
M_LN10 // 2.302585093 log_e 10
M_PI // 3.141592654 pi
M_PI_2 // 1.570796327 pi/2
M_PI_4 // 0.785398163 pi/4
M_1_PI // 0.318309886 1/pi
M_2_PI // 0.636619772 2/pi
M_2_SQRTPI // 1.128379167 2/корень(pi)
M_SQRT2 // 1.414213562 корень(2)
M_SQRT1_2 // 0.707106781 1/корень(2)
PI // 3.141592654 Пи
HALF_PI // 1.570796326 пол Пи
TWO_PI // 6.283185307 два Пи
EULER // 2.718281828 Число Эйлера е
DEG_TO_RAD // 0.01745329 Константа перевода град в рад
RAD_TO_DEG // 57.2957786

AlexGyver

Сайт для любителей техники предоставляет бесплатные текстовые уроки — максимально подробные уроки по программированию Arduino с разбором всех тонкостей и особенностей языка.

Есть также бесплатные видеоуроки. Цикл охватывает все стандартные операторы и функции Ардуино и построен таким образом, что от выпуска к выпуску у зрителя идёт плавное формирование “базы”, каждый последующий урок (видео урок) содержит в себе информацию из предыдущих, то есть уроки усложняются и становятся комплексными.

Что узнает ребенок:

  • Что такое Ардуино и зачем она нужна?
  • Что умеет Ардуино и что можно сделать на её основе?
  • Подключение датчиков к Ардуино
  • Питание Arduino от различных источников электричества
  • Математические операторы для работы с переменными
  • Особенности переменных и констант
  • Общение между компьютером и Arduino Через COM порт
  • Какие существуют типы реле? В чём достоинства и недостатки?
  • Как подключить реле и как им управлять?

И это еще не все. 16 видеоуроков расскажут все нюансы о программировании на Arduino.

Подключение вашей платы Arduino к компьютеру

После того как вы установили Arduino IDE на свой компьютер следующим логичным шагом будет подключение платы Arduino UNO к компьютеру. Чтобы сделать это просто используйте кабель для программирования (синего цвета) и соедините его с платой Arduino и USB портом вашего компьютера.

Синий кабель для программирования может выполнять следующие три функции:

  1. Он запитывает плату Arduino UNO, то есть чтобы обеспечить выполнение программ на ней необходимо просто запитать ее с помощью USB кабеля.
  2. Через него программируется микроконтроллер ATmega328, находящийся на плате Arduino UNO. То есть код программы пересылается из компьютера в микроконтроллер именно по этому кабелю.
  3. Он может функционировать в качестве кабеля для последовательной связи, то есть с его помощью можно передавать данные с Arduino UNO в компьютер – это полезно для целей отладки программы.

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

Поскольку вы подключаете плату Arduino в первый раз к компьютеру необходимо некоторое время чтобы драйвера для нее успешно установились. Чтобы проверить правильно ли все установилось и определилось откройте «Диспетчер устройств (Device manager)» на вашем компьютере.

В диспетчере устройств откройте опцию «Порты» “Ports (COM & LPT)”, кликните на ней и посмотрите правильно ли отображается там ваша плата.

При этом стоит отметить, что не стоит обращать внимание на то, какой номер порта отобразился у вашей платы Arduino – он может, к примеру, выглядеть как CCH450 или что то подобное. Этот номер порта просто определяется производителем платы и больше ни на что не влияет

Если вы не можете в диспетчере устройств найти опцию “Ports (COM & LPT)”, то это означает, что ваша плата не корректно определилась компьютером. В большинстве случает это означает проблему с драйверами – по какой то причине они автоматически не установились для вашей платы. В этом случае вы должны будете вручную установить необходимые драйверы.

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

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

Сравнение

В языке C++ (как и пожалуй во всех языках) есть такое понятие, как логическая величина, которая принимает два значения: правда и ложь, и , 1 и 0. В качестве типа данных по работе с логическими величинами у нас есть (синоним – ), который может принимать значения 0 () или 1 (). Точно такое же значение возвращает результат сравнения двух чисел или переменных, для сравнения у нас есть несколько операторов сравнения:

  • == равенство (a == b)
  • != неравенство (a != b)
  • >= больше или равно (a >= b)
  • <= меньше или равно (a <= b)
  • > больше (a > b)
  • < меньше (a < b)

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

  • ! логическое НЕ, отрицание. Есть аналог – оператор
  • && логическое И. Есть аналог – оператор
  • || логическое ИЛИ. Есть аналог – оператор
byte a = 10, b = 20;
(a > b);  // false
(a != b); // true

boolean flag = true;
flag;   // true
!flag;  // false !инверт
!(a > b); // true

//flagA = true, flagB = false;
(flagA && flagB); // false, т.к. B false
//flagA = true, flagB = true;
(flagA and flagB);  // true, т.к. оба true

//flagA = true, flagB = false;
(flagA || flagB); // true, т.к. хотя бы А true
//flagA = false, flagB = false;
(flagA or flagB);  // false, т.к. ни А ни В не true 

Результаты операторов сравнения можно использовать для работы с условиями, а также для цикла (речь о нём пойдёт в следующем уроке)

Сравнение float

Со сравнением чисел всё не так просто из за особенности самой модели “чисел с плавающей точкой” – вычисления иногда производятся с небольшой погрешностью, из за этого сравнение может работать неверно! Пример из:

float val1 = 0.1;
// val1 == 0.100000000

float val2 = 1.1 - 1.0;
// val2 == 0.100000023 !!!

// казалось бы, val1 == val2
// но сравнение вернёт false
if (val1 == val2);  // false

Будьте внимательны при сравнении float чисел, особенно со строгими операциями ==, >= и <=: результат может быть некорректным и нелогичным!

Подводим итоги урока

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

В следующих уроках мы с вами узнаем, как работает контроллер, разберем устройство платы Arduino Uno и запустим свой первый проект.

Оцените статью
Рейтинг автора
5
Материал подготовил
Андрей Измаилов
Наш эксперт
Написано статей
116
Добавить комментарий