Сайт о телевидении

Сайт о телевидении

» » Подключение двух дисплеев к arduino. Учебный курс. Подключение lcd к микроконтроллеру. Получение первых результатов

Подключение двух дисплеев к arduino. Учебный курс. Подключение lcd к микроконтроллеру. Получение первых результатов

Сегодня попробуем остановиться на выводе на текстовый дисплей. Наиболее популярным является чип HD44780 (или совместимый с ним KS0066). Перечислим их плюсы и минусы:

Плюсы:

  1. Невысокая цена.
  2. Простота программирования, код будет одинаков для любой модели.
  3. Многообразие моделей - наиболее распространённые: 8x1, 16x2, 20x4. Также можно встретить довольно экзотические модели 40x4, т.е. четыре строки по 40 символов в каждой.
  4. Возможность подключить несколько дисплеев к одной Arduino.
  5. Возможность задавать собственные символы.

Минусы:

  1. Далеко не все дисплеи поддерживают русские символы. Подробнее надо смотреть в описании к конкретному дисплею.
  2. Подключение без использования I2C-шины требует использования 10-16 проводов, что очень плохо. с I2C - 4 провода.

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

Давайте попробуем.

Что нам понадобится.

  1. Arduino (Я взял модель Nano)
  2. Дисплей на чипе HD44780 с модулем I2C или без него (тогда понадобится отдельно плата LC1602 IIC) - в нашем случае 16x2 без I2C модуля
  3. Резистор на 10Ком (Если нужно ручное управление подсветкой).
  4. Потенциометр (Если нужно ручное управление подсветкой).
  5. Макетная плата Breadboard.
  6. Библиотека LiquidCrystal_I2C. http://www.ansealk.ru/files/LiquidCrystal_V1.2.1.zip

Небольшое отступление №1: Как отличить дисплей с I2C-модулем?

На самом деле все довольно просто. Если, перевернув дисплей мы видим длинную колодку разъемов (как правило 16 штук) то модуля I2C на дисплее нет:

А вот так выглядит дисплей с уже установленным I2C-модулем:

Контакты SCL, SDA, VCC, GND используются для подключения Arduino. Два контакта слева - на картинке они замкнуты перемычкой - нужны для работы подсветки.

Если модуль не подключен - придется сделать это самостоятельно. Главное, на что стоит обратить внимание - соединить контакты в правильном порядке. Как правило первый и 16 пины помечены. Иногда бывает, что 15-16 контакты, через которые осуществляется управление подсветкой, могут располагаться перед первым (в этом случае они будут пронумерованы). На самом же модуле первый пин также может быть обозначен не цифрой, а квадратом вокруг самого пина.

Схемы:

Соберем следующую схему:

Обращу внимание на следующие моменты:

  1. Если вам попался дисплей с уже припаянным I2C-модулем, то провода, помеченные серым, не понадобятся. В остальном - ничего не меняется.
  2. Если мы не хотим менять яркость дисплея - то схема упростится:

как заметили, два пина на I2C-модуле с маркировкой LED отвечают за подсветку дисплея. Если не хотим использовать управление яркостью - их просто можно замкнуть.

Теперь давайте разберем код.

Тут почти все нам должно быть знакомо. В строке 5 указываем адрес устройства. В строках 16 и 17 - количество символов в строке и количество строк. В строках 20-22 - Создаем объект для работы с дисплеем и описываем параметр работы с ним.

Небольшое отступление №2: Как узнать адрес I2C-устройства?

В большинстве своем адрес можно посмотреть в даташите к микросхеме, на которой построено I2C-устройство. Если же такой возможности нет вот ссылка на архив со скетчем и схемами - http://www.ansealk.ru/files/Arduino_lcd_i2c.zip который определяет адреса всех устройств, подключенных по I2C-шине. Достаточно только подключить устройство к Arduino, загрузить скетч, открыть консоль и увидеть адрес.

Тут мы видим функцию, которая, собственно, и будет заниматься выводом на дисплей. Принцип вывода примерно такой:

Задаём позицию начала вывода функцией setCursor()

Печатаем строку функцией print()

После этого следующая функцию print() начнет вывод со следующей позиции, после которой закончился предыдущий ввод. Также обращу внимание на то, что, в отличие от вывода в консоль, тут не используется функция println() для завершения вывода и перевода строки.

