Выпуск 7. Логические операции И, ИЛИ, НЕ. Основы Arduino для начинающих
И снова здравствуйте! :)
Это седьмая видео-статья из цикла «Основы Arduino для начинающих» и сегодня мы поговорим о таком важном понятии, как логические операции, без которых не обойтись при решении практически любой задачи.
Предыдущие выпуски вы найдете здесь: 0,1,2,3,4,5,6
Видеоверсия поста:
Начнем с определения в википедии – логическая операция в программировании, это операция над выражениями логического (булевского) типа, соответствующая некоторой операции над высказываниями в алгебре логики. На первый взгляд – ничего не понятно, давайте подробнее разберемся, что такое логический или булевский тип, а так же алгебра логики.
Фраза логический (он же булевский) тип выражения означает, что это выражение может принимать только два значения – ложь или истина, 0 или 1. Если мы укажем переменной, что она имеет тип bool (boolean), то, как ни крути, значения, которые она сможет в себе нести, будут либо 0, либо 1. Помните, в предыдущих выпусках мы составляли условия, в зависимости от истинности или ложности которых происходили какие-либо действия – как раз тогда мы уже работали с булевыми выражениями.
Итак, кажется, теперь становится более понятной первая строчка определения – логическая операция, это операция над выражениями логического (булевского) типа. Теперь со второй частью об операциях алгебры логики.
Каждый из вас помнит уроки математики в школе, где мы работали с числами в привычной для нас, десятичной системе счисления – то есть с цифрами от 0 до 9. Но мир логики, если так можно сказать, отличается от нашего, ведь там все значения имеют только два состояния - 0 или 1, отсюда и возникает потребность в специальной математике для работы с логическими выражениями. Эта математика носит название «алгебра логики».
В этой алгебре есть три основных операции – сложение, умножение и отрицание, позволяющих реализовать любые логические функции. Давайте разберемся на примерах для микроконтроллера, где нам может понадобиться каждая из этих операций.
Операция сложения, она же операция дизъюнкции либо логическое ИЛИ. Многие из вас помнят, что в прошлом выпуске, при изучении циклов и условий, мы брали примеры с автобусами и остановкой, давайте снова разберем такой пример – наверное, вы замечали, что в относительно новых автобусах по салону распределены кнопки требования остановки. При нажатии на такую кнопку у водителя на приборной панели загорается лампочка и звучит сигнал требования остановки.
Давайте попробуем реализовать такую же систему на Arduino – возьмем, например, три кнопки и подключим их к микроконтроллеру, а так же добавим в схему светодиод и, при наличии, пьезо-извещатель.
Алгоритм работы такой системы достаточно прост и схож с тем, что мы писали для одной кнопки и светодиода, но, в данном случае возникает одна проблема - у нас не одна кнопка, для которой можно написать условие, а целых три. И при нажатии любой из кнопок у нас должен звучать сигнал и гореть светодиод. Что же делать? Можно, конечно, написать три отдельных условия для контроля каждой из кнопок, но код в таком случае выглядит нагроможденным и при увеличении количества кнопок становится жутко не удобным.
Здесь нам на помощь и приходят логические операции, позволяющие составлять не одиночные условия, как мы это делали раньше, а достаточно гибкие и удобные совмещенные.
В нашей задаче необходимо включить оповещение при срабатывании первой или второй или третьей кнопки и, если вы помните, операция сложения так и называлась – логическое ИЛИ.
Давайте создадим три переменных типа boolean, в которые будем сохранять считанный сигнал от каждой из кнопок, и объединим эти переменные в одном условии, поставив между ними логическое ИЛИ. Эта операция записывается в виде двух вертикальных черточек и, что бы понять логику ее работы, давайте взглянем на так называемую таблицу истинности, где указываются операнды, над которыми совершается операция.
Два первых столбца это возможные значения на входах - например, если бы у нас было две кнопки и между ними мы производили дизъюнкцию. Как видите, при комбинации 00 итогом логического сложения так же будет 0. А вот следующая комбинация - 0 или 1 уже дает на выходе логическую единицу, так же, как и оставшиеся комбинации. Нижняя строка 11 так же выдаст единицу, поскольку мы производим сравнение двух положительных значений.
В итоге мы можем сделать вывод, что логическая операция ИЛИ выдаст единичный результат, если на любом из ее входов появится хоть одна единица. Для нашей системы мы можем составить таблицу из трех колонок и перебрать все возможные нажатия кнопок, логика останется прежней – если существует хоть одна единица – ответ будет равен одному.
Это отлично подходит к нашей задаче, ведь нам как раз и требовалось при нажатии любой из кнопок запускать оповещение, а при отпущенных кнопках ничего не делать. Давайте взглянем на получившийся программный код..
Надеюсь, цикл for, находящийся в теле условия, после прошлого выпуска теперь не вызывает у вас трудностей в понимании. Как видите, при нажатии на любую кнопку условие становится истинным и выполняется цикл for, написанный в теле условия.
Переходим к следующей логической операции – это конъюнкция или логическое И, иначе говоря – умножение. Если предыдущая операция делала условие истинным при любой нажатой кнопке, то операция умножения потребует нажатия сразу всех кнопок и только тогда выдаст нам логическую единицу.
Более наглядно это можно увидеть по таблице истинности. Как можно заметить, если в комбинации присутствует хотя бы один ноль, то вся функция становится равной нулю.
Эта операция записывается в виде двойного амперсанда (&&), и, такой символ - &, по сути, заменяет слово И (от английского and). Таким образом, если вам понадобится сделать условие истинным при одновременно нескольких истинных событиях, то этот оператор то, что нужно.
Это можно увидеть, если заменить в предыдущем коде ИЛИ на И.
Загрузив код, мы увидим, что нажатие одной кнопки никак не влияет на истинность условия и теперь от нас требуется нажать сразу все кнопки.
Также мы можем комбинировать операции сложения и умножения в одной функции. Например, нам необходимо включать оповещение только при одновременном наличии сигнала с 1-й и 2-й кнопки, или со 2-й и 3-й. Тогда условие примет вот такой вид:
Скобками осуществляется разграничение между отдельными условиями и, по сути, сейчас у нас два условия в одном: первое – нажатие 1-й и 2-й кнопки, второе – нажатие 2-й и 3-й кнопки, что бы учесть выполнение одного из этих двух условий мы ставим между ними логическое ИЛИ.
И, наконец, нам осталось разобраться с третьей логической операцией, пожалуй, самой простой из всех – это логическое отрицание или логическое НЕ. Единственная его задача - менять значение переменной или функции на противоположное.
Обозначается операция восклицательным знаком, который ставится впереди переменной или функции. Например, первая переменная кнопки при считывании значения с порта микроконтроллера стала равна нулю, но, добавив впереди нее восклицательный знак, это значение становится обратным – то есть теперь эта связка равна единице.
Когда может понадобиться отрицание? Например, когда в условии нужно проверить не истинность какой-либо функции или переменной, а, наоборот, ее ложность. Но, как вы помните, например, оператор if разрешит нам попасть в тело условия, только если условие в его круглых скобках будет истинно, а не ложно, для ложного значения мы использовали else.
Так вот, что бы условие выполнилось при нормально-ложном значении чего-либо и пригодится отрицание. Допустим, мы хотим выполнить тело условия только если кнопка отпущена, то есть в переменной находится ноль, поэтому к переменной, указанной в условии, мы добавляем восклицательный знак. Теперь при отпущенной кнопке связка переменной и отрицания равна единице и условие выполняется.
Модернизировать наш прошлый алгоритм можно добавив условие, что, одна из кнопок должна быть обязательно отпущена. Иначе условие срабатывает при, например, нажатых первой и второй кнопках, но при этом не учитывает в каком положении находится третья. Указав, что третья кнопка должна быть равна нулю, мы задаем более точное условие срабатывания алгоритма.
Как и в обычной математике, у алгебры логики есть свои законы, советую самостоятельно подробно с ними ознакомиться.
Ну а в качестве домашнего задания, попробуйте добавить к нашей схеме еще пару кнопок и применить свои условия срабатывания оповещения - здесь важно отточить навык использования сразу всех операторов – сложения, умножения и отрицания.
Для тех, кому трудно придумать свои условия, я составил небольшую таблицу зависимостей выходного сигнала от состояния 4 кнопок. Попробуйте реализовать каждое из этих условий:
Так же, для тех, кто не состоит в нашем сообществе Вконтакте, сообщаю, что теперь после каждого выпуска с задержкой в один-два дня будет выкладываться небольшой тест, в котором вы сможете проверить свои остаточные знания по изученному материалу и восполнить возможные пробелы. Тест к предыдущему выпуску можно найти здесь.
Ну а на этом про логические операции, пожалуй, все, не забывайте оценивать материал и писать свои пожелания и замечания, надеюсь, что вам было интересно :) Всем добра!