[Dr.Zero]
В C++ для булевых переменных существует тип bool. Для обозначения истины в C++ используется слово true, а для обозначения лжи — слово false. Таким образом, если для объявления целочисленных переменных мы используем:
Для логических переменных, используется:
Поскольку C++ для Arduino — это некоторая надстройка над голым C++, для обозначения логического типа наряду с bool существует ещё слово boolean. Это абсолютные синонимы. Можете использовать и то и другое. Просто из соображений единого стиля и повышения читаемости кода выберите один из терминов и используйте его всюду. Мы в статье будем использовать bool, просто потому что в нём меньше букв и он входит в стандарт языка.
Применение на практике: экологичный отель
Давайте разовьём тему с энергосберегающим освещением и сделаем на Arduino устройство, которое включает свет в коридоре только тогда, когда это действительно необходимо.
Допустим, к Arduino подключён аналоговый датчик уровня освещённости, пироэлектрический цифровой датчик движения тёплых объектов и экологичная светодиодная лампа.
Тогда скетч будет выглядеть следующим образом:
Взглянем на loop и поймём что здесь происходит. С первой строкой всё понятно: мы считываем значение освещённости с аналогового сенсора с помощью встроенной функции analogRead и присваиваем его переменной с именем lightLevel.
Далее мы объявляем логическую переменную motionDetected в качестве значения которой присваиваем результат вызова встроенной функции digitalRead. Функция digitalRead похожа по своей сути на analogRead, но может возвращать лишь одно из двух значений: либо истину (true), либо ложь (false). То есть это функция, которая возвращает логическое значение. Она подходит для считывания показаний разнообразных бинарных цифровых датчиков. В нашем примере мы как раз использовали такой: пироэлектрический сенсор, который выдаёт 0 вольт, пока движения в его радиусе видимости нет и 5 вольт, когда замечено перемещение тёплого объекта: человека, кошки или кого-то ещё. Нулю вольт микроконтроллер ставит в соответствие значение false, а пяти вольтам — true.
Итак, по итогам исполнения второй строки, в переменной motionDetected будет храниться либо истина, либо ложь в зависимости от того замечено ли движение в коридоре.
Далее мы видим определение булевой переменной tooDark, которой в качестве значения присваивается значение выражения lightLevel < LIGHT_LEVEL_THRESHOLD. Символ <, как можно догадаться, в C++ означает оператор «меньше, чем». Из двух численных операндов, этот оператор делает один логический результат. Значение всего выражения считается истинным, если то, что записано слева от знака (lightLevel в нашем случае) меньше, чем то, что записано справа от знака (LIGHT_LEVEL_THRESHOLD). Довольно логично и интуитивно понятно, не правда ли?!
Таким образом в переменной tooDark окажется значение true, только если значение уровня освещённости lightLevel, полученное ранее, окажется меньше 600. В противном случае, в переменной окажется false.
Конкретное значение, вроде 600 в нашем случае, в подобных случаях часто получают экспериментально: в зависимости от используемого сенсора и конфигурации помещения, где стоит устройство.
Идём дальше. Мы видим объявление булевой переменной lightningRequired, в качестве значения которой присваивается значение выражения tooDark && motionDetected. Символ && в C++ означает оператор логического «и». Как можно догадаться, всё выражение считается истинным тогда и только тогда, когда и то, что справа, и то что слева от оператора истинно. Таким образом, переменная lightningRequired примет значение true, если в коридоре одновременно: и слишком темно, и замечено движение человека. Если не выполнено хоть одно из условий, результатом будет false. Как раз то, что нужно.
И наконец, последним выражением идёт вызов функции digitalWrite для пина Arduino, к которому подключена лампа. Нам нужно включить лампу, если переменная lightningRequired содержит истинное значение и выключить, если в ней хранится ложь. Чтобы сделать это, мы используем тернарный условный оператор ? :. Где в качестве условия используем просто значение переменной lightningRequired. Помните? В тернарном операторе условие считается выполненным, если его значение — не ноль; и не выполненным если его значение — ноль.
На самом деле для процессора не существует понятия логических значений. Всё что он умеет — оперировать над целыми числами. Поэтому в C++ существует автоматическое преобразование типов. Там, где ожидается int, а мы используем bool, за кадром происходит автоматическое преобразование: true превращается в целое число 1, а false — в целое число 0.
Так что, булевы выражения и переменные — ни что иное, как удобство для программистов, синтаксический сахар, который позволяет писать программы более понятно и выразительно.
Возвращаясь к нашему примеру, в выражении:
второй аргумент примет значение HIGH, если lightningRequired — это true; и LOW, если lightningRequired — это false. Таким образом, мы добились чего хотели: включения света, если он нужен и выключения, если он не уместен.
О краткости записи
Если вспомнить об автоматическом преобразовании переменных разных типов, а ещё о том, что HIGH — это ничто иное, как макроопределение числа 1, а LOW — макроопределение числа 0, последнюю строку в нашем примере можно сократить до лаконичного выражения:
Мы обошлись без тернарного оператора: ведь всё равно функция digitalWrite получит:
единицу: то же самое, что и HIGH, если lightningRequired будет true
ноль: то же самое, что и LOW, если lightningRequired будет false
Кроме того, логические выражения — это самые обычные выражения в C++, к которым применяются общие правила встраивания. Поэтому весь код loop в примере с экологичным освещением на самом деле мог бы быть записан в одну строку:
Да, код теперь находится на грани читаемости, но это всего лишь демонстрация возможностей. В реальной жизни лучше использовать пару промежуточных переменных:
Или хотя бы использовать перенос строк для наглядности:
Автор урока: [Dr.Zero]. Если нужнен урок со значением if пишите,сделаю
PHP:
int myValue = 42;
PHP:
bool tooDark = false;
bool humanDetected = true;
Применение на практике: экологичный отель
Давайте разовьём тему с энергосберегающим освещением и сделаем на Arduino устройство, которое включает свет в коридоре только тогда, когда это действительно необходимо.
Допустим, к Arduino подключён аналоговый датчик уровня освещённости, пироэлектрический цифровой датчик движения тёплых объектов и экологичная светодиодная лампа.
Тогда скетч будет выглядеть следующим образом:
PHP:
#define LIGHT_SENSOR_PIN A0
#define MOTION_SENSOR_PIN 2
#define LED_LAMP_PIN 5
#define LIGHT_LEVEL_THRESHOLD 600
void setup()
{
pinMode(LIGHT_SENSOR_PIN, INPUT);
pinMode(MOTION_SENSOR_PIN, INPUT);
pinMode(LED_LAMP_PIN, OUTPUT);
}
void loop()
{
int lightLevel = analogRead(LIGHT_SENSOR_PIN);
bool motionDetected = digitalRead(MOTION_SENSOR_PIN);
bool tooDark = lightLevel < LIGHT_LEVEL_THRESHOLD;
bool lightningRequired = tooDark && motionDetected;
digitalWrite(LED_LAMP_PIN, lightningRequired ? HIGH : LOW);
}
Далее мы объявляем логическую переменную motionDetected в качестве значения которой присваиваем результат вызова встроенной функции digitalRead. Функция digitalRead похожа по своей сути на analogRead, но может возвращать лишь одно из двух значений: либо истину (true), либо ложь (false). То есть это функция, которая возвращает логическое значение. Она подходит для считывания показаний разнообразных бинарных цифровых датчиков. В нашем примере мы как раз использовали такой: пироэлектрический сенсор, который выдаёт 0 вольт, пока движения в его радиусе видимости нет и 5 вольт, когда замечено перемещение тёплого объекта: человека, кошки или кого-то ещё. Нулю вольт микроконтроллер ставит в соответствие значение false, а пяти вольтам — true.
Итак, по итогам исполнения второй строки, в переменной motionDetected будет храниться либо истина, либо ложь в зависимости от того замечено ли движение в коридоре.
Далее мы видим определение булевой переменной tooDark, которой в качестве значения присваивается значение выражения lightLevel < LIGHT_LEVEL_THRESHOLD. Символ <, как можно догадаться, в C++ означает оператор «меньше, чем». Из двух численных операндов, этот оператор делает один логический результат. Значение всего выражения считается истинным, если то, что записано слева от знака (lightLevel в нашем случае) меньше, чем то, что записано справа от знака (LIGHT_LEVEL_THRESHOLD). Довольно логично и интуитивно понятно, не правда ли?!
Таким образом в переменной tooDark окажется значение true, только если значение уровня освещённости lightLevel, полученное ранее, окажется меньше 600. В противном случае, в переменной окажется false.
Конкретное значение, вроде 600 в нашем случае, в подобных случаях часто получают экспериментально: в зависимости от используемого сенсора и конфигурации помещения, где стоит устройство.
Идём дальше. Мы видим объявление булевой переменной lightningRequired, в качестве значения которой присваивается значение выражения tooDark && motionDetected. Символ && в C++ означает оператор логического «и». Как можно догадаться, всё выражение считается истинным тогда и только тогда, когда и то, что справа, и то что слева от оператора истинно. Таким образом, переменная lightningRequired примет значение true, если в коридоре одновременно: и слишком темно, и замечено движение человека. Если не выполнено хоть одно из условий, результатом будет false. Как раз то, что нужно.
И наконец, последним выражением идёт вызов функции digitalWrite для пина Arduino, к которому подключена лампа. Нам нужно включить лампу, если переменная lightningRequired содержит истинное значение и выключить, если в ней хранится ложь. Чтобы сделать это, мы используем тернарный условный оператор ? :. Где в качестве условия используем просто значение переменной lightningRequired. Помните? В тернарном операторе условие считается выполненным, если его значение — не ноль; и не выполненным если его значение — ноль.
На самом деле для процессора не существует понятия логических значений. Всё что он умеет — оперировать над целыми числами. Поэтому в C++ существует автоматическое преобразование типов. Там, где ожидается int, а мы используем bool, за кадром происходит автоматическое преобразование: true превращается в целое число 1, а false — в целое число 0.
Так что, булевы выражения и переменные — ни что иное, как удобство для программистов, синтаксический сахар, который позволяет писать программы более понятно и выразительно.
Возвращаясь к нашему примеру, в выражении:
PHP:
digitalWrite(LED_LAMP_PIN, lightningRequired ? HIGH : LOW);
О краткости записи
Если вспомнить об автоматическом преобразовании переменных разных типов, а ещё о том, что HIGH — это ничто иное, как макроопределение числа 1, а LOW — макроопределение числа 0, последнюю строку в нашем примере можно сократить до лаконичного выражения:
PHP:
digitalWrite(LED_LAMP_PIN, lightningRequired);
единицу: то же самое, что и HIGH, если lightningRequired будет true
ноль: то же самое, что и LOW, если lightningRequired будет false
Кроме того, логические выражения — это самые обычные выражения в C++, к которым применяются общие правила встраивания. Поэтому весь код loop в примере с экологичным освещением на самом деле мог бы быть записан в одну строку:
PHP:
void loop()
{
digitalWrite(LED_LAMP_PIN, analogRead(LIGHT_SENSOR_PIN) < LIGHT_LEVEL_THRESHOLD && digitalRead(MOTION_SENSOR_PIN));
}
PHP:
void loop()
{
bool tooDark = analogRead(LIGHT_SENSOR_PIN) < LIGHT_LEVEL_THRESHOLD;
bool motionDetected = digitalRead(MOTION_SENSOR_PIN);
digitalWrite(LED_LAMP_PIN, tooDark && motionDetected);
}
PHP:
void loop()
{
digitalWrite(LED_LAMP_PIN,
analogRead(LIGHT_SENSOR_PIN) < LIGHT_LEVEL_THRESHOLD &&
digitalRead(MOTION_SENSOR_PIN)
);
}
Автор урока: [Dr.Zero]. Если нужнен урок со значением if пишите,сделаю