Таким образом у нас на экране в первой строке появится надпись "Test LCD1602", а во второй будет указано разрешение дисплея и счетчик, показывающий, сколько циклов отработал наш скетч.

Но, если нам надо будет выводить много значений переменных на экран, этот метод не совсем удобен. Дело в том, что процедура вывода на дисплей - очень энергоёмкая и медленная, а вывод мы делаем в этой функции аж 7 раз. Гораздо проще будет заранее сформировать строку заранее, а затем вывести её целиком. В этом нам поможет функция форматированного ввода sprintf().

Небольшое отступление №3: Функция форматированного ввода sprintf().

В Языке C существует несколько очень удобных функций для вывода строк - они называются функциями форматированного вывода - printf (от слов print и format). В нашем конкретном случае нас интересует функция sprintf, которая не выводит ничего на экран, а формирует строку для последующего вывода. Выглядит она примерно так:

sprintf (str , "Строка %d для вывода ", i );

Функция формирует строку (помечено синим) с использованием шаблона (желтым), в который подставляются значения переменных (зеленым). Полученный результат будет записан в строковую переменную (красным).

Шаблонов и переменных может быть несколько. В этом случае переменные записываются через запятую. Главное, следите за тем, чтобы количество шаблонов в строке соответствовало количеству переменных. Переменные для шаблонов берутся последовательно, т.е. в первый шаблон подставляется значение первой переменной, во второй - второй переменной и т.д.

Что же такое шаблоны? Любой шаблон начинается символом "%" и заканчивается одним из десяти (в случае Arduino - семи) символов типа. Между ними может быть указано довольно много информации о том, как выводить значение, а может быть не указано и ничего.

Давайте разберем что же может быть в шаблоне. В общем случае шаблон имеет такой вид:

%[флаг ][ширина ][.точность ]типа

Квадратные скобки показывают, что элемент заключенный в них может отсутствовать. Вертикальная черта говорит о том, что в этом поле должно быть выбрано одно из указанных значений (в нашем случае одна из букв H, I, или L).

Давайте сначала разберемся с обязательным элементом шаблона - типом. Он указывает, какой тип переменной будет выводится и может принимать одно из следующих значений:

Символ Значение
c Один символ
s Строка символов
d,i Целое десятичное со знаком
o Целое восьмеричное
u Целое десятичное без знака
x, X Целое шестнадцатеричное
p Указатель (в шестнадцатеричном виде)
f Дробное число в фиксированном формате
e, E Дробное число в научном формате
g, G Дробное число в научном или фиксированном формате

Серым помечены те типы, которые не применимы при работе с Arduino. Таким образом, для вывода строки надо указать "%s", а для вывода целого числа - "%d".

Далее рассмотрим поле ширины. Число в нем указывает минимальную ширину поля, в котором будет выведен шаблон. Если размер значения в переменной меньше - поле будет добито пробелами, если больше - запись выйдет за пределы поля. Таким образом шаблон "%6d" для числа 385 выведет 385 (обратим внимание на три пробела перед числом).

Спецификатор точности всегда начинается с точки и следующее за ним число указывает различные действия в зависимости от типа значения. Для типов "d,o,u,x" он укажет минимальное количество символов, которое должно появится при обработке. Для типа "f" - число знаков после запятой. Для типа "s" - максимальное число символов стоки, который будут выведены. Например, "%6.1f" для числа 34.2345 выведет "34.1" (обращу внимание, что точка также считается знаком и перед числом будет присутствовать два пробела). Или шаблон "%.3s" от строки "точность" выведет только первые три символа - "точ".

Флаг позволяет изменить отображение выводимого значения:

Более подробно о шаблонах функции printf можно прочитать интернете. Здесь же я дал краткий обзор наиболее часто используемых возможностей.

Таким образом, наша функция вывода, переписанная с учетом использования форматированного вывода будет выглядеть следующим образом:

Заметим, что в строках 33 и 37 мы формируем целую строку для вывода, а в строках 34 и 38 - выводим их.

Наконец, наши любимые функции setup и loop.

В строке 47 мы задаем разрешение дисплея, в строке 48 - включим подсветку (яркость которой можно отрегулировать потенциометром). В строке 49 установим счетчик циклов в ноль. Увеличивать его будем на единицу в 37-й строке при выводе (помните конструкцию count++?). Наконец, в строке 56 вызываем рассмотренную раннее функцию вывода на дисплей. Все.

Что можно поменять или улучшить?

К примеру, можно сделать автоматическое управление подсветкой в зависимости от освещенности, использовав фоторезистор или датчик освещенности из рассмотренной несколькими статьями ранее метеостанции. Допустим, при сильном освещении - увеличить яркость подсветки, а в ночное время - уменьшить. Или прикрутить датчик движения и зажигать подсветку при появлении объект перед дисплеем, или... В общем, я думаю, вы уже поняли, что при желании, заменив один или несколько компонентов и написав кусок кода можно довольно серьезно улучшить удобство работы с дисплеем. Также мы можем использовать для вывода на дисплей собственноручно разработанные символы.

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

А на сегодня у меня все.

Arduino. Подключаем LCD-дисплей

26 оценок, Средняя оценка: 5 из 5

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

В данной статье мы расскажем как его подключить к Arduino и вывести информацию.

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

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

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

Данные дисплеи имеют два исполнения: желтая подсветка с черными буквами либо, что встречается чаще, синюю подсветку с белыми буквами.

Размерность дисплеев на контроллере HD44780 может быть различной, управляться они будут одинаково. Самые распространенные размерности 16x02 (т.е. по 16 символов в двух строках) либо 20x04. Разрешение же самих символов - 5x8 точек.

Большинство дисплеев не имеют поддержку кириллицы, имеют её лишь дисплеи с маркировкой CTK. Но данную проблему можно попытаться частично решить (продолжение в статье).

Выводы дисплея:

На дисплее имеется 16pin разъем для подключения. Выводы промаркированы на тыльной стороне платы.

1 (VSS) - Питание контроллера (-)
2 (VDD) - Питание контроллера (+)
3 (VO) - Вывод управления контрастом
4 (RS) - Выбор регистра
5 (R/W) - Чтение/запись (режим записи при соединении с землей)
6 (E) - Еnable (строб по спаду)
7-10 (DB0-DB3) - Младшие биты 8-битного интерфейса
11-14 (DB4-DB7) - Старшие биты интерфейса
15 (A) - Анод (+) питания подсветки
16 (K) - Катод (-) питания подсветки

Режим самотестирования:

Перед попытками подключения и вывода информации, было бы неплохо узнать рабочий дисплей или нет. Для этого необходимо подать напряжение на сам контроллер (VSS и VDD ), запитать подсветку (A и K ), а также настроить контрастность.

Для настройки контрастности следует использовать потенциометр на 10 кОм. Каким он будет по форме - не важно. На крайние ноги подается +5V и GND, центральная ножка соединяется с выводом VO

После подачи питания на схему необходимо добиться правильного контраста, если он будет настроен не верно, то на экране ничего не будет отображаться. Для настройки контраста следует поиграться с потенциометром.

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

Вывод информации:

Для работы дисплея используется встроенная с среду Arduino IDE библиотека LiquidCrystal.h

Функционал библиотеки

//Работа с курсором lcd.setCursor (0, 0); // Устанавливаем курсор (номер ячейки, строка) lcd.home (); // Установка курсора в ноль (0, 0) lcd.cursor (); // Включить видимость курсора (подчеркивание) lcd.noCursor (); // Убрать видимость курсора (подчеркивание) lcd.blink (); // Включить мигание курсора (курсор 5х8) lcd.noBlink (); // Выключить мигание курсора (курсор 5х8) //Вывод информации lcd.print ("сайт" ); // Вывод информации lcd.clear (); // Очистка дисплея, (удаление всех данных) установка курсора в ноль lcd.rightToLeft (); // Запись производится справа на лево lcd.leftToRight (); // Запись производится слева на право lcd.scrollDisplayRight (); // Смещение всего изображенного на дисплее на один символ вправо lcd.scrollDisplayLeft (); // Смещение всего изображенного на дисплее на один символ влево //Информация полезная для шпионов:) lcd.noDisplay (); // Информация на дисплее становится невидимой, данные не стираются // если, в момент когда данная функция активна, ничего не выводить на дисплей, то lcd.display (); // При вызове функции display() на дисплее восстанавливается вся информация которая была

Сам же дисплей может работать в двух режимах:

8-битный режим - для этого используются и младшие и старшие биты (BB0- DB7)

