Skip to contentSkip 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, попробовать все функции из документации
  • Создать несколько символов и вывести их
  • Оптимизировать последний пример: не очищать дисплей и не выводить лейбл при клике, менять только значение

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

Похожие примеры
17 Комментариев
  • Может кто-нибудь объяснить, почему дисплей включается, но не выводит информацию?

    Использовал скетч из примера; библиотеку скачал с по этой ссылке https://github.com/johnrickman/LiquidCrystal_I2C и правильно установил; проверил пины подключения; попробовал разные адреса дисплея. В чем еще может быть проблема?

    • После почти дня ковыряния заработало! Скорее всего дело было в кабеле или в порте или в них обоих. Начал пошагово как в инструкции Алекса Гайвера. Поставил другой кабель в другой порт, попробовал запустить саму Ардуину нано одну, чтобы изменить скорость мигания светодиода. С новым кабелем и портом он ЗАМИГАЛ!!!! После этого все пошло и с экраном нормально. Бедолага Гайвер, чтобы дойти до таких подробностей разжовывания сколько ж он натерпелся. Спасибо тебе, Алекс Гайвер.

    • Алексей, мой дисплей 2004 ничего не отображал, пока я не покрутил подстроечный резистор на I2C модуле, который меняет яркость символов.

  • Сзади на модуле дисплея есть синяя крутелка под крестовидную отвертку. Подкрутите контрастность там. Сам постарел на 5 лет пока дотумкал)

    • Не помогает крутилка. Появляются 16 квадратиков в одном из максимальных положений крутилки. Текста, символов, ничего другого нет

      • Я пробовал менять. Дисплей i2c. Бесполезно. Алекс подскажи что делать. У меня выводит 16 квадратиков в верхней строке(крутилку крутил)!

      • И у меня такая же история – 16 квадратов и всё. Плата подключена, прошивка заливается, дисплей подключен по схеме, адреса менял

      • надо устанавливать контраст меньше что бы не было квадратов, тогда будет виден текст, а когда его увидишь поставь контраст на такое значение что было бы не было виждно квадраты, но текст был максимально ярким

      • Нашел причину – i2c модуль экранчика висит на адресе 0x26. Алекс, добавь 0х26 к 0х27 и 0х3F.

  • Мне дисплей ардуину чуть не убил. При подключении дисплея на макетке – ардуино выключалась, а когда подкинул питания по юсб – вообще дым пошел. Найс

  • Помогите решить проблему😌 использую кириллицу и происходит “пляска” символов на lcd 2004a. Другой дисплей не пробовал.

  • такая проблема, после загрузки скетча на экран выводит только первые буквы, искал другие библиотеки, нашел вроде бы, но подключить не смог. помогите кто сталкивался

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *