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 символов, это английские буквы, стандартные символы и китайские буквы. Стандартные символы, такие как [email protected]#$%&()* и так далее выводятся через 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, попробовать все функции из документации
  • Создать несколько символов и вывести их
  • Оптимизировать последний пример: не очищать дисплей и не выводить лейбл при клике, менять только значение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • тоже хороший код:

    #include //подключаем библиотеку для работы с жидкокристаллическим экраном.
    LiquidCrystal lcd(13,12,11,10,9,8); //объявляем объект для управления дисплеем. 13,12,11,10,9,8-это порты куда подключен экран(у вас могут быть другие…)
    void setup() {
    lcd.begin(16,2); //начинаем работу с LCD экраном. сообщаем сколько строк и столбцов у экрана.
    lcd.print(“”); //вводим любой текст ПРИМЕР: “” скобки ставить обязательно если это не переменная ПРИМЕР: lcd.print(serial);
    }

    void loop() {
    //можете продолжить
    программу…
    }

  • Выводились только первые буквы слов. Полез смотреть библиотеку – её в папке с библами не оказалось. Нашёл её в папке пользователя/Документы и скопировал в каталог Ардуино. Всё заработало.

  • здравствуйте, хочу задать вопрос.как можно с помощью кнопок листать вниз(мне просто шпору по истории надо сделать а то что у гайвера есть у меня нет модулей некоторых )?

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

Ваш адрес email не будет опубликован.