В этой статье расскажу, как использовать интерфейсный модуль I2C для управления LCD дисплеем (2×16 / 20х4) с помощью Arduino. Данный модуль позволяет уменьшить количество используемых выводов контроллера, вместо 8 или 4-битного соединения, требуется только 2 вывода (SDA и SCL).
Поддержка дисплеев: LCD 16×02 / 20×04
Дополнительно: регулировка контрастности
Напряжение питания. 5В
Интерфейс: I2C
Габариты: 54мм x 19мм x 15мм
Поскольку количество контактов на контроллерах Arduino ограничено и часто при использовании различных датчиков и модулей они заканчиваются, появляется необходимость в их экономии, для этих случай разработан этот модуль, с его помощью можно реализовать передачу по двум контактам (SDA и SCL).
Теперь немного о самом модуле, построен он на микросхеме PCF8574T. Резисторы R8 (4.7кОм) и R9 (4.7кОм) необходимы для подтяжки линий SDA и SCL, в идеале при подключении двух и более устройств по шине I2C необходимо использовать подтяжку только на одном устройств, позже напишу почему. На плате предусмотрены три перемычки (по схеме видно что линии A0, A1, A2 подтянуты к питанию через резисторы R4, R5, R6), необходимы они для смены адресации устройства, всего их 8 вариантов. Изменение адресации дает нам возможность подключения до восьми устройств по шине IC2 c микросхемой PCF8574T, варианты адресов показаны на рисунке (по умолчанию адрес устройства 0x27). Так же модуль оснащен потенциометром R11 с его помощью можно изменить контрастность LCD дисплея.
Для соединения на модуле расположено три группы контактов:
Первая группа:
SCL: линия тактирования (Serial CLock)
SDA: линия данных (Serial Dфta)
VCC: «+» питание
GND: «-» питание
Вторая группа:
VSS: «-» питание
VDD: «+» питание
VO: Вывод управления контрастом
RS: Выбор регистра
RW: Чтение/запись (режим записи при соединении с землей)
E: Еnable (строб по спаду)
DB0-DB3: Младшие биты интерфейса
DB4-DB7: Старшие биты интерфейса
A: «+» питания подсветки
K: «-» питания подсветки
Третья группа: (по умолчанию установлена перемычка)
VCC:
A от LCD:
Необходимые детали:
Arduino UNO R3 x 1 шт.
LCD-дисплей 1602A (2×16, 5V, Синий) x 1 шт.
Интерфейсный модуль I2C, IIC, TWI для LCD x 1 шт.
Провод DuPont, 2,54 мм, 20 см, F-M (Female — Male) x 1 шт.
Кабель USB 2.0 A-B x 1 шт.
Подключение
:
Первым делом, припаиваем модуль I2C к LCD дисплею, затем необходимо подключить дисплей к Arduino UNO. Для этого воспользуемся проводками DuPont, подключение осуществляем по таблице ниже.
Для наглядности, приведу еще одну схему.
Для этого эксперимента необходимо скачать и установить библиотеку «LiquidCrystal_I2C». Затем скопируйте и вставьте этот пример кода в окно программы IDE Arduino и загрузите в контроллер.
/*
Тестировалось на Arduino IDE 1.6.11
Дата тестирования 15.09.2016г.
*/
#include
Если Вы правильно все сделали, но никаких символов на дисплее нет, попробуйте увеличить контрастность потенциометром.
Ссылки
Скачать библиотеку
Документация на микросхему
Документация к
Купить на Aliexpress
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.
Давайте посмотрим на выводы LCD1602 повнимательней:
Каждый из выводов имеет свое назначение:
7-14. Линии данных;
Технические характеристики дисплея:
Стандартная схема присоединения монитора напрямую к микроконтроллеру Ардуино без I2C выглядит следующим образом.
Из-за большого количества подключаемых контактов может не хватить места для присоединения нужных элементов. Использование I2C уменьшает количество проводов до 4, а занятых пинов до 2.
LCD экран 1602 (и вариант 2004) довольно популярен, поэтому вы без проблем сможете найти его как в отечественных интернет-магазинах, так и на зарубежных площадках. Приведем несколько ссылок на наиболее доступные варианты:
![]() ![]() | ![]() ![]() | ![]() ![]() |
![]() ![]() | ![]() ![]() | ![]() ![]() |
![]() ![]() | ![]() ![]() | ![]() ![]() |
Прежде чем обсуждать подключение дисплея к ардуино через i2c-переходник, давайте вкратце поговорим о самом протоколе i2C.
I2C / IIC (Inter-Integrated Circuit) – это протокол, изначально создававшийся для связи интегральных микросхем внутри электронного устройства. Разработка принадлежит фирме Philips. В основе i2c протокола является использование 8-битной шины, которая нужна для связи блоков в управляющей электронике, и системе адресации, благодаря которой можно общаться по одним и тем же проводам с несколькими устройствами. Мы просто передаем данные то одному, то другому устройству, добавляя к пакетам данных идентификатор нужного элемента.
Самая простая схема I2C может содержать одно ведущее устройство (чаще всего это микроконтроллер Ардуино) и несколько ведомых (например, дисплей LCD). Каждое устройство имеет адрес в диапазоне от 7 до 127. Двух устройств с одинаковым адресом в одной схеме быть не должно.
Плата Arduino поддерживает i2c на аппаратном уровне. Вы можете использовать пины A4 и A5 для подключения устройств по данному протоколу.
В работе I2C можно выделить несколько преимуществ:
Недостатки:
Самый быстрый и удобный способ использования i2c дисплея в ардуино – это покупка готового экрана со встроенной поддержкой протокола. Но таких экранов не очень много истоят они не дешево. А вот разнообразных стандартных экранов выпущено уже огромное количество. Поэтому самым доступным и популярным сегодня вариантом является покупка и использование отдельного I2C модуля – переходника, который выглядит вот так:
С одной стороны модуля мы видим выводы i2c – земля, питание и 2 для передачи данных. С другой переходника видим разъемы внешнего питания. И, естественно, на плате есть множество ножек, с помощью которых модуль припаивается к стандартным выводам экрана.
Для подключения к плате ардуино используются i2c выходы. Если нужно, подключаем внешнее питание для подстветки. С помощью встроенного подстроечного резистора мы можем настроить настраиваемые значения контрастности J
На рынке можно встретить LCD 1602 модули с уже припаянными переходниками, их использование максимально упощено. Если вы купили отдельный переходник, нужно будет предварительно припаять его к модулю.
Для подключения необходимы сама плата Ардуино, дисплей, макетная плата, соединительные провода и потенциометр.
Если вы используете специальный отдельный i2c переходник, то нужно сначала припаять его к модулю экрана. Ошибиться там трудно, можете руководствоваться такой схемой.
Жидкокристаллический монитор с поддержкой i2c подключается к плате при помощи четырех проводов – два провода для данных, два провода для питания.
И это все! Никаких паутин проводов, в которых очень легко запутаться. При этом всю сложность реализации i2C протокола мы можем просто доверить библиотекам.
Для взаимодействие Arduino c LCD 1602 по шине I2C вам потребуются как минимум две библиотеки:
После подключения к скетчу всех необходимых библиотек мы создаем объект и можем использовать все его функции. Для тестирования давайте загрузим следующий стандартный скетч из примера.
#include
Описание функций и методов библиотеки LiquidCrystal_I2C:
В некоторых случаях при использовании указанной библиотеки с устройствами, оснащенными контроллерами PCF8574 могут возникать ошибки. В этом случае в качестве альтернативы можно предложить библиотеку LiquidCrystal_PCF8574.h. Она расширяет LiquidCrystal_I2C, поэтому проблем с ее использованием быть не должно.
Если после загрузки скетча у вас не появилось никакой надписи на дисплее, попробуйте выполнить следующие действия.
Во-первых, можно увеличить или уменьшить контрастность монитора. Часто символы просто не видны из-за режима контрастности и подсветки.
Если это не помогло, то проверьте правильность подключения контактов, подключено ли питание подсветки. Если вы использовали отдельный i2c переходник, то проверьте еще раз качество пайки контактов.
Другой часто встречающейся причиной отсутствия текста на экране может стать неправильный i2c адрес. Попробуйте сперва поменять в скетче адрес устройства с 0x27 0x20 или на 0x3F. У разных производителей могут быть зашиты разные адреса по умолчанию. Если и это не помогло, можете запустить скетч i2c сканера, который просматривает все подключенные устройства и определяет их адрес методом перебора. Пример скетча i2c сканера .
Если экран все еще останется нерабочим, попробуйте отпаять переходник и подключить LCD обычным образом.
В этой статье мы рассмотрели основные вопросы использования LCD экрана в сложных проектах ардуино, когда нам нужно экономить свободные пины на плате. Простой и недорогой переходник i2c позволит подключить LCD экран 1602, занимая всего 2 аналоговых пина. Во многих ситуациях это может быть очень важным. Плата за удобство – необходимость в использовании дополнительного модуля – конвертера и библиотеки. На наш взгляд, совсем не высокая цена за удобство и мы крайне рекомендуем использовать эту возможность в проектах.
Пожалуй один из самых популярных экранов на рынке. Собран на популярном контроллере 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
Пожалуй один из самых популярных экранов на рынке. Собран на популярном контроллере 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
Плата разведена таким образом, чтобы ее можно было сразу скрестить с ЖК дисплеем. На вход подается питание и линии I2C. На плате сразу установлены подтягивающие резисторы на линиях SCL и SDA, потенциометр для регулировки контрастности и питание самого дисплея.
Джампер справа включает/отключает подсветку. Далее вооружившись тестером была составлена следующая табличка.
После изучения модуля было выявлено что P3
управляет подсветкой. Если джампер установлен, то 1 включает подсветку, а 0 выключает. При снятом джампере подсветка всегда выключена. Далее было принято решение дополнить библиотеку axlib функциями для работы с шиной I2C(программная реализация) и функциями для управления микросхемой PCF8574. В двух словах как работает модуль. Для того чтобы вывести параллельно байт, для этого нужно послать в шину I2C адрес микросхемы (по умолчанию он равен 0x4E. Так же можно менять адрес методом впаивания перемычек на плате и меняя значение трех младших разрядов адреса), затем после получения ACK посылается байт данных. После того как микросхема отвечает ACK, байт появляется на параллельном порту микросхемы. Для управления ЖК дисплеем я взял функции из библиотеки axlib и немного переделал их для работы с шиной I2C.
#include
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
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
Запятая пропущена. Правильно: "ПРИВЕТ, МИР!" И сей девайс заточен не только для 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 выполнена с нарушениями спецификации таймингов.
Из-за отсутствия запятой, дисплей не пострадает. Сей девайc как раз заточен именно под дисплеи с таким, либо аналогичным контроллером. А вот именно микросхема действительно простой расширитель порта. По поводу Е я согласен. Дополнительные переменные нужны. Если передать функции аргумент с выполнением неких действий с логикой, могут возникнуть глюки. Уже с таким сталкивался. Инициализация выполняется без нарушений тайменгов. В документации сказано, что между командами ставиться пауза 40 мкс. Из-за того что передача идет по шине i2c, а та в свою очередь программная и медленная, то периоды выполняются с лихвой. Если все же Вам не лень, то напишите свой вариант и пришлите мне. Я его опубликую. В конце концов данный сайт предназначен на любительскую аудиторию и каждый кто хочет может высказать свое мнение и видение на жизнь МК.
Добавлены тайменги при инициализации дисплея по замечанию уважаемого "Грамотного"
Здравствуйте Алексей.Можно в генератор кода добавить библиотеку для работы с PCF8574.
Я подумаю.))
О да. Особенно код на асме. Ардуинщики оценят по полной)))
Пы.сы.
Даже если не взирать на асм, то там прога написана под PIC контроллер. Для AVRщиков это "очень" полезная информация? особенно начинающим))) Я ничего не имею против PIC, но даже асм у PIC и AVR разный. А по поводу подробностей работы ЖК дисплея, то можно глянуть ))) Правда я ее еще писал под CVAVR но все команды разобраны и разложены по полочкам. Но в любом случае решайте сами где понятнее написано))) Автор пишет, читатель выбирает.
"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
Что-то вы перепутали.
Выписка из документации на микросхему
0b01001110 это 0x4E
Так что тут все верно. А если нужно сменить адрес, то всего лишь нужно его поменять в дефайне.
Доброго времени суток! А можно еще код функции lcdgotoxy и lcdclear для работы с переходником на PCF8574.
Доброго времени суток! как вы выводите русский текст.
Это отечественный дисплей от фирмы МЭЛТ. У него в памяти зашита кириллица.
Доброго времени суток! Я пиши как у вас в Проект для AtmelStudio 6.2 " ЁPҐBET MҐP!" то выводит нормально
а если пиши "ПРИВЕТ МИР!" выводит ерунду всякую. у меня два
варианта дисплеев у одного зашита кириллица. второй китайский.
Я бы для начала написал бы тестовою программу. Перебор всей памяти с выводом на дисплей символов и их адресов. А потом уже выеснять в чем проблема. Скорее всего таблица символов не совпадает с таблицей ascii.
День Добрый!
А схемку под Proteus не можете подкинуть?
Или в Proteuse никто не проверял?
Разобрался main_init
Любопытная вещь, адрес дисплея 0х4Е, а если тот же дисплей подключить к ардуинке то адрес 0х27
Спасибо огромное за Вашу работу! Перерыл весь интернет, ни один из приведенных примеров кроме Вашего не заработал. Единственное, в архиве проекта в функции инициализации дисплея не прописаны задержки _delay_, и он соответственно не работает
Ну это больше демонстрационный проект. По хорошему нужно библиотеку axlib переписывать, но с учетом того что STM32 и STM8 двигается семимильными шагами, смысла в AVR уже нет вообще.
У STM нет DIP корпусов, сложнее делать печатные платы. Для моих проектов возможностей AVR хватает с запасом, на одной Atmega 8 очень много можно уместить
Да, но сколько стоит Atmega8 и stm8s003)))
Здравствуй, Алексей.
Подскажи, пожалуйста, как нужно читать из pcf8574 состояние порта?
Хочу сделать внешний блок, 8 GPIO по шине i2c - саме оно.
Сам себе отвечу
Функция возвращает байт - состояние портов микросхемы
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;
}
Сколько стоит, 150 рублей, по цене релюшки в общем), а как вы разводите платы под STM? ЛУТ ненадежен, ЧПУ фрезер не уверен что возьмет (не пробовал)