понедельник, 2 сентября 2013 г.

Подключение LCD дисплея к Raspberry Pi

Кто бы мог подумать еще в 2010 году, что такое явление как "Raspberry Pi" обретет тысячи поклонников по всему миру.
Не смог пройти мимо и я.
Сегодня я покажу на примере как подключать и использовать LCD (хотя аббревиатура уже включает в себя слово "дисплей" далее я будут все равно его использовать) совместно с Raspberry Pi. Скажу сразу: статья ориентирована на тех, кто не первый раз сталкивается с Raspberry.


Пример подключения LCD дисплея к Raspberry Pi

На борту Raspberry Pi имеет особый разъем типа GPIO. К нему-то мы и подключим дисплей.
Распиновка разъема GPIO представлена в таблице ниже:
Таблица 1.

Выбор LCD дисплея

Для наших целей подойдет любой жидкокристаллический знакосинтезирующий (символьный) дисплей на базе микроконтроллера Hitachi HD44780U или его аналогов.
Почему знакосинтезирующий? 
Все просто: в одном разряде можно отобразить только 1 знак из заданного набора, который хранится во внутренней ROM микроконтроллера. У каждого экземпляра LCD может быть свой набор с дополнительными знаками. Более того, микроконтроллеры некоторых LCD дисплеев позволяют создавать и сохранять свои знаки в EEPROM микроконтроллера.
LCD дисплеи бывают 8x2, 16x2, 4x20 и т.д. - строк на количество знаков. Их выпускает куча разных фирм - Winstar, МЭЛТ и другие.
Для сборки прототипа я приобрел дисплей Winstar WH0802A-YYH-CT. 
Документация (datasheet) на дисплей тут.

Сборка прототипа

Для сборки прототипа я раздобыл макетную печатную плату, цветной шлейф, разъем IDC 26P типа "мама" и латунные стойки для монтажа плат.

Разъем IDC я "подписал" для удобства сборки. Файл с подписями можно скачать тут.


Теперь нужно определиться с порядком соединения пинов на разъеме IDC с пинами на GPIO, плюс разобраться как мы подключим питание к нашему дисплею.
Оказывается все просто! В документации находим таблицу с распиновкой порта LCD дисплея для 4-х битного режима и дополняем ее следующим образом:
Таблица 2.
Где GND - это "минус", а +5V - "плюс" питания, которое мы берем все из того же GPIO разъема. 
Подписи GPIO - соответствуют ... ну вы сами догадались)
Данный дисплей имеет подсветку. Для ее включения достаточно подключить LEDA к +5V, а LEDK - к GND.

!ВНИМАНИЕ! 
Для использования LCD дисплея в данной схеме ваш источник питания, который вы подключаете к Raspberry Pi, должен быть рассчитан на потребляемый ток, как минимум, 2А.
!ВНИМАНИЕ! 

Далее паяем, собираем...


Выбор и использование библиотек для работы с LCD дисплеем

Для работы с LCD дисплеем нам нужно написать программу. Делать это я буду на языке Си. Но для компиляции листинга нам потребуется загрузить набор библиотек. Мой выбор пал на  пакет библиотек wiringPi, который был использован в статье. Сам пакет предназначен не только для подключения LCD дисплея.
Процесс установки пакета описан на сайте.

Листинг "mylcd.c" с текстом программы я привожу ниже (по стандарту С99).
 
#include <stdio.h>  //стандартная библиотека ввода-вывода
#include <wiringPi.h>  //библиотека из пакета wiringPi
#include <lcd.h>  //библиотека из пакета wiringPi

int main (void)
{
 printf ("Raspberry Pi LCD test\n") ;
 //Инициализация порта GPIO
 if(wiringPiSetup ()==-1)
 {
  printf ("GPIO Setup failed!\n") ;
 }

 int fd;
 printf ("Start LCD initialization...\n") ;
 //Инициализация LCD
 fd = lcdInit (2,8,4, 11,10, 1,0,2,3,0,0,0,0);

 if(fd==-1)
 {
  printf ("Initialization failed\n") ;
 }
 else
 {
  printf ("GO!\n");

  //Очистка дислпея
  lcdClear(fd);
  
  //Перевод каретки на первую позицию первой строки
  lcdPosition (fd,0,0);
  
  //Вывод форматированного текста
  lcdPrintf(fd, "Hello Pi");

  //Перевод каретки на вторую строку и вывод текста
  lcdPosition (fd,0,1);
  lcdPrintf(fd, " World!");
 }
 return 0;
}
 
В листинге нас особо интересует следующие функции:
  1. wiringPiSetup() - функция для инициализации порта GPIO
  2. lcdInit(int rows, int cols, int bits, int rs, int strb, int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7)  - функция для инициализации LCD дисплея, где:
    * int rows - число строк дисплея (у нас 2)
    * int cols - число знаков в строке (у нас 8)
    * int rs - маппинг порта wiringPi на управляющий регистр дисплея RS (у нас 11)
    * int strb - маппинг порта wiringPi  разрешающий регистр дисплея E (у нас 10)
    * int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7 - маппинг портов wiringPi на шину данных дисплея
  3. lcdPrintf(int handle, char *message, …) - в качестве int handle передаем указатель на дисплей, * message - указываем в кавычках текст для вывода
Теперь чуть подробнее про маппинг. В wiringPi используется понятие мапинга (привязки) физических пинов порта GPIO к "виртуальным" пинам - wiringPi. 
Таблица 3 с маппингом приведена ниже.
Сопоставив ее с таблицей 1 мы и получим комбинацию fd = lcdInit (2,8,4, 11,10, 1,0,2,3,0,0,0,0);
Пины int d4, int d5, int d6, int d7 в 4-х битном режиме не используются!
Таблица 3.

Итак, мы сохранили листинг с программой в файле "mylcd.c" в директории /home/pi/wiringPi/ (которая создается автоматически после установки пакета).
Далее для компиляции кода набираем в консоли:
gcc -Wall -o mylcd wiringPi/mylcd.c -lwiringPi -lwiringPiDev

Если не вывелось никаких "ворнингов" и "эрроров" - значит повезло программа написана верно!
Для запуска программы набираем в консоли:
sudo ./mylcd

Получаем диагностические сообщения, которые мы сами и выводим:
Raspberry Pi LCD test
Start LCD initialization...
GO!

Вывод в консоли:

Смотрим на результат:

UPDATE 25.01.2014

Недавно ко мне попал новый дисплей МЭЛТ MT–20S4A, который имеет 4 строки по 20 знаков в каждой.
Ниже привожу несколько фотографий процесса подключения данного дисплея к Raspberry Pi.





Таблица подключения проводников приведена на рисунке ниже.

Для вывода текста на дисплей 20x4 нам потребуется незначительно изменить код программы, листинг которой я привел ниже.
 
#include <stdio.h>  //стандартная библиотека ввода-вывода
#include <wiringPi.h>  //библиотека из пакета wiringPi
#include <lcd.h>  //библиотека из пакета wiringPi

int main (void)
{
 printf ("Raspberry Pi LCD test\n") ;
 //Инициализация порта GPIO
 if(wiringPiSetup ()==-1)
 {
  printf ("GPIO Setup failed!\n") ;
 }

 int fd;
 printf ("Start LCD initialization...\n") ;
 //Инициализация LCD
 fd = lcdInit (4,20,4, 11,10, 1,0,2,3,0,0,0,0);

 if(fd==-1)
 {
  printf ("Initialization failed\n") ;
 }
 else
 {
  printf ("GO!\n");

  //Очистка дислпея
  lcdClear(fd);
  
  //Перевод каретки на первую позицию первой строки
  lcdPosition (fd,0,0);
  
  //Вывод форматированного текста
  lcdPrintf(fd, "Hello Pi");

  //Перевод каретки на вторую строку и вывод текста
  lcdPosition (fd,0,1);
  lcdPrintf(fd, " World!");

  //Перевод каретки на третью строку и вывод текста
  lcdPosition (fd,0,2);
  lcdPrintf(fd, "25-01-2014");

  //Перевод каретки на четвертую строку и вывод текста
  lcdPosition (fd,0,3);
  lcdPrintf(fd, "Happy New Year))))");
 }
 return 0;
}
 

Как видно из листинга, в функции lcdInit() в двух первых аргументах теперь мы передаем количество строк = 4 и количество символов в строке = 20.
Далее мы дополнительно вызываем функции lcdPosition() и lcdPrintf() чтобы вывести текст на третью и четвертую строки.
Результат работы программы приведен на рисунке ниже.


Ниже привожу несколько фото дисплея в корпусе от DIR-320.








Подведем итоги

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

Полезные ссылки

Комментариев нет:

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