Доступ к готовым решениям

Переход в группу "Пользователь"

300.00 ₽
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

C++ Логические операции в С++

Статус
В этой теме нельзя размещать новые ответы.

[Dr.Zero]

В C++ для булевых переменных существует тип bool. Для обозначения истины в C++ используется слово true, а для обозначения лжи — слово false. Таким образом, если для объявления целочисленных переменных мы используем:
PHP:
int myValue = 42;
Для логических переменных, используется:
PHP:
bool tooDark = false;
bool humanDetected = true;
Поскольку C++ для Arduino — это некоторая надстройка над голым C++, для обозначения логического типа наряду с bool существует ещё слово boolean. Это абсолютные синонимы. Можете использовать и то и другое. Просто из соображений единого стиля и повышения читаемости кода выберите один из терминов и используйте его всюду. Мы в статье будем использовать bool, просто потому что в нём меньше букв и он входит в стандарт языка.

Применение на практике: экологичный отель

Давайте разовьём тему с энергосберегающим освещением и сделаем на 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);
}
Взглянем на 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.

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

Возвращаясь к нашему примеру, в выражении:
PHP:
digitalWrite(LED_LAMP_PIN, lightningRequired ? HIGH : LOW);
второй аргумент примет значение HIGH, если lightningRequired — это true; и LOW, если lightningRequired — это false. Таким образом, мы добились чего хотели: включения света, если он нужен и выключения, если он не уместен.

О краткости записи

Если вспомнить об автоматическом преобразовании переменных разных типов, а ещё о том, что HIGH — это ничто иное, как макроопределение числа 1, а LOW — макроопределение числа 0, последнюю строку в нашем примере можно сократить до лаконичного выражения:
PHP:
digitalWrite(LED_LAMP_PIN, lightningRequired);
Мы обошлись без тернарного оператора: ведь всё равно функция digitalWrite получит:

единицу: то же самое, что и 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 пишите,сделаю
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу