Заполучил я тут от хорошего магазина Чип Резистор очередной девайс для изучения и применения в полезных устройствах. Сей девайс оказался заточен для управления ЖК дисплеем под управлением контроллера HD44780, в 4-х битном режиме. Для этой цели на плате установлена микросхема , которая является преобразователем шины I2C в параллельный 8 битный порт.

Плата разведена таким образом, чтобы ее можно было сразу скрестить с ЖК дисплеем. На вход подается питание и линии I2C. На плате сразу установлены подтягивающие резисторы на линиях SCL и SDA, потенциометр для регулировки контрастности и питание самого дисплея.

Джампер справа включает/отключает подсветку. Далее вооружившись тестером была составлена следующая табличка. После изучения модуля было выявлено что P3 управляет подсветкой. Если джампер установлен, то 1 включает подсветку, а 0 выключает. При снятом джампере подсветка всегда выключена. Далее было принято решение дополнить библиотеку axlib функциями для работы с шиной I2C(программная реализация) и функциями для управления микросхемой PCF8574. В двух словах как работает модуль. Для того чтобы вывести параллельно байт, для этого нужно послать в шину I2C адрес микросхемы (по умолчанию он равен 0x4E. Так же можно менять адрес методом впаивания перемычек на плате и меняя значение трех младших разрядов адреса), затем после получения ACK посылается байт данных. После того как микросхема отвечает ACK, байт появляется на параллельном порту микросхемы. Для управления ЖК дисплеем я взял функции из библиотеки axlib и немного переделал их для работы с шиной I2C. #include #include #include #include #define ADD 0x4E // Адрес микросхемы /* LCD Микросхема RS P0 RW P1 EN P2 D4 P4 D5 P5 D6 P6 D7 P7 На ножке P3 подключени подсветка. 1 вкл, 0 выкл. */ // Вывод данных com |= 0x04; // Е в единицу pcf8574_byte_out(com, ADD); // Вывод данных com &= 0xFB; // Е в ноль pcf8574_byte_out(com, ADD); // Вывод данных } void init(void) { _delay_ms(30); com(0x30); _delay_us(40); com(0x30); // Переход в 4-х битный режим _delay_us(40); // Задержка для выполнения команды com(0x30); // Переход в 4-х битный режим _delay_us(40); // Задержка для выполнения команды com(0x20); // Переход в 4-х битный режим _delay_us(40); // Задержка для выполнения команды com(0x20); // Установка параметров com(0x80); // Установка параметров com(0x00); // Выключаем дисплей com(0x80); // Выключаем дисплей com(0x00); // Очищаем дисплей com(0x10); // Очищаем дисплей com(0x00); com(0x60); // Устанавливаем режим ввода данных com(0x00); com(0xC0); // Включаем дисплей с выбранным курсором } void char_out(BYTE data) { BYTE data_h = ((data & 0xF0) + 0x09); BYTE data_l = ((data // Передача старших 4 бит data_h |= 0x04; pcf8574_byte_out(data_h, ADD); // Передача старших 4 бит // Передача старших 4 бит // Передача младших 4 бит // Передача младших 4 бит // Передача младших 4 бит } void str_out(BYTE *str) { while((*str) != "\0") { char_out(*str); str++; } } int main(void) { init(); str_out("ЁPҐBET MҐP!"); while(1) { } } Собственно что здесь происходит. Сначала подключаем библиотеки для I2C и для PCF8574. Про I2C я писал уже , поэтому распинаться еще раз на буду, а вот что в PCF8574.h я расскажу. В состав библиотеки вошли всего три функции.
BYTE pcf8574_test(BYTE add) { BYTE ask = ACK; add &= 0xFE; i2c_start(); ask = i2c_send_byte(add); i2c_stop(); return ask; } Первая функция была написана для проверки наличия устройства на шине. В принципе ее можно применять для поиска любого устройства находящегося на шине. Функция принимает адрес искомого устройства и если оно отвечает, то возвращает ноль. Если устройство с таким адресом нет на шине, то вернет единицу.
BYTE pcf8574_byte_out(BYTE data, BYTE add) { BYTE ask = ACK; add &= 0xFE; i2c_start(); ask = i2c_send_byte(add); if(!ask) ask = i2c_send_byte(data); i2c_stop(); return ask; } Эта функция уже заточена чисто под данную микросхему. В качестве аргументов ей передаются байт для передачи в шину и адрес микросхемы. Функция сначала запросит микросхему по адресу, а затем пошлет байт. Если микросхема получила байт и ответила ACK, то функция закончит работу с микросхемой и вернет ноль как удачная посылка байта. А микросхема в это время выведет этот байт в свой параллельный порт. Иначе получим NACK и вернем единицу, передача провалилась.
BYTE pcf8574_str_out(BYTE *data, BYTE col, BYTE add) { BYTE ask = ACK; add &= 0xFE; i2c_start(); ask = i2c_send_byte(add); for(BYTE i=0; i Эта функция создана для эксперимента. Принимает указатель на массив однобайтовых данных, количество этих байт и адрес микросхемы. Собственно попытка передать все данные одной сессией, а не одним байтом за сессию. Функция работает, но так для ЖК дисплея и не подошла. А теперь давайте вернемся к основной программе. После подключения библиотек, прописываем адрес микросхемы. Далее создаем три функции по аналогии с lcd.h. Отличие лишь в принципе передачи данных.
void com(BYTE com) { com |= 0x08; // Р3 в единицу, дабы горела подсветка pcf8574_byte_out(com, ADD); // Вывод данных com |= 0x04; // Е в единицу pcf8574_byte_out(com, ADD); // Вывод данных com &= 0xFB; // Е в ноль pcf8574_byte_out(com, ADD); // Вывод данных } Эта функция передает только команды дисплею. Отсюда появилась первая строка с логическим сложением команды с 0х08. Эта бяка нужна из-за того что мы передаем байт не прямо в порт ЖК дисплея, а через наш ретранслятор. То есть если мы подали байт, а потом нам нужно вывести только один бит, то соизвольте к предыдущему байту присвоит нужный бит и уже его снова отправить в порт. Вот такая заморочка. Сложение с 0х08 необходимо для постоянного удержания единицы на третьем разряде. Помните про подсветку? Вот именно это сложение и включает подсветку. После вызываем функцию передачи байта в шину. О ней написано выше. Затем передаем байт по шине в микросхему. Далее следует выставить в единицу Е, чем собственно занимается логическое сложение байта с 0х04. После обнуление Е. Таким образом можно послать любую команду дисплею лишь передав в качестве аргумента саму команду. void init(void) { _delay_ms(30); // Пауза после подачи питания com(0x30); // Переход в 4-х битный режим _delay_us(40); // Задержка для выполнения команды com(0x30); // Переход в 4-х битный режим _delay_us(40); // Задержка для выполнения команды com(0x30); // Переход в 4-х битный режим _delay_us(40); // Задержка для выполнения команды com(0x20); // Переход в 4-х битный режим _delay_us(40); // Задержка для выполнения команды com(0x20); // Установка параметров com(0x80); // Установка параметров com(0x00); // Выключаем дисплей com(0x80); // Выключаем дисплей com(0x00); // Очищаем дисплей com(0x10); // Очищаем дисплей com(0x00); // Устанавливаем режим ввода данных com(0x60); // Устанавливаем режим ввода данных com(0x00); // Включаем дисплей с выбранным курсором com(0xC0); // Включаем дисплей с выбранным курсором } Эта функция занимается лишь инициализацией дисплея. Последовательность команд взята из даташита на ЖК дисплей. void char_out(BYTE data) { BYTE data_h = ((data & 0xF0) + 0x09); BYTE data_l = ((data // Передача старших 4 бит data_h |= 0x04; pcf8574_byte_out(data_h, ADD); // Передача старших 4 бит data_h &= 0xF9; pcf8574_byte_out(data_h, ADD); // Передача старших 4 бит pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит data_l |= 0x04; pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит data_l &= 0xF9; pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит } Эта функция передает данные ЖК дисплею. Выполняется так же как и команды за исключением того, что передача байта идет сначала старшим полубайтом, а затем младшим. А остальное тоже самое. void str_out(BYTE *str) { while((*str) != "\0") { char_out(*str); str++; } } Ну, а эта функция чисто для передачи строки дисплею. Собственно к нашей теме она никакого отношения не имеет.

Проект для AtmelStudio 6.2 

Грамотный 01.08.15 17:11

Запятая пропущена. Правильно: "ПРИВЕТ, МИР!" И сей девайс заточен не только для HD44780. Подтягивающие резисторы ставятся со стороны мастера. Согласно спецификации, запись данных в контроллер LCD идет по спаду Е. Отсюда первая же функция упрощается: void com(BYTE com) { com |= 0x08; // подсветка pcf8574_byte_out(com | 0x04, ADD);// Вывод данных pcf8574_byte_out(com, ADD); // Е в ноль } Да и остальные тоже существенно меньше могут быть. Например, void char_out(BYTE data) будет всего из двух вызовов, и уж тем более без дополнительных переменных. Инициализация LCD выполнена с нарушениями спецификации таймингов.

Алексей 02.08.15 19:11

Из-за отсутствия запятой, дисплей не пострадает. Сей девайc как раз заточен именно под дисплеи с таким, либо аналогичным контроллером. А вот именно микросхема действительно простой расширитель порта. По поводу Е я согласен. Дополнительные переменные нужны. Если передать функции аргумент с выполнением неких действий с логикой, могут возникнуть глюки. Уже с таким сталкивался. Инициализация выполняется без нарушений тайменгов. В документации сказано, что между командами ставиться пауза 40 мкс. Из-за того что передача идет по шине i2c, а та в свою очередь программная и медленная, то периоды выполняются с лихвой. Если все же Вам не лень, то напишите свой вариант и пришлите мне. Я его опубликую. В конце концов данный сайт предназначен на любительскую аудиторию и каждый кто хочет может высказать свое мнение и видение на жизнь МК.

Алексей 06.08.15 09:14

Добавлены тайменги при инициализации дисплея по замечанию уважаемого "Грамотного"

Дмитрий 14.06.16 21:57

Здравствуйте Алексей.Можно в генератор кода добавить библиотеку для работы с PCF8574.

Алексей 14.06.16 22:32

Я подумаю.))

ruslan 21.12.16 19:54
Алексей 21.12.16 21:53

О да. Особенно код на асме. Ардуинщики оценят по полной)))

Пы.сы.
Даже если не взирать на асм, то там прога написана под PIC контроллер. Для AVRщиков это "очень" полезная информация? особенно начинающим))) Я ничего не имею против PIC, но даже асм у PIC и AVR разный. А по поводу подробностей работы ЖК дисплея, то можно глянуть ))) Правда я ее еще писал под CVAVR но все команды разобраны и разложены по полочкам. Но в любом случае решайте сами где понятнее написано))) Автор пишет, читатель выбирает.

GeK 04.01.17 12:52

"I2C адрес микросхемы (по умолчанию он равен 0x4E"

Старшие 4 бита адреса фиксированы,
префикс У PCF8574 равен 0100, а у PCF8574A - 0111
Младшие 3 бита зависят от состояния входов микросхемы A2-A0. По умолчанию все 3 перемычки разомкнуты, соответственно адрес микросхемы принимает значение 0111111.
// A2 A1 A0 PCF8574 PCF8574A
// 1 1 1 0x20 0x38
// 1 1 0 0x21 0x39
// 1 0 1 0x22 0x3A
// 1 0 0 0x23 0x3B
// 0 1 1 0x24 0x3C
// 0 1 0 0x25 0x3D
// 0 0 1 0x26 0x3E
// 0 0 0 0x27 0x3F

Алексей 04.01.17 14:27

Что-то вы перепутали.
Выписка из документации на микросхему

0b01001110 это 0x4E
Так что тут все верно. А если нужно сменить адрес, то всего лишь нужно его поменять в дефайне.

Юрий 14.12.17 21:26

Доброго времени суток! А можно еще код функции lcdgotoxy и lcdclear для работы с переходником на PCF8574.

Александр 20.05.18 18:14

Доброго времени суток! как вы выводите русский текст.

Алексей 20.05.18 23:04

Это отечественный дисплей от фирмы МЭЛТ. У него в памяти зашита кириллица.

Александр 21.05.18 04:55

Доброго времени суток! Я пиши как у вас в Проект для AtmelStudio 6.2 " ЁPҐBET MҐP!" то выводит нормально
а если пиши "ПРИВЕТ МИР!" выводит ерунду всякую. у меня два
варианта дисплеев у одного зашита кириллица. второй китайский.

Алексей 21.05.18 09:22

Я бы для начала написал бы тестовою программу. Перебор всей памяти с выводом на дисплей символов и их адресов. А потом уже выеснять в чем проблема. Скорее всего таблица символов не совпадает с таблицей ascii.

Андрей 03.09.18 08:32

День Добрый!

А схемку под Proteus не можете подкинуть?

Андрей 03.09.18 10:22

Или в Proteuse никто не проверял?

Андрей 03.09.18 10:56

Разобрался main_init

Павел 30.05.19 23:35

Любопытная вещь, адрес дисплея 0х4Е, а если тот же дисплей подключить к ардуинке то адрес 0х27

Павел 31.05.19 11:04

Спасибо огромное за Вашу работу! Перерыл весь интернет, ни один из приведенных примеров кроме Вашего не заработал. Единственное, в архиве проекта в функции инициализации дисплея не прописаны задержки _delay_, и он соответственно не работает

Алексей 01.06.19 09:52

Ну это больше демонстрационный проект. По хорошему нужно библиотеку axlib переписывать, но с учетом того что STM32 и STM8 двигается семимильными шагами, смысла в AVR уже нет вообще.

Павел 05.06.19 12:57

У STM нет DIP корпусов, сложнее делать печатные платы. Для моих проектов возможностей AVR хватает с запасом, на одной Atmega 8 очень много можно уместить

Алексей 05.06.19 15:20

Да, но сколько стоит Atmega8 и stm8s003)))

Дмитрий 07.06.19 00:41

Здравствуй, Алексей.
Подскажи, пожалуйста, как нужно читать из pcf8574 состояние порта?
Хочу сделать внешний блок, 8 GPIO по шине i2c - саме оно.

Дмитрий 07.06.19 17:56

Сам себе отвечу
Функция возвращает байт - состояние портов микросхемы
uint8_t pcf8574_byte_rcv(uint8_t addr)
{
uint8_t ask = ACK;
addr |= 0b01; //READ
uint8_t data=0;
i2c_start();
ask = i2c_send_byte(addr);
if(!ask) data = i2c_read_byte(NACK);
i2c_stop();

Return data;
}

Павел 07.06.19 20:37

Сколько стоит, 150 рублей, по цене релюшки в общем), а как вы разводите платы под STM? ЛУТ ненадежен, ЧПУ фрезер не уверен что возьмет (не пробовал)

Пожалуй один из самых популярных экранов на рынке. Собран на популярном контроллере HD44780U. Из названия модели следует, что экран состоит из двух строк по 16 символов. Поддержки русского языка в этой конкретной модели нет.

Шина данных ш2с позволяет по двум проводам подключать до 127 устройств, при чем одновременно. Данный I2C реализован на чипе PCF8574T.

Схема подключения:

Синяя штука — переменное сопротивление, позволяет настроить контрастность экрана.

Перемычка слева — отвечает за подсветку экрана.

Блок из 4х контактов подключается к arduino так:

GND — GND
VCC — 5V
SDA — A4 (если Arduino MEGA, то к D20)
SCL — A5 (если Arduino MEGA, то к D21)

Библиотека

Скетч

У дисплея может быть другой IIC адрес, вместо 0x27 может оказаться 0x3F. Чтобы точно определить адрес можете воспользоваться сканером i2c устройств .

#include #include //задаем адрес LCD экрана 0x27, 16 символов, 2 строки LiquidCrystal_I2C lcd(0x27, 16, 2); void setup () { lcd.init(); // Инициализируем экран //включаем подсветку lcd.backlight(); //Устанавливаем позицию начиная с которой выводится текст. lcd.setCursor (2, 0); //выводим строку 1 lcd.print ("Hello, World!" ); //аналогично выводим вторую строку lcd.setCursor (1, 1); lcd.print ("www.сайт" ); } void loop () { }

  • Модуль FC-113 сделан на базе микросхемы PCF8574T, которая представляет собой 8-битный сдвиговый регистр - «расширитель» входов-выходов для последовательной шины I2C. На рисунке микросхема обозначена DD1.
  • R1 - подстроечный резистор для регулировки контрастности ЖК дисплея.
  • Джампер J1 используется для включения подсветки дисплея.
  • Выводы 1…16 служат для подключения модуля к выводам LCD дисплея.
  • Контактные площадки А1…А3 нужны для изменения адреса I2C устройства. Запаивая соответствующие перемычки, можно менять адрес устройства. В таблице приведено соответствие адресов и перемычек: "0" соответствует разрыву цепи, "1" - установленной перемычке. По умолчанию все 3 перемычки разомкнуты и адрес устройства 0x27 .

2 Схема подключения ЖК дисплея к Arduino по протоколу I2C

Подключение модуля к Arduino осуществляется стандартно для шины I2C: вывод SDA модуля подключается к аналоговому порту A4, вывод SCL - к аналоговому порту A5 Ардуино. Питание модуля осуществляется напряжением +5 В от Arduino. Сам модуль соединяется выводами 1…16 с соответствующими выводами 1…16 на ЖК дисплее.


3 Библиотека для работы по протоколу I2C

Теперь нужна библиотека для работы с LCD по интерфейсу I2C. Можно воспользоваться, например, вот этой (ссылка в строке "Download Sample code and library").

Скачанный архив LiquidCrystal_I2Cv1-1.rar разархивируем в папку \libraries\ , которая находится в директории Arduino IDE.

Библиотека поддерживает набор стандартных функций для LCD экранов:

Функция Назначение
LiquidCrystal() создаёт переменную типа LiquidCrystal и принимает параметры подключения дисплея (номера выводов);
begin() инициализация LCD дисплея, задание параметров (кол-во строк и символов);
clear() очистка экрана и возврат курсора в начальную позицию;
home() возврат курсора в начальную позицию;
setCursor() установка курсора на заданную позицию;
write() выводит символ на ЖК экран;
print() выводит текст на ЖК экран;
cursor() показывает курсор, т.е. подчёркивание под местом следующего символа;
noCursor() прячет курсор;
blink() мигание курсора;
noBlink() отмена мигания;
noDisplay() выключение дисплея с сохранением всей отображаемой информации;
display() включение дисплея с сохранением всей отображаемой информации;
scrollDisplayLeft() прокрутка содержимого дисплея на 1 позицию влево;
scrollDisplayRight() прокрутка содержимого дисплея на 1 позицию вправо;
autoscroll() включение автопрокрутки;
noAutoscroll() выключение автопрокрутки;
leftToRight() задаёт направление текста слева направо;
rightToLeft() направление текста справа налево;
createChar() создаёт пользовательский символ для LCD-экрана.

4 Скетч для вывода текста на LCD экран по шине I2C

Откроем образец: Файл Образцы LiquidCrystal_I2C CustomChars и немного его переделаем. Выведем сообщение, в конце которого будет находиться мигающий символ. В комментариях к коду прокомментированы все нюансы скетча.

#include // подключаем библиотеку Wire #include // подключаем библиотеку ЖКИ #define printByte(args) write(args); // uint8_t heart = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0}; // битовая маска символа «сердце» LiquidCrystal_I2C lcd(0x27, 16, 2); // Задаём адрес 0x27 для LCD дисплея 16x2 void setup() { lcd.init(); // инициализация ЖК дисплея lcd.backlight(); // включение подсветки дисплея lcd.createChar(3, heart); // создаём символ «сердце» в 3 ячейке памяти lcd.home(); // ставим курсор в левый верхний угол, в позицию (0,0) lcd.!"); // печатаем строку текста lcd.setCursor(0, 1); // перевод курсора на строку 2, символ 1 lcd.print(" i "); // печатаем сообщение на строке 2 lcd.printByte(3); // печатаем символ «сердце», находящийся в 3-ей ячейке lcd.print(" Arduino "); } void loop() { // мигание последнего символа lcd.setCursor(13, 1); // перевод курсора на строку 2, символ 1 lcd.print("\t"); delay(500); lcd.setCursor(13, 1); // перевод курсора на строку 2, символ 1 lcd.print(" "); delay(500); }

Кстати, символы, записанные командой lcd.createChar(); , остаются в памяти дисплея даже после выключения питания, т.к. записываются в ПЗУ дисплея 1602.

5 Создание собственных символов для ЖК дисплея

Немного подробнее рассмотрим вопрос создания собственных символов для ЖК экранов. Каждый символ на экране состоит из 35-ти точек: 5 в ширину и 7 в высоту (+1 резервная строка для подчёркивания). В строке 6 приведённого скетча мы задаём массив из 7-ми чисел: {0x0, 0xa, 0x1f, 0x1f, 0xe, 0x4, 0x0} . Преобразуем 16-ричные числа в бинарные: {00000, 01010, 11111, 11111, 01110, 00100, 00000} . Эти числа - не что иное, как битовые маски для каждой из 7-ми строк символа, где "0" обозначают светлую точку, а "1" - тёмную. Например, символ сердца, заданный в виде битовой маски, будет выглядеть на экране так, как показано на рисунке.

6 Управление ЖК экраном по шине I2C

Загрузим скетч в Arduino. На экране появится заданная нами надпись с мигающим курсором в конце.


7 Что находится «за» шиной I2C

В качестве бонуса рассмотрим временную диаграмму вывода латинских символов "A", "B" и "С" на ЖК дисплей. Эти символы имеются в ПЗУ дисплея и выводятся на экран просто передачей дисплею их адреса. Диаграмма снята с выводов RS, RW, E, D4, D5, D6 и D7 дисплея, т.е. уже после преобразователя FC-113 «I2C параллельная шина». Можно сказать, что мы погружаемся немного «глубже» в «железо».


Временная диаграмма вывода латинских символов "A", "B" и "С" на LCD дисплей 1602

На диаграмме видно, что символы, которые имеются в ПЗУ дисплея (см. стр.11 даташита, ссылка ниже), передаются двумя полубайтами, первый из которых определяет номер столбца таблицы, а второй - номер строки. При этом данные «защёлкиваются» по фронту сигнала на линии E (Enable), а линия RS (Register select, выбор регистра) находится в состоянии логической единицы, что означает передачу данных. Низкое состояние линии RS означает передачу инструкций, что мы и видим перед передачей каждого символа. В данном случае передаётся код инструкции возврата каретки на позицию (0, 0) ЖК дисплея, о чём также можно узнать, изучив техническое описание дисплея.

И ещё один пример. На этой временной диаграмме показан вывод символа «Сердце» на ЖК дисплей.


Опять, первые два импульса Enable соответствуют инструкции Home() (0000 0010 2) - возврат каретки на позицию (0; 0), а вторые два - вывод на ЖК дисплей хранящийся в ячейке памяти 3 10 (0000 0011 2) символ «Сердце» (инструкция lcd.createChar(3, heart); скетча).

LCD I2C модуль позволить подключить символьный дисплей к плате Arduino всего по двум сигнальным проводам.

Используемые компоненты (купить в Китае):

. Управляющая плата

. Соединительные провода

Основные технические характеристики:

Дисплей: Символьный 16х02 либо 20x04
. Подсветка: Синяя c белыми символами
. Контраст: Настраивается потенциометром
. Напряжение питания: 5В
. Интерфейс: I2C
. I2C адрес: 0x27
. Размеры: 82мм x 35мм x 18мм

Подключение к Arduino

Модуль оборудован четырех-пиновым разъемом стандарта 2.54мм

SCL : последовательная линия тактирования (Serial CLock)

SDA : последовательная линия данных (Serial DAta)

VCC : "+" питания

GND : "-" питания

Выводы отвечающие за интерфейс I2C на платах Arduino на базе различных контроллеров разнятся

Для работы с данным модулем необходимо установить библиотеку LiquidCrystal_I2C1602V1

Скачиваем, распаковываем и закидываем в папку libraries в папке Arduino. В случае, если на момент добавления библиотеки, Arduino IDE была открытой, перезагружаем среду.

Переходим непосредственно к скетчу. В данном примере выведем стандартный "Hello, world!" и для адрес нашего сообщества.

пример программного кода:

#include #include LiquidCrystal_I2C lcd(0x27,16,2); /* Задаем адрес и размерность дисплея. При использовании LCD I2C модуля с дисплеем 20х04 ничего в коде изменять не требуется, cледует только задать правильную размерность */ void setup () { lcd.init(); // Инициализация lcd lcd.backlight(); // Включаем подсветку // Курсор находится в начале 1 строки lcd.print ("Hello, world!" ); // Выводим текст lcd.setCursor (0, 1); // Устанавливаем курсор в начало 2 строки lcd.print ("сайт" ); // Выводим текст } void loop () { }

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

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

Не беда, требуемый символ можно сделать вручную. Данный способ частично, ограничение в 7 символов, поможет решить проблему вывода.

Ячейка, в рассматриваемых нами дисплеях, имеет разрешение 5х8 точек. Все, к чему сводится задача создания символа, это написать битовую маску и расставить в ней единички в местах где должны гореть точки и нолики где нет.

В ниже приведенном примере нарисуем смайлик.

пример программного кода:

//Тестировалось на Arduino IDE 1.0.5 // Добавляем необходимые библиотеки #include #include // Битовая маска символа улыбки byte smile = { B00010, B00001, B11001, B00001, B11001, B00001, B00010, }; LiquidCrystal_I2C lcd(0x27,20,4); // Задаем адрес и размерность дисплея. void setup () { lcd.init(); // Инициализация lcd lcd.backlight(); // Включаем подсветку // Создаем символ под номером 0 lcd.createChar (1, smile); lcd.setCursor (0, 0); // Устанавливаем курсор в начало 1 строки lcd.print ("\1" ); // Выводим смайлик (символ под номером 1) - "\1" } void loop () { }

Программка для легкого создания символов

В комментариях участник сообщества скинул ссылку на генератор символов

LCD дисплей – частый гость в проектах ардуино. Но в сложных схемах у нас может возникнуть проблема недостатка портов Arduino из-за необходимости подключить экран, у которого очень очень много контактов. Выходом в этой ситуации может стать I2C /IIC переходник, который подключает практически стандартный для Arduino экран 1602 к платам Uno, Nano или Mega всего лишь при помощи 4 пинов. В этой статье мы посмотрим, как можно подключить LCD экран с интерфейсом I2C, какие можно использовать библиотеки, напишем короткий скетч-пример и разберем типовые ошибки.

Жидкокристаллический дисплей (Liquid Crystal Display) LCD 1602 является хорошим выбором для вывода строк символов в различных проектах. Он стоит недорого, есть различные модификации с разными цветами подсветки, вы можете легко скачать готовые библиотеки для скетчей Ардуино. Но самым главным недостатком этого экрана является тот факт, что дисплей имеет 16 цифровых выводов, из которых обязательными являются минимум 6. Поэтому использование этого LCD экрана без i2c добавляет серьезные ограничения для плат Arduino Uno или Nano. Если контактов не хватает, то вам придется покупать плату Arduino Mega или же сэкономить контакты, в том числе за счет подключения дисплея через i2c.

Краткое описание пинов LCD 1602

Давайте посмотрим на выводы LCD1602 повнимательней:

Каждый из выводов имеет свое назначение:

  1. Земля GND;
  2. Питание 5 В;
  3. Установка контрастности монитора;
  4. Команда, данные;
  5. Записывание и чтение данных;
  6. Enable;

7-14. Линии данных;

  1. Плюс подсветки;
  2. Минус подсветки.

Технические характеристики дисплея:

  • Символьный тип отображения, есть возможность загрузки символов;
  • Светодиодная подсветка;
  • Контроллер HD44780;
  • Напряжение питания 5В;
  • Формат 16х2 символов;
  • Диапазон рабочих температур от -20С до +70С, диапазон температур хранения от -30С до +80 С;
  • Угол обзора 180 градусов.

Схема подключения LCD к плате Ардуино без i2C

Стандартная схема присоединения монитора напрямую к микроконтроллеру Ардуино без I2C выглядит следующим образом.

Из-за большого количества подключаемых контактов может не хватить места для присоединения нужных элементов. Использование I2C уменьшает количество проводов до 4, а занятых пинов до 2.

Где купить LCD экраны и шилды для ардуино

LCD экран 1602 (и вариант 2004) довольно популярен, поэтому вы без проблем сможете найти его как в отечественных интернет-магазинах, так и на зарубежных площадках. Приведем несколько ссылок на наиболее доступные варианты:

Модуль LCD1602+I2C с синим экраном, совместим с Arduino Простой дисплей LCD1602 (зеленая подсветка) дешевле 80 рублей Большой экран LCD2004 с I2C HD44780 для ардуино (синяя и зеленая подсветка)
Дисплей 1602 с IIC адаптером и синей подсветкой Еще один вариант LCD1602 со впаянным I2C модулем Модуль адаптера Port IIC/I2C/TWI/SPI для экрана 1602, совместим с Ардуино
Дисплей с RGB-подсветкой! LCD 16×2 + keypad +Buzzer Shield for Arduino Шилд для Ардуино с кнопками и экраном LCD1602 LCD 1602 LCD дисплей для 3D принтера (Smart Controller for RAMPS 1.4, Text LCD 20×4), модулем кардридера SD и MicroSD-

Описание протокола I2C

Прежде чем обсуждать подключение дисплея к ардуино через i2c-переходник, давайте вкратце поговорим о самом протоколе i2C.

I2C / IIC (Inter-Integrated Circuit) – это протокол, изначально создававшийся для связи интегральных микросхем внутри электронного устройства. Разработка принадлежит фирме Philips. В основе i2c протокола является использование 8-битной шины, которая нужна для связи блоков в управляющей электронике, и системе адресации, благодаря которой можно общаться по одним и тем же проводам с несколькими устройствами. Мы просто передаем данные то одному, то другому устройству, добавляя к пакетам данных идентификатор нужного элемента.

Самая простая схема I2C может содержать одно ведущее устройство (чаще всего это микроконтроллер Ардуино) и несколько ведомых (например, дисплей LCD). Каждое устройство имеет адрес в диапазоне от 7 до 127. Двух устройств с одинаковым адресом в одной схеме быть не должно.

Плата Arduino поддерживает i2c на аппаратном уровне. Вы можете использовать пины A4 и A5 для подключения устройств по данному протоколу.

В работе I2C можно выделить несколько преимуществ:

  • Для работы требуется всего 2 линии – SDA (линия данных) и SCL (линия синхронизации).
  • Подключение большого количества ведущих приборов.
  • Уменьшение времени разработки.
  • Для управления всем набором устройств требуется только один микроконтроллер.
  • Возможное число подключаемых микросхем к одной шине ограничивается только предельной емкостью.
  • Высокая степень сохранности данных из-за специального фильтра подавляющего всплески, встроенного в схемы.
  • Простая процедура диагностики возникающих сбоев, быстрая отладка неисправностей.
  • Шина уже интегрирована в саму Arduino, поэтому не нужно разрабатывать дополнительно шинный интерфейс.

Недостатки:

  • Существует емкостное ограничение на линии – 400 пФ.
  • Трудное программирование контроллера I2C, если на шине имеется несколько различных устройств.
  • При большом количестве устройств возникает трудности локализации сбоя, если одно из них ошибочно устанавливает состояние низкого уровня.

Модуль i2c для LCD 1602 Arduino

Самый быстрый и удобный способ использования i2c дисплея в ардуино – это покупка готового экрана со встроенной поддержкой протокола. Но таких экранов не очень много истоят они не дешево. А вот разнообразных стандартных экранов выпущено уже огромное количество. Поэтому самым доступным и популярным сегодня вариантом является покупка и использование отдельного I2C модуля – переходника, который выглядит вот так:

С одной стороны модуля мы видим выводы i2c – земля, питание и 2 для передачи данных. С другой переходника видим разъемы внешнего питания. И, естественно, на плате есть множество ножек, с помощью которых модуль припаивается к стандартным выводам экрана.


Для подключения к плате ардуино используются i2c выходы. Если нужно, подключаем внешнее питание для подстветки. С помощью встроенного подстроечного резистора мы можем настроить настраиваемые значения контрастности J

На рынке можно встретить LCD 1602 модули с уже припаянными переходниками, их использование максимально упощено. Если вы купили отдельный переходник, нужно будет предварительно припаять его к модулю.

Подключение ЖК экрана к Ардуино по I2C

Для подключения необходимы сама плата Ардуино, дисплей, макетная плата, соединительные провода и потенциометр.

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


Жидкокристаллический монитор с поддержкой i2c подключается к плате при помощи четырех проводов – два провода для данных, два провода для питания.

  • Вывод GND подключается к GND на плате.
  • Вывод VCC – на 5V.
  • SCL подключается к пину A5.
  • SDA подключается к пину A.

И это все! Никаких паутин проводов, в которых очень легко запутаться. При этом всю сложность реализации i2C протокола мы можем просто доверить библиотекам.

Библиотеки для работы с i2c LCD дисплеем

Для взаимодействие Arduino c LCD 1602 по шине I2C вам потребуются как минимум две библиотеки:

  • Библиотека Wire.h для работы с I2C уже имеется в стандартной программе Arduino IDE.
  • Библиотека LiquidCrystal_I2C.h, которая включает в себя большое разнообразие команд для управления монитором по шине I2C и позволяет сделать скетч проще и короче. Нужно дополнительно установить библиотеку После подключения дисплея нужно дополнительно установить библиотеку LiquidCrystal_I2C.h

После подключения к скетчу всех необходимых библиотек мы создаем объект и можем использовать все его функции. Для тестирования давайте загрузим следующий стандартный скетч из примера.

#include #include // Подключение библиотеки //#include // Подключение альтернативной библиотеки LiquidCrystal_I2C lcd(0x27,16,2); // Указываем I2C адрес (наиболее распространенное значение), а также параметры экрана (в случае LCD 1602 - 2 строки по 16 символов в каждой //LiquidCrystal_PCF8574 lcd(0x27); // Вариант для библиотеки PCF8574 void setup() { lcd.init(); // Инициализация дисплея lcd.backlight(); // Подключение подсветки lcd.setCursor(0,0); // Установка курсора в начало первой строки lcd.print("Hello"); // Набор текста на первой строке lcd.setCursor(0,1); // Установка курсора в начало второй строки lcd.print("ArduinoMaster"); // Набор текста на второй строке } void loop() { }

Описание функций и методов библиотеки LiquidCrystal_I2C:

  • home() и clear() – первая функция позволяет вернуть курсор в начало экрана, вторая тоже, но при этом удаляет все, что было на мониторе до этого.
  • write(ch) – позволяет вывести одиночный символ ch на экран.
  • cursor() и noCursor() – показывает/скрывает курсор на экране.
  • blink() и noBlink() – курсор мигает/не мигает (если до этого было включено его отображение).
  • display() и noDisplay() – позволяет подключить/отключить дисплей.
  • scrollDisplayLeft() и scrollDisplayRight() – прокручивает экран на один знак влево/вправо.
  • autoscroll() и noAutoscroll() – позволяет включить/выключить режим автопрокручивания. В этом режиме каждый новый символ записывается в одном и том же месте, вытесняя ранее написанное на экране.
  • leftToRight() и rightToLeft() – Установка направление выводимого текста – слева направо или справа налево.
  • createChar(ch, bitmap) – создает символ с кодом ch (0 – 7), используя массив битовых масок bitmap для создания черных и белых точек.

Альтернативная библиотека для работы с i2c дисплеем

В некоторых случаях при использовании указанной библиотеки с устройствами, оснащенными контроллерами PCF8574 могут возникать ошибки. В этом случае в качестве альтернативы можно предложить библиотеку LiquidCrystal_PCF8574.h. Она расширяет LiquidCrystal_I2C, поэтому проблем с ее использованием быть не должно.

Проблемы подключения i2c lcd дисплея

Если после загрузки скетча у вас не появилось никакой надписи на дисплее, попробуйте выполнить следующие действия.

Во-первых, можно увеличить или уменьшить контрастность монитора. Часто символы просто не видны из-за режима контрастности и подсветки.

Если это не помогло, то проверьте правильность подключения контактов, подключено ли питание подсветки. Если вы использовали отдельный i2c переходник, то проверьте еще раз качество пайки контактов.

Другой часто встречающейся причиной отсутствия текста на экране может стать неправильный i2c адрес. Попробуйте сперва поменять в скетче адрес устройства с 0x27 0x20 или на 0x3F. У разных производителей могут быть зашиты разные адреса по умолчанию. Если и это не помогло, можете запустить скетч i2c сканера, который просматривает все подключенные устройства и определяет их адрес методом перебора. Пример скетча i2c сканера .

Если экран все еще останется нерабочим, попробуйте отпаять переходник и подключить LCD обычным образом.

Заключение

В этой статье мы рассмотрели основные вопросы использования LCD экрана в сложных проектах ардуино, когда нам нужно экономить свободные пины на плате. Простой и недорогой переходник i2c позволит подключить LCD экран 1602, занимая всего 2 аналоговых пина. Во многих ситуациях это может быть очень важным. Плата за удобство – необходимость в использовании дополнительного модуля – конвертера и библиотеки. На наш взгляд, совсем не высокая цена за удобство и мы крайне рекомендуем использовать эту возможность в проектах.