4-битный режим - для этого используются и только младшие биты (BB4- DB7)

Использование 8-битного режима на данном дисплее не целесообразно. Для его работы требуется на 4 ноги больше, а выигрыша в скорости практически нет т.к. частота обновления данного дисплея упирается в предел < 10раз в секунду.

Для вывода текста необходимо подключить выводы RS, E, DB4, DB5, DB6, DB7 к выводам контроллера. Их можно подключать к либым пинам Arduino, главное в коде задать правильную последовательность.

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

//Тестировалось на Arduino IDE 1.0.5 #include // Лобавляем необходимую библиотеку LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // (RS, E, DB4, DB5, DB6, DB7) void setup (){ lcd.begin (16, 2); // Задаем размерность экрана lcd.setCursor (0, 0); // Устанавливаем курсор в начало 1 строки lcd.print ("Hello, world!" ); // Выводим текст lcd.setCursor (0, 1); // Устанавливаем курсор в начало 2 строки lcd.print ("сайт" ); // Выводим текст } void loop (){ }

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

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

За все время увлечения электроникой мне довелось пользоваться ЖКД от нескольких производителей - DataVision, WINSTAR, Uniworld Technology Corp . Они отличались типом контроллера, количеством выводов и длинною строк, но при этом все имели одинаковую схему подключения, систему команд и обслуживались одной и той же программой со стороны микроконтроллера. Поэтому, хотя речь сейчас пойдет о дисплее WH0802A фирмы WINSTAR , все ниже сказанное применимо к символьным ЖК-дисплеям и других фирм.

Итак, подключаем дисплей WH0802A-YGH-CT к микроконтроллеру

WH0802A – двухстрочный символьный дисплей на 8 знакомест со встроенным управляющим контроллером KS0066.
Разбираем назначение выводов дисплея.

У некоторых дисплеев есть два дополнительных вывода – выводы подсветки +LED и –LED. Причем если выводы есть – это еще не означает что есть и подсветка. Как и наоборот. У моего дисплея подсветка есть, а выводов управления нет.

По умолчанию подсветка у дисплея WH0802A-YGH-CT отключена. Чтобы ее включить, нужно проделать парочку нехитрых манипуляций, а именно – установить две перемычки и впаять токоограничительный резистор (смотри на фотке RK, JF и RA соответственно).

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

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

Начальный код

Подав питание на схему, нужно покрутить регулятор контраста (резистор R1). Если на экранчике появилась верхняя строка, значит, он живой и самое время приступать к написанию кода. На начальном этапе мы будем использовать 8-ми разрядную шину. Чтобы получить первые результаты, нам понадобится написать две функции – функцию записи данных и функцию записи команд. Отличаются они всего одной строчкой – когда записываются данные, сигнал RS должен быть 1, когда записывается команда, RS должен быть 0. Функции чтения мы пока использовать не будем, поэтому сигнал R/W будет всегда 0.

Цикл записи для 8-ми разрядной шины выглядит следующим образом:
1. Установить RS (0 - команда, 1 – данные)
2. Вывести значение байта данных на шину DB7…DB0
3. Установить E=1
4. Программная задержка 1
5. Установить E=0
6. Программная задержка 2

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

Вообще у контроллера дисплея есть так называемый флаг занятости – BF. Если флаг в 1 – контроллер занят, если в 0 – свободен. Вместо второй программной задержки можно читать флаг занятости и проверять, когда контроллер дисплея освободится. Но поскольку мы хотим быстро получить первые результаты, с флагом занятости будем разбираться потом.

//подключаем символьный ЖК-дисплей к AVR
#include
#include

//порт к которому подключена шина данных ЖКД
#define PORT_DATA PORTD
#define PIN_DATA PIND
#define DDRX_DATA DDRD

//порт к которому подключены управляющие выводы
#define PORT_SIG PORTB
#define PIN_SIG PINB
#define DDRX_SIG DDRB

//номера выводов микроконтроллера
//к которым подключены управляющие выводы ЖКД
#define RS 5
#define RW 6
#define EN 7

//макросы для работы с битами
#define ClearBit(reg, bit) reg &= (~(1<<(bit)))
#define SetBit(reg, bit) reg |= (1<<(bit))

#define F_CPU 8000000
#define _delay_us(us) __delay_cycles ((F_CPU / 1000000) * (us));
#define _delay_ms(ms) __delay_cycles ((F_CPU / 1000) * (ms));

//функция записи команды
void LcdWriteCom(unsigned char data)
{
ClearBit(PORT_SIG, RS); // устанавливаем RS в 0
PORT_DATA = data; // выводим данные на шину
SetBit(PORT_SIG, EN); // устанавливаем Е в 1
_delay_us (2);
ClearBit(PORT_SIG, EN); // устанавливаем Е в 0
_delay_us(40);

//функция записи данных

void LcdWriteData(unsigned char data)
{
SetBit(PORT_SIG, RS); //устанавливаем RS в 1
PORT_DATA = data; //выводим данные на шину
SetBit(PORT_SIG, EN); //устанавливаем Е в 1
_delay_us (2);

ClearBit(PORT_SIG, EN); // устанавливаем Е в 0

Delay_us(40);
}

int main(void )
{
while (1);
return 0;
}

Здесь нет сложных мест, все должно быть понятно. Идем дальше.

Любой ЖК-дисплей перед использованием нужно инициализировать. Процесс инициализации обычно описан в datasheet`е на контроллер дисплея. Но даже если там и нет информации, последовательность, скорее всего, будет такая.

1. Подаем питание

2. Ждем >40 мс

3. Подаем команду Function set

DL – бит установки разрядности шины
0 – 4 разрядная шина, 1 – 8 разрядная шина

N – бит установки количества строк дисплея
0 – однострочный режим, 1 – двухстрочный режим

F – бит установки шрифта
0 – формат 5*8, 1 – формат 5*11

* - не важно что будет в этих битах

4. Подаем команду Display ON/OFF

D – бит включения/выключения дисплея
0 – дисплей выключен, 1 – дисплей включен

C – бит включения/выключения курсора
0 – курсор выключен, 1 – курсор включен

B – бит включения мерцания
0 – мерцающий курсор включен, 1 – мерцающий курсор выключен

5. Подаем команду Clear Display


6. Ждем > 1,5 ms

7. Подаем команду Entry Mode Set

I/D – порядок увеличения/уменьшения адреса DDRAM(ОЗУ данных дисплея)
0 – курсор движется влево, адрес уменьшается на 1, 1 – курсор движется вправо, адрес увеличивается на 1

SH – порядок сдвига всего дисплея
0 – сдвига нет, 1 – сдвиг происходит согласно сигналу I/D – если он 0 – дисплей сдвигается вправо, 1 – дисплей сдвигается влево

Для нашего примера функция инициализации будет выглядеть так

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.

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

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

  • Вариант обычного дисплея от довольно известного продавца Wavgat по цене ниже 100 рублей.
  • Комплект экрана и i2c адаптера (нужно спаять самим). Цена – ниже 200 рублей
  • Шилд i2c экрана – модуль LCD 1602 с управляющими кнопками и платой расширения .

Описание протокола 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 аналоговых пина. Во многих ситуациях это может быть очень важным. Плата за удобство – необходимость в использовании дополнительного модуля – конвертера и библиотеки. На наш взгляд, совсем не высокая цена за удобство и мы крайне рекомендуем использовать эту возможность в проектах.

При создании собственного устройства не редко возникает необходимость оперативного вывода разнообразной информации. Например, если вы создаёте контроллер умного дома, то разумно оснастить прибор устройством вывода, позволяющим быстро узнать текущее состояние систем. Лучшим решением является жидкокристаллический дисплей. Энергопотребление при отключённой подсветке минимально а работа с дисплеем предельно проста и не требует сильного вмешательства в код программы. Фактически, вывод информации на ЖК дисплей не многим отличается от вывода в серийный порт. В статье рассмотрено подключение знакогенерирующего дисплея на базе популярного чипа HD44780 к контроллеру Arduino.

Как работает жидкокристаллический текстовый дисплей

Для понимания некоторых нюансов полезно знать как работает знакогенерирующий дисплей. Особенностью работы дисплеев такого типа является наличие своего контроллера с собственной памятью. DDRAM — память дисплея. Для вывода символа на экран необходимо загрузить символ в ячейку памяти, а затем передать команду на отображение ячейки памяти. При передаче символы кодируются ASCII кодами. Например, при записи в память кода 0×31 на дисплей будет выведен символ «1 ». Соответствие кода символа его отображению на экране (т.е. «картинке» символа) хранится в памяти CGROM. CGROM не изменяемая память. Поэтому, дисплей может отображать только те символы, которые «зашиты» в контроллер. Именно поэтому не каждый дисплей способен отображать, например, русские символы. Дисплеи, продающиеся в нашем магазине, к сожалению, не русифицированы. Есть ещё CGRAM память. Она изменяемая. Мы можем создавать собственные символы и отображать их на дисплее. Стоит учитывать, что можно создать не более восьми символов.

Вся эта «подкапотная» работа важна только для понимания некоторых нюансов. Для Arduino существует простая и понятная библиотека, которая выполняет за вас всю черновую работу, позволяя контролировать вывод на дисплей легко и просто.

Подключение жидкокристаллического дисплея к Arduino

Для подключения дисплея его, разумеется, нужно установить на макетную плату. Обратите внимание: дисплеи, продающиеся у нас в магазине продаются без припаянного штырькового разъёма. Если вы хотите получить дисплей сразу готовый к установке на макетку, отметьте галочку «припаять разъём» на странице товара и мы припаяем разъём для вас. Передача данных на дисплей может быть организована двумя способами: по 4 или по 8 бит за раз. Соответственно, потребуется либо 4, либо 8 выводов Arduino. На практике, выигрыша в скорости при использовании восьмибитного интерфейса не будет. Поэтому, нам потребуется только 4 цифровых вывода для передачи данных. Ещё 3 вывода потребуются для задания режима работы дисплея. Итого для подключения дисплея понадобится всего 7 цифровых выходов контроллера. Контакты на дисплее подписаны, что позволит не запутаться при подключении:

Выводы нумеруем слева направо:

  • 1-(VSS ) Земля дисплея. Подключается к рельсе земли.
  • 2-(VDD ) Питание дисплея. Подключается к рельсе питания.
  • 3-(VO ) Вход потенциометра (входит в комплект). С помощью потенциометра регулируется контрастность дисплея. К выводу дисплея подключается средний выход потенциометра.
  • 4-(RS ) Вход «командного» сигнала. Подключается к любому цифровому выводу Arduino. В примере подключён к выводу №12.
  • 5-(RW ) Устанавливает режим «чтения» или «записи». Мы собираемся записывать. Подключаем контакт к земле.
  • 6-(E ) Enable. Ещё один «командный» вывод. Когда на вывод подаётся единица, дисплей выполняет переданную ранее команду. Подключается к любому цифровому выводу. В примере подключен к выводу №11.
  • 7-10 (D0-D3 ) оставляем не подключёнными. Это контакты передачи данных, который используются в восьмибитном интерфейсе. Нам не нужны.
  • 11-14 (D4-D7 ) Контакты для передачи данных в четырёхбитном режиме. Подключаются опять таки к любым цифровым выводам. В примере подключены соответственно к 5,4,3 и 2 выводам (D4 к 5 выводу, D5 к 4 и т.д.).
  • 15 (A ) Анод светодиода подсветки. Токоограничительный резистор уже установлен в дисплее, поэтому анод подключается просто к рельсе питания. Поскольку в подсветке используется самый обычный светодиод, вы можете подключить его к любому выводу, поддерживающему и управлять яркостью подсветки программно.
  • 16 (K ) Катод подсветки. Подключается к рельсе земли.

Визуальная схема подключения:

Программирование

Вместе с Arduino IDE поставляется прекрасная библиотека для жидкокристаллических дисплеев - LiquidCrystal . Библиотека содержит примеры, полностью раскрывающие возможности экрана. Для начала воспользуйтесь стандартным примером «HelloWorld» (Файл -> Примеры -> LiquidCrystal -> HelloWorld) или загрузите в плату следующий код:

/* *RS вывод дисплея к 12 выводу arduino *Enable вывод дисплея к 11 выводу arduino *D4 вывод дисплея к 5 выводу arduino *D5 вывод дисплея к 4 выводу arduino *D6 вывод дисплея к 3 выводу arduino *D7 вывод дисплея к 2 выводу arduino *R/W вывод дисплея к земле *Выход потенциометра к VO выводу дисплея */ // подключаем библиотеку: #include ; // Инициализируем дисплей // Перечисляем выводы arduino к которым подключены // RS, E, D4, D5, D6, D7 контакты дисплея LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { // Указываем количество столбцов и строк дисплея: lcd.begin(16, 2); // Выводим сообщение на дисплей. lcd.print("hello, world!"); } void loop() { // устанавливаем курсор в 0 (нулевой) столбец первой строки // фактически курсор установится во вторую (нижнюю) строку // нумерация строк и столбцов начинается с нуля lcd.setCursor(0, 1); // выводим на дисплей количество секунд, // прошедших с момента загрузки платы: lcd.print(millis()/1000); }

*RS вывод дисплея к 12 выводу arduino

*Enable вывод дисплея к 11 выводу arduino

*D4 вывод дисплея к 5 выводу arduino

*D5 вывод дисплея к 4 выводу arduino

*D6 вывод дисплея к 3 выводу arduino

*D7 вывод дисплея к 2 выводу arduino

*R/W вывод дисплея к земле

*Выход потенциометра к VO выводу дисплея

// подключаем библиотеку:

#include ;

// Инициализируем дисплей

// Перечисляем выводы arduino к которым подключены

// RS, E, D4, D5, D6, D7 контакты дисплея

void setup () {

// Указываем количество столбцов и строк дисплея:

lcd . begin (16 , 2 ) ;

// Выводим сообщение на дисплей.

lcd . print ("hello, world!" ) ;

void loop () {

// нумерация строк и столбцов начинается с нуля

lcd . setCursor (0 , 1 ) ;

// выводим на дисплей количество секунд,

// прошедших с момента загрузки платы:

lcd . print (millis () / 1000 ) ;

После загрузки этого кода в плату Arduino на экране отобразится надпись «hello, world!»(англ. «привет, Мир!» ) на первой строке и таймер, отсчитывающий секунды на второй строке.

Как обычно и бывает, код простой и понятный. Однако, мы всё же разберём его более подробно:

  • LiquidCrystal lcd (12, 11, 5, 4, 3, 2) - эта строка создаёт объект дисплея, с которым мы будем работать в будущем. В скобках в качестве аргументов передаются номера пинов, к которым подключены контакты дисплея. Соответственно: RS, E, D4, D5, D6, D7. Как уже отмечалось выше, номера выводов при подключении можно выбирать совершенно произвольно.
  • lcd.begin (16, 2) - здесь мы настроили размеры дисплея. В данном примере 16 столбцов и 2 строки. Для нашего дисплея 20Х4 эта строчка выглядела бы так: lcd.begin (20, 4).
  • lcd.print («hello, world!») - выводит текст на дисплей. После указания размера дисплея (lcd.begin) курсор устанавливается в левый верхний угол дисплея. Поэтому, этот текст будет выведен на первой (верхней) строке слева.
  • lcd.setCursor (0, 1) - устанавливает курсор на указанную позицию. В данном случае указана крайняя левая позиция второй строки. В скобках задаётся номер столбца, затем номер строки. И строки и столбцы нумеруются с нулевой позиции. Таким образом: lcd.setCursor(0, 0) - установит курсор в левый верхний угол, lcd.setCursor(15, 0) - правый нижний.
  • lcd.print (millis()/1000) - уже описано выше. Здесь вместо текста в качестве параметра передаётся формула для вычисления. Результат выводится на экран.

Теперь, когда мы разобрались с простейшим примером, можно перейти к примерам посложнее. А если вы уже всё поняли и готовы купить ЖК дисплей, то я собрал для вас ссылки на проверенных мной китайских продавцов дисплеев:

Символьные ЖК дисплеи

Размер дисплея (столбцы*строки) Цвет подстветки Статус
20*4 Синий проверено
20*4 Жёлтый проверено
16*2 Синий проверено
16*2 Жёлтый проверено
16*2 Зелёный проверено

Обзор других примеров библиотеки LiquidCrystal

В стандартных примерах, поставляющихся вместе с библиотекой LiquidCrystal можно найти следующие скетчи:

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

    • Blink - демонстрирует возможность включить отображение мигающего курсора в виде прямоугольника.

    • Cursor - демонстрирует возможность включить отображение курсора в виде мигающей горизонтальной черты.

    • CustomCharacter - показана возможность создания собственных символов для отображения их на дисплее. Кстати, в этом скетче ошибка. Подробности ниже.

    • Display - показывает способ «выключать» дисплей. То есть показывать или скрывать выведенный текст.

    • Scroll - демонстрирует возможность прокрутки текста в ручном режиме.

    • SerialDisplay - отображает на экране текст, напечатанный в окне монитора порта (т.е. текст, передающийся через серийный порт).
    • setCursor - заполняет дисплей буквами, демонстрируя возможность установки курсора в любую позицию экрана.
    • TextDirection - демонстрирует возможность изменять направление вывода текста (с права налево или слева направо).

Рассмотрим более подробно процедуры, возможности которых демонстрируют эти примеры:

lcd.autoscroll()

После вызова этой процедуры, текст на экране будет автоматически прокручиваться. Для остановки прокрутки, следует вызвать lcd.noAutoscroll() .

lcd.blink()

После вызова процедуры курсор примет вид мигающего прямоугольника. Для отключения следует вызвать lcd.noBlink()

lcd.cursor()

После вызова процедуры курсор примет вид мигающей горизонтальной черты. Для отключения следует вызвать lcd.noСursor() . Курсор снова станет невидимым.

lcd.createChar()

Процедура загружает в изменяемую таблицу символов экрана (в память CGRAM) символ, описанный в виде байтового массива. В качестве аргумента передаётся номер символа и массив байт, описывающий символ. Остановимся на этом более подробно. Внести в память дисплея можно не более восьми символов. Для добавления своего символа нужно:

  1. Создать байтовый массив, описывающий символ.
  2. Записать символ в память дисплея, присвоив ему номер в таблице символов. Символы нумеруются в диапазоне от нуля до семи.
  3. Вывести символ на экран с помощью процедуры lcd.write() (не путать с lcd.print() ), в качесте аргумента которой передать номер символа.

Баг среды разработки и особенности библиотеки вылились в невозможность вывести на экран символ под номером 0 (ноль). Компилятор повстречав строку lcd.write(0) выдаст ошибку: «call of overloaded ‘write(int)’ is ambiguous «. Именно такая строка встречается в примере CustomCharacter библиотеки. При попытке скомпилировать стандартный пример, вы получите ошибку:

CustomCharacter.ino: In function ‘void setup()’: CustomCharacter:115: error: call of overloaded ‘write(int)’ is ambiguous /home/nazarovd/arduino-1.0.5/libraries/LiquidCrystal/LiquidCrystal.h:82: note: candidates are: virtual size_t LiquidCrystal::write(uint8_t) /home/nazarovd/arduino-1.0.5/hardware/arduino/cores/arduino/Print.h:49: note: size_t Print::write(const char*)

CustomCharacter . ino : In function ‘void setup () ’:

CustomCharacter : 115 : error : call of overloaded ‘write (int ) ’is ambiguous

/ home / nazarovd / arduino - 1.0.5 / libraries / LiquidCrystal / LiquidCrystal . h : 82 : note : candidates are : virtual size_t LiquidCrystal :: write (uint8_t )

/ home / nazarovd / arduino - 1.0.5 / hardware / arduino / cores / arduino / Print . h : 49 : note : size_t Print :: write (const char * )

Для устранения ошибки достаточно изменить строку lcd.write(0 ) на lcd.write((byte)0 ).
Теперь небольшой пример по созданию своего символа. Давайте выведем на дисплей символ рубля .

// Подключаем библиотеку #include ; // Инициализируем дисплей LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Описываем свой символ. // Просто "рисуем" символ единицами // Единицы при выводе на экран окажутся закрашенными точками, нули - не закрашенными byte rubl = { 0b00000, 0b01110, 0b01001, 0b01001, 0b01110, 0b01000, 0b11110, 0b01000, }; void setup() { // записываем свой символ в память экрана // аргументами передаём номер символа // и байтовый массив, описывающий наш символ lcd.createChar(0, rubl); // настраиваем дисплей lcd.begin(16, 2); } void loop() { // устанавливаем курсор в левый верхний угод экрана lcd.setCursor(0,0); // выводим символ с номером ноль на экран lcd.write((byte)0); // ничего не делаем 10 секунд delay(10000); }

// Подключаем библиотеку

#include ;

// Инициализируем дисплей

LiquidCrystal lcd (12 , 11 , 5 , 4 , 3 , 2 ) ;