Skip to content Skip to main navigation Skip to footer

Arduino и дисплей LCD1602

Описание


Классический LCD дисплей, раньше такие стояли в кассовых аппаратах и офисной технике.

  • Бывают разного размера, самый популярный – 1602 (16 столбцов 2 строки), есть ещё 2004, 0802 и другие. В наборе идёт 1602.
  • Снабжён отключаемой светодиодной подсветкой. Существует несколько вариантов, например синий фон белые буквы, зелёный фон чёрные буквы, чёрный фон белые буквы и проч. В наборе идёт с зелёным фоном и чёрными буквами.
  • Сам по себе требует для подключения 6 цифровых пинов, но китайцы выпускают переходник на шину I2C на базе PCF8574, что сильно упрощает подключение и экономит пины. В наборе идёт дисплей с припаянным переходником.
  • На переходнике также распаян потенциометр настройки контрастности (синий параллелепипед с крутилкой под крестовую отвёртку). В зависимости от напряжения питания нужно вручную подстроить контрастность. Например при питании платы от USB на пин 5V приходит ~4.7V, а при внешнем питании от адаптера – 5.0V. Контрастность символов на дисплее будет разной!
  • Переходник может иметь разный адрес для указания в программе: 0х26, 0x27 или 0x3F, об этом ниже.

Подключение


Дисплей подключается по шине I2C, выведенной на пины:

  • Arduino: SDA – A4, SCL – A5
  • Wemos: SDA – D2, SCL – D1
  • Питание: 5V в обоих случаях

Библиотеки


Для этого дисплея существует несколько библиотек, я рекомендую LiquidCrystal_I2C от Frank de Brabander. Библиотека идёт в архиве к набору, а также её можно скачать через менеджер библиотек по названию LiquidCrystal_I2C и имени автора. Репозиторий на GitHub.

print(data);          // вывести (любой тип данных)
setCursor(x, y);      // курсор на (столбец, строка)
clear();              // очистить дисплей
home();               // аналогично setCursor(0, 0)
noDisplay();          // отключить отображение
display();            // включить отображение
blink();              // мигать курсором на его текущей позиции
noBlink();            // не мигать
cursor();             // отобразить курсор
noCursor();           // скрыть курсор
scrollDisplayLeft();  // подвинуть экран влево на 1 столбец
scrollDisplayRight(); // подвинуть экран вправо на 1 столбец
backlight();          // включить подсветку
noBacklight();        // выключить подсветку
createChar(uint8_t, uint8_t[]);                     // создать символ
createChar(uint8_t location, const char *charmap);  // создать символ

Пример вывода


При первой работе с дисплеем нужно настроить контраст и определиться с адресом:

  • Прошить пример “Демо”
  • Если дисплей показывает чёрные прямоугольники или пустой экран – крутим контраст
  • Если кроме чёрных прямоугольников и пустого экрана ничего не видно – меняем адрес в программе: 0х26, 0x27 и 0x3F
  • Снова крутим контраст, должно заработать
  • Если не работает – проверяем подключение и повторяем сначала
  • Примечание: в наборе должны идти дисплеи с адресом 0x27, но может зависеть от партии!
Демо
// базовый пример инициализации и вывода текста
#include <LiquidCrystal_I2C.h>  // подключаем библу

// адрес дисплея 0x3f или 0x27
// размер дисплея 16x2 (поддерживаются и другие, например 20x4)
LiquidCrystal_I2C lcd(0x27, 16, 2);  // адрес, столбцов, строк

void setup() {
  lcd.init();           // инициализация
  lcd.backlight();      // включить подсветку  
  lcd.setCursor(1, 0);  // столбец 1 строка 0
  lcd.print("Hello, world!");
  lcd.setCursor(4, 1);  // столбец 4 строка 1
  lcd.print("GyverKIT");
}

void loop() {
}
Выводим по буквам
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  lcd.init();           // инициализация
  lcd.backlight();      // включить подсветку  

  // строки для вывода
  char s1[] = "Hello, world!";
  char s2[] = "GyverKIT";

  lcd.setCursor(1, 0);
  for (int i = 0; i < strlen(s1); i++) {
    lcd.print(s1[i]);
    delay(100);
  }

  lcd.setCursor(4, 1);
  for (int i = 0; i < strlen(s2); i++) {
    lcd.print(s2[i]);
    delay(100);
  }
}

void loop() {
}

Символы дисплея


В памяти дисплея содержится 255 символов, это английские буквы, стандартные символы и китайские буквы. Стандартные символы, такие как !@#$%&()* и так далее выводятся через print(), остальные можно вывести по их коду при помощи write():

Из интересных:

  • Стрелка вправо – 126
  • Стрелка влево – 127
  • Символ градуса – 223
  • Прямоугольник – 255
Пример
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  lcd.init();           // инициализация
  lcd.backlight();      // включить подсветку

  // выводим стрелочку, надпись temp, число и градус
  lcd.write(126);
  lcd.print("Temp: ");
  lcd.print(25.6);
  lcd.write(223); 
}

void loop() {
}

Свои символы


Библиотека поддерживает создание “своих” дополнительных символов размером 5х7 точек, можно воспользоваться онлайн-генератором кодов символов – ссылка. Для компактности рекомендую переключить его в HEX. Вот так будет выглядеть “символ” крестик: byte myX[] = {0x00, 0x00, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x00};

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

Важный момент: после вызова createChar сбрасывается позиция вывода текста, нужно обязательно вызвать setCursor!

Пример
// выводим кастомные символы

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

byte bell[]  = {0x4, 0xe, 0xe, 0xe, 0x1f, 0x0, 0x4};
byte note[]  = {0x2, 0x3, 0x2, 0xe, 0x1e, 0xc, 0x0};
byte clock[] = {0x0, 0xe, 0x15, 0x17, 0x11, 0xe, 0x0};
byte heart[] = {0x0, 0xa, 0x1f, 0x1f, 0xe, 0x4, 0x0};
byte duck[]  = {0x0, 0xc, 0x1d, 0xf, 0xf, 0x6, 0x0};
byte check[] = {0x0, 0x1, 0x3, 0x16, 0x1c, 0x8, 0x0};
byte cross[] = {0x0, 0x1b, 0xe, 0x4, 0xe, 0x1b, 0x0};
byte retarrow[] = {0x1, 0x1, 0x5, 0x9, 0x1f, 0x8, 0x4};

void setup() {
  lcd.init();           // инициализация
  lcd.backlight();      // включить подсветку

  // загружаем все сразу
  lcd.createChar(0, bell);
  lcd.createChar(1, note);
  lcd.createChar(2, clock);
  lcd.createChar(3, heart);
  lcd.createChar(4, duck);
  lcd.createChar(5, check);
  lcd.createChar(6, cross);
  lcd.createChar(7, retarrow);

  // выводим для примера все
  lcd.home();
  lcd.write(0);
  lcd.write(1);
  lcd.write(2);
  lcd.write(3);
  lcd.write(4);
  lcd.write(5);
  lcd.write(6);
  lcd.write(7);
}

void loop() {
}

Важная информация по дисплеям


Данная информация относится ко всем дисплеям.

  • Вывод данных на дисплей занимает время, поэтому выводить нужно либо по таймеру, либо по факту изменения данных.
  • Очищать дисплей полностью не всегда целесообразно, иногда достаточно вывести новые значения поверх старых, либо частично очистить “пробелами”.

Уроки по таймерам:

Рассмотрим два примера.

Выводим значение с потенциометра

Урок по потенциометрам читай здесь.

// оптимально выводим значение с потенциометра по таймеру
// текстовый лейбл не выводим, дисплей не очищаем
// потенциометр подключен на A0
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  lcd.init();           // инициализация
  lcd.backlight();      // включить подсветку
  lcd.home();
  lcd.print("Pot. val: ");
}

void loop() {
  static uint32_t tmr;
  // таймер на 10 раз в секунду
  if (millis() - tmr >= 100) {
    tmr = millis();
    lcd.setCursor(10, 0);
    lcd.print(analogRead(0));
    lcd.print("   ");
  }
}
Выводим счётчик от кнопки

Урок по кнопкам читай здесь.

// выводим счётчик нажатий по событию
#include <EncButton.h>
EncButton<EB_TICK, 3> btn(INPUT_PULLUP);  // кнопка на D3

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  lcd.init();           // инициализация
  lcd.backlight();      // включить подсветку
}

void loop() {
  btn.tick();
  if (btn.isClick()) {
    static int count = 0;
    count++;

    // очищаем и выводим текст и значение
    lcd.home();
    lcd.clear();
    lcd.print("Counter: ");
    lcd.print(count);
  }
}

Вывод на русском языке


Данный дисплей работает следующим образом: шрифт (буквы, цифры, символы) зашит в память контроллера дисплея, поэтому язык определяется моделью контроллера. Самые распространённые – с английским и китайским, как в табличке выше. Есть дисплеи с кириллицей (вместо китайского), но они сильно дороже. Также у нас есть 8 ячеек для хранения своих символов, и с их помощью можно вполне организовать вывод на другом языке. Что касается русского – большая часть букв совпадает по написанию, и это сильно упрощает задачу. Есть готовые библиотеки, где это уже реализовано, например LCD_1602_RUS_ALL от ssilver2007. Библиотека поддерживает также украинский язык для LCD1602. Пример:

#define _LCD_TYPE 1  // для работы с I2C дисплеями
#include <LCD_1602_RUS_ALL.h>
LCD_1602_RUS lcd(0x27, 16, 2);

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Привет!");
}

void loop() {
}

Домашнее задание


  • Освоить библиотеку LiquidCrystal_I2C, попробовать все функции из документации
  • Создать несколько символов и вывести их
  • Оптимизировать последний пример: не очищать дисплей и не выводить лейбл при клике, менять только значение

Полезный пример?

Похожие примеры
Подписаться
Уведомить о
37 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии