#7 Эксперимент “Умный замок 2.0”
Это занятие будет посвящено одному из устройств, позволяющих выводить текстово-символьную информацию. Это LCD дисплей. Устройства Arduino чаще всего – автономные устройства, а значит они должны “уметь” своё собственное устройство для вывода необходимой информации. Вспомните, в одном из предыдущих занятий мы уже посылали нужную нам информацию в последовательный порт компьютера и “ловили” её в мониторе порта.
Сегодня мы научимся выводить нужную нам текстовую информацию напрямую на LCD-дисплей и даже соберём полностью автономную версию электронного кодового замка. Итак, наш сегодняшний “подопытный”:
Внешний вид | Основные характеристики |
|
Перед выполнением эксперимента прочтите:
Наше занятие будет разбита на 2 части:
- Вначале мы освоим тонкости работы с LCD дисплеем и установим библиотеку, необходимую для работы с LCD дисплеем, получающим данные по протоколу I2C;
- Вторая часть занятия будет посвящена сборке и программированию нашего электронного кодового замка.
СБОРКА УСТРОЙСТВА НА МАКЕТНОЙ ПЛАТЕ
Нам понадобятся следующие компоненты:
- Arduino Uno;
- USB-кабель для подключения к компьютеру;
- LCD дисплей;
- 4 соединительных провода типа “папа-мама” различных цветов.
Соберите устройство по следующей схеме:
Схема устройства на макетной плате |
Принципиальная схема устройства |
Обратите внимание:
- Порты SDA и SCL находятся в левой части блока цифровых пинов Arduino. Они подписаны с обратной стороны платы;
- Дисплей имеет встроенную подсветку. Для того, чтобы отключить её (это может понадобится в целях энергосбережения, если устройство работает автономно), необходимо выдернуть джемпер, соединяющий пины подсветки и питания. Он находится на плате I2C модуля, впаянного в LCD дисплей;
- кроме этого, яркость подсветки можно отрегулировать вращая специальный подстроечный потенциометр, который находится на I2C плате дисплея.
Установка библиотеки для работы с протоколом I2C
Библиотеки Arduino нужны для того, чтобы значительно упростить работу с тем или иным устройством, подключённым к Arduino. Некоторые (самые востребованные и популярные) библиотеки уже загружены в Arduino IDE по умолчанию, другие же библиотеки (в том числе написанные самими пользователями) необходимо загружать дополнительно. Удобнее всего искать нужные библиотеки в соответствующем разделе Arduino IDE.
- Запустите Arduino IDE;
- Выберите [Скетч] → [Подключить библиотеку] → [Управлять библиотеками]:
- В строке поиска введите “LiquidCrystal I2C” и нажмите [Enter]:
- Выберите библиотеку [LiquidCrystal I2C by Frank de Brabander] и нажмите [Установка].
После установки эта библиотека добавиться в раздел с библиотеками Arduino IDE. Для того, чтобы вызвать данную библиотеку и использовать её функции, в самом начале скетча необходимо прописать команду [#include <LiquidCrystal_I2C.h>].
ПРОГРАММИРОВАНИЕ
В качестве примера, скопируйте и загрузите в Arduino следующий скетч:
#include <LiquidCrystal_I2C.h> // подключаем библиотеку для дисплея LiquidCrystal_I2C lcd(0x27,16,2); // установки нашего дисплея // обратите внимание, если после загрузки скетча в плату, у вас наблюдаются // проблемы с выводом информации, попробуйте вписать в скобках значение // 0x20 или 0x3F void setup() { lcd.init(); // инициализируем дисплей lcd.backlight(); // инициализируем подсветку lcd.setCursor(0, 0); // помещаем курсор на первую ячейку 2-й строки lcd.print("Hello, world I2C!"); // выводим надпись "Hello, world I2C!" } void loop() { lcd.setCursor(0, 1); // помещаем курсор на первую ячейку 2-й строки lcd.print(millis() / 1000); // выводим количество секунд работы Arduino lcd.setCursor(4,1); // помещаем курсор на 5-й символ 2-й строки lcd.print("display 16x2"); //выводим надпись "display 16x2" }
Пояснения к скетчу:
- Наш дисплей имеет 2 строки по 16 ячеек (сегментов) в каждой. Эти цифры мы и указываем в параметрах установки дисплея;
- Нумерация строк и сегментов начинается с нуля, т.е. первая ячейка первой строки имеет адрес [0, 0], а 7-я ячейка второй строки адрес [6,1];
- Если после загрузки скетча ваш дисплей не отображает информацию, попробуйте поменять значение [0x27] в установках дисплея на [0x20] или [0x3F];
- Если вы видите, что информация отображается на дисплее, но она плохо читается из-за недостаточно или избыточной яркости подсветки, вы можете отрегулировать её с помощью потенциометра на плате I2C, впаянной в дисплей.
ЗАДАНИЯ ДЛЯ САМОСТОЯТЕЛЬНОГО ВЫПОЛНЕНИЯ
Задание 1:
Подключите к плате Arduino дополнительно датчик освещённости (фоторезистор) по схеме, показанной в эксперименте “Автоматический светильник” и выведите на ваш дисплей данные с этого датчика.
Задание 2:
Подключите к плате Arduino тактовую кнопку по схеме со стягивающим резистором, показанной в памятки “Кнопка“. Запрограммируйте простейший секундомер, способный измерять промежутки времени с точностью до 1/10 секунды. При нажатии на кнопку, секундомер должен начинать отсчёт времени с нуля.
Задание 3*:
Усовершенствуйте код предыдущего скетча так, чтобы при нажатии на кнопку, секундомер не только запускал счёт времени с нуля, но и выводил рядом последний результат замеров времени.
ПОДКЛЮЧЕНИЕ МАТРИЧНОЙ КЛАВИАТУРЫ
Зачастую, для управления каким-либо устройством, недостаточно только одной кнопки. Поэтому, в такие устройства обычно монтируют сразу целый клавиатурный блок, размером 3х4 или 4х4, т.е. содержащий или 12 или 16 кнопок. Подсчитав количество кнопок, становится понятно, что у Arduino просто не хватит пинов для того, чтобы подключить каждую из этих кнопок по отдельности. Именно поэтому, в таких случаях принято использовать т.н. матричный клавиатуры, т.е. набор кнопок, соединённых по матричному принципу.
Внешний вид | Основные характеристики |
|
СБОРКА УСТРОЙСТВА НА МАКЕТНОЙ ПЛАТЕ
Нам понадобятся следующие компоненты:
- Arduino Uno;
- USB-кабель для подключения к компьютеру;
- Матричная клавиатура;
- 8 соединительных проводов типа “папа-мама” различных цветов.
Соберите устройство по следующей схеме:
Схема устройства на макетной плате |
Принципиальная схема устройства |
Порядок подключения пинов матричной клавиатуры к пинам Arduino не имеет принципиального значения, т.к. позже мы укажем параметры нашего подключения прямо внутри скетча. Для того, чтобы мы могли удобно работать с клавиатурой, нам потребуется библиотека [Keypad]. Давайте установим её:
- Выберите [Скетч] → [Подключить библиотеку] → [Управлять библиотеками]:
- В строке поиска введите “Keypad” и нажмите [Enter]:
- Найдите и установите библиотеку [Keypad by Mark Stanley, Alexander Brevig].
ПРОГРАММИРОВАНИЕ
После установки, данную библиотеку можно подключить с помощью команды [#include <Keypad.h>]. Давайте изменим предыдущий скетч, включив в него команды для вывода на наш дисплей символов, привязанных к клавишам матричной клавиатуры:
#include <Keypad.h> // подключаем библиотеку для нашей клавиатуры #include <LiquidCrystal_I2C.h> // подключаем библиотеку для дисплея LiquidCrystal_I2C lcd(0x27,16,2); // установки нашего дисплея // обратите внимание, если после загрузки скетча в плату, у вас наблюдаются // проблемы с выводом информации, попробуйте вписать в скобках значение // 0x20 или 0x3F const byte ROWS = 4; // Задаём количество строк const byte COLS = 4; // Задаём количество столбцов char keys[ROWS][COLS] = { // создаём массив символов для каждой из кнопок {'1','2','3','*'}, // здесь мы располагаем {'4','5','6','/'}, // названия наших клавиш, {'7','8','9','-'}, // как на клавиатуре, {'C','0','=','+'} // для удобства пользования }; byte rowPins[ROWS] = { 5, 4, 3, 2 }; // Указываем номера пинов к которым подключены строки R1, R2, R3, R4 byte colPins[COLS] = { 6, 7, 8 ,9}; // Указываем номера пинов к которым подключены строки C1, C2, C3, C4 Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // инициализируем нашу клавиатуру void setup() { lcd.init(); // инициализируем дисплей lcd.backlight(); // инициализируем подсветку } void loop() { char key = kpd.getKey(); // помещаем символ нажатой клавиши в переменную key if (key != NO_KEY){ // проверяем нажата ли клавиша на клавиатуре lcd.setCursor(0, 0); // помещаем курсор на первую ячейку 1-й строки lcd.print(key); // выводим на экран символ нажатой клавиши } }
Как видите, управлять даже сложными устройствами с помощью Arduino совсем несложно, если при этом использовать библиотеки. Обычно, вместе с каждой библиотекой идёт набор примеров, демонстрирующих различные возможности данной библиотеки. Найти эти примеры можно выбрав [Файл] → [Примеры] → [Название библиотеки].
Давайте попробуем попробовать возможности использования нашей матричной клавиатуры на примере одного из старых экспериментов. Попробуем переписать код эксперимента “Умный замок” таким образом, чтобы наш замок открывался только тогда, когда с клавиатуры будет введён корректный код из 4-х цифр.
Эксперимент “Электронный замок”
- Подключите к плате Arduino сервопривод по схеме, показанной в эксперименте “Умный замок“;
- В качестве управляющего пина используйте 10-й пин платы;
Рассмотрим пример скетча, который позволит управлять нашим замком:
#include <Keypad.h> // подключаем библиотеку для нашей клавиатуры #include <LiquidCrystal_I2C.h> // подключаем библиотеку для дисплея #include <Servo.h>; // подключаем библиотеку для управления сервоприводом LiquidCrystal_I2C lcd(0x27,16,2); // установки нашего дисплея // обратите внимание, если после загрузки скетча в плату, у вас наблюдаются // проблемы с выводом информации, попробуйте вписать в скобках значение // 0x20 или 0x3F const byte ROWS = 4; // Задаём количество строк const byte COLS = 4; // Задаём количество столбцов char keys[ROWS][COLS] = { // создаём массив символов для каждой из кнопок {'1','2','3','*'}, // здесь мы располагаем {'4','5','6','/'}, // названия наших клавиш, {'7','8','9','-'}, // как на клавиатуре, {'C','0','=','+'} // для удобства пользования }; byte rowPins[ROWS] = { 5, 4, 3, 2 }; // Указываем номера пинов к которым подключены строки R1, R2, R3, R4 byte colPins[COLS] = { 6, 7, 8 ,9}; // Указываем номера пинов к которым подключены строки C1, C2, C3, C4 Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // инициализируем нашу клавиатуру Servo my_servo; // Объявляем переменную типа Servo String get_pass; // объявляем переменную для хранения введённого пароля String save_pass="6586"; // это наш пароль для открытия замка void setup() { lcd.init(); // инициализируем дисплей lcd.backlight(); // инициализируем подсветку lcd.setCursor(0,0); // помещаем курсор на первую ячейку 1-й строки lcd.print("____"); // обозначаем место для вводимого пароля my_servo.attach(10); // инициализируем сервопривод на 10-м пине my_servo.write(0); // поворачиваем вал в положение 0 градусов (закрываем замок) delay(1000); // даём время, для того, чтобы вал сервопривода успел провернуться lcd.setCursor(0,1); // помещаем курсор на первую ячейку 2-й строки lcd.print("Lock"); // выводим на экран сообщение о том, что замок закрыт } void loop() { char key = kpd.getKey(); // помещаем символ нажатой клавиши в переменную key if (key != NO_KEY){ // проверяем нажата ли клавиша на клавиатуре get_pass=get_pass+key; // склеиваем введённые символы if (get_pass.length()>4) // если введено больше 4-х символов { get_pass=""; // вводимый пароль обнуляется lcd.setCursor(0,0); // помещаем курсор на первую ячейку 1-й строки lcd.print("____"); // обозначаем место для вводимого пароля } lcd.setCursor(0,0); // помещаем курсор на первую ячейку 1-й строки lcd.print(get_pass); // выводим на экран введённые цифры } if (get_pass==save_pass){ my_servo.write(180); // открываем замок lcd.setCursor(0,1); // помещаем курсор на первую ячейку 2-й строки lcd.print("Open"); // выводим на экран сообщение об открытии замка lcd.setCursor(0,0); // помещаем курсор на первую ячейку 1-й строки lcd.print("____"); // скрываем введённый пароль delay(5000); // ждём 5 секунд my_servo.write(0); // закрываем замок lcd.setCursor(0,1); // помещаем курсор на первую ячейку 2-й строки lcd.print("Lock"); // выводим на экран сообщение о закрытии замка delay(1000); // даём время сервоприводу провернуть вал get_pass=""; // обнуляем вводимый пароль } }
Все нужные комментарии приведены внутри скетча. Теперь мы умеем работать с матричной клавиатурой и выводить нужные нам данные на LCD дисплей!
ЗАДАНИЯ ДЛЯ САМОСТОЯТЕЛЬНОГО ВЫПОЛНЕНИЯ
Задание 1:
Добавьте в схему 2 светодиода красного и зелёного цветов. Зажигайте зелёный светодиод и гасите красный, когда замок открыт. Зажигайте красный светодиод и гасите зелёный, когда замок закрыт.
Задание 2:
Измените код управляющего скетча таким образом, чтобы при открытии и закрытии замка в com-порт посылалась информация о состоянии замка, т.е. “Замок открыт” и “Замок закрыт”.
Задание 3*:
Дополните код управляющего скетча таким образом, чтобы наш замок открывался автоматически при возникновении пожара, т.е. в схему нужно добавить фоторезистор и открывать замок не только с помощью пароля, но и когда с фоторезистора будет приходить высокий сигнал. Пожар можно имитировать с помощью фонарика на мобильном телефоне.