Урок 1.9. ЖК-дисплей. Датчик влажности и температуры

Базовый курс "Программирование микроконтроллеров"
Модуль 1. Введение в Arduino. Работа с цифровым и аналоговым сигналом

ЖК-дисплей

Все давно привыкли, что у каждого электронного устройства есть экран, с помощью которого оно дает человеку всякую полезную информацию. MP3-плеер показывает название играемого трека, пульт квадрокоптера отображает полетную телеметрию, даже стиральная машина выводит на дисплей время до конца стирки, а на смартфоне вообще размещается целый рабочий стол персонального компьютера!

Скорее всего, вашему очередному устройству тоже не помешает какой-нибудь небольшой дисплейчик 🙂 Попробуем сделать простые электронные часы! А в качестве табло используем распространенный и дешевый символьный жидкокристаллический дисплей 1602. Вот прямо такой, как на картинке:

 

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

Для удобства, мы будем использовать дисплей с интерфейсом I2C, так как они сейчас довольно широко распространены и не требуют много пинов микроконтроллера для работы. Такие дисплеи отличаются наличием небольшой платы с микроконтроллером на обратной стороне ЖК-дисплея.

Схема сборки и программа для вывода символов на дисплей

Соберем схему с дисплеем и попробуем вывести на него символы. Для работы с данным дисплеем нам потребуется библиотека. Для того, что бы её подключить нам потребуется в панели иконок быстрого доступа кликнуть по иконке “Управление библиотеками”, ввести в строку поиска LiquidCrystal I2C и установить библиотеку от Frank de Barbader.

Напишем простой код для проверки работы дисплея и выведем на него какое-то слово или фразу:

#include <Wire.h>                    //  Подключаем библиотеку для работы с шиной I2C
#include <LiquidCrystal_I2C.h>       //  Подключаем библиотеку для работы с LCD дисплеем по шине I2C
LiquidCrystal_I2C lcd(0x27, 16, 2);  //  Объявляем  объект библиотеки, указывая параметры дисплея 
// (адрес I2C = 0x27, количество столбцов = 16, количество строк = 2)
// Если надпись не появилась, замените адрес 0x27 на 0x3F или подкрутите потенциометр, на обратной стороне экрана void setup() { lcd.init(); // Инициируем работу с LCD дисплеем lcd.backlight(); // Включаем подсветку LCD дисплея lcd.setCursor(0, 0); // Устанавливаем курсор в позицию (0 столбец, 0 строка) lcd.print("Hello World!"); // Выводим текст "LCD", начиная с установленной позиции курсора } void loop() {}

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

Напишем простой пример – это будет бегущая строка:

#include <Wire.h>                    //  Подключаем библиотеку для работы с шиной I2C
#include <LiquidCrystal_I2C.h>       //  Подключаем библиотеку для работы с LCD дисплеем по шине I2C
LiquidCrystal_I2C lcd(0x27, 16, 2);  //  Объявляем  объект библиотеки, указывая параметры дисплея 
// (адрес I2C = 0x27, количество столбцов = 16, количество строк = 2)
// Если надпись не появилась, замените адрес 0x27 на 0x3F или подкрутите потенциометр, на обратной стороне экрана void setup() { lcd.init(); // Инициируем работу с LCD дисплеем lcd.backlight(); // Включаем подсветку LCD дисплея }
void loop() {
  for (int i = 16; i >= 0; i--) {
    lcd.clear();
    lcd.setCursor(i, 0);
    lcd.print("PRODAM GARAGE");
    delay(500);
  }
  delay(1000);
  for (int i = 16; i >= 0; i--) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("PRODAM GARAGE");
    lcd.setCursor(i, 1);
    lcd.print("8800123654789");
    delay(500);
  }
  delay(3000);
}

Теперь выведем на экран надпись по буквам:

#include <Wire.h>                    //  Подключаем библиотеку для работы с шиной I2C
#include <LiquidCrystal_I2C.h>       //  Подключаем библиотеку для работы с LCD дисплеем по шине I2C
LiquidCrystal_I2C lcd(0x27, 16, 2);  //  Объявляем  объект библиотеки, указывая параметры дисплея 
                                     //  (адрес I2C = 0x27, количество столбцов = 16, количество строк = 2)
//  Если надпись не появилась, замените адрес 0x27 на 0x3F или подкрутите потенциометр, на обратной стороне экрана
char s1[] = "LoL KeK";
char s2[] = "CHABUREK";

void setup() {
  lcd.init();       //  Инициируем работу с LCD дисплеем
  lcd.backlight();  //  Включаем подсветку LCD дисплея
}

void loop() {
  lcd.setCursor(1, 0);
  for (int i = 0; i < strlen(s1); i++) {
    lcd.print(s1[i]);
    delay(200);
  }
  lcd.setCursor(4, 1);
  for (int i = 0; i < strlen(s2); i++) {
    lcd.print(s2[i]);
    delay(200);
  }
  delay(2000);
  lcd.clear();
  delay(1000);
}

Обратите внимание: в данном примере мы использовали массив символов char, по этому работать со строками мы можем точно так же, как с любым массивом.

В памяти дисплея содержится 255 символов, это английские буквы, стандартные символы и китайские буквы их можно вывести по их коду при помощи команды lcd.write().

Так же существуют дисплеи с кириллическими символами вместо китайских.

Создание своих символов

Библиотека поддерживает создание “своих” дополнительных символов размером 5х7 точек, можно воспользоваться онлайн-генератором кодов символов.

Дисплей имеет 8 ячеек под сторонние символы, добавляются они при помощи lcd.createChar(номер, массив):
номер
– от 0 до 7, это порядковый номер символа;
массив – имя массива с данными, которое мы создали для символа.

Выводятся символы при помощи write(номер).

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

Код программы будет следующий:

#include <Wire.h>                    //  Подключаем библиотеку для работы с шиной I2C
#include <LiquidCrystal_I2C.h>       //  Подключаем библиотеку для работы с LCD дисплеем по шине I2C
LiquidCrystal_I2C lcd(0x27, 16, 2);  //  Объявляем  объект библиотеки, указывая параметры дисплея 
// (адрес I2C = 0x27, количество столбцов = 16, количество строк = 2)
// Если надпись не появилась, замените адрес 0x27 на 0x3F или подкрутите потенциометр, на обратной стороне экрана
byte smile[8] = { B00000,
                  B01010,
                  B01010,
                  B00000,
                  B00100,
                  B10001,
                  B01010,
                  B00100 };

void setup() {
  lcd.init();       //  Инициируем работу с LCD дисплеем
  lcd.backlight();  //  Включаем подсветку LCD дисплея
  lcd.createChar(0, smile);
}

void loop() {
  lcd.setCursor(1, 0);
  lcd.write(smile);
}

Информация к размышлению

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

Во-первых, многие символы кириллицы совпадают с латинскими буквами, а во-вторых обратимся к частоту употребления русских букв в словах:

И напоследок: вряд ли в вашем проекте понадобиться выводить слова содержащие все буквы русского алфавита. 😉

Датчик влажности температуры DHT

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

Внутри корпуса DHT размещается резистивный элемент, чувствительный к изменению относительной влажности, термистор типа NTC, а также микросхема для передачи показаний этих двух датчиков по цифровому протоколу 1-wire.


Такие датчики бывают двух типов:

Датчик DHT11

Потребляемый ток – 2,5 мА (максимальное значение при преобразовании данных);

Измеряет влажность в диапазоне от 20% до 80%. Погрешность может составлять до 5%;

Применяется при измерении температуры в интервале от 0 до 50 градусов (точность – 2%)

Габаритные размеры: 15,5 мм длина; 12 мм широта; 5,5 мм высота;

Питание – от 3 до 5 Вольт;

Одно измерение в единицу времени (секунду). То есть, частота составляет 1 Гц.

Датчик DHT22

Питание – от 3 до 5 Вольт;

Максимальный ток при преобразовании – 2,5 мА;

Способен измерять влажность в интервале от 0% до 100%. Точность измерений колеблется от 2% до 5%;

Минимальная измеряемая температура – минус 40, максимальная – 125 градусов по Цельсию (точность измерений – 0,5);

Устройство способно совершать одно измерение за 2 секунд. Частота – до 0,5 ГЦ;

Габаритные размеры: 15,1 мм длина; 25 мм широта; 5,5 мм высота.

Схема подключения и программа проекта "Метеостанция"

Предлагаем собрать проект портативной метеостанции. Для этого соберите следующую схему:

Для работы с данным датчиком нам понадобится библиотека. Действуем по знакомой схеме и в панели быстрого доступа переходим в “управление библиотеками”. Нам нужна библиотека DHT sensor library от Adafruit.

Для начала выведем показания датчика в монитор порта:

// подключаем необходимые библиотеки
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 3           // пин подключения датчика
#define DHTTYPE DHT22      // тип датчика
DHT dht(DHTPIN, DHTTYPE);  // создаем объект датчика  
                           // влажности и температуры
void setup() {
  Serial.begin(9600);
  dht.begin();  // инициализация датчика
}

Добавим уже известный нам код для работы с экраном:

// подключаем необходимые библиотеки
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include <LiquidCrystal_I2C.h>  //  Подключаем библиотеку для работы с LCD дисплеем по шине I2C
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define DHTPIN 3           // пин подключения датчика
#define DHTTYPE DHT22      // тип датчика
DHT dht(DHTPIN, DHTTYPE);  // создаем объект датчика влажности и температуры
void setup() {
  Serial.begin(9600);
  dht.begin();      // инициализация датчика
  lcd.init();       //  Инициируем работу с LCD дисплеем
  lcd.backlight();  //  Включаем подсветку LCD дисплея
}

void loop() {
  // Ожидание между измерениями
  delay(2000);
  lcd.clear();
  float h = dht.readHumidity();     // считываем влажность
  float t = dht.readTemperature();  // считываем температуру
  lcd.setCursor(0, 0);
  lcd.print("T = " + String(t));
  lcd.setCursor(0, 1);
  lcd.print("H = " + String(h));
}