В данной статье мы рассмотрим подключение жидкокристаллического (ЖК) дисплея 16x2 к плате Raspberry Pi. ЖК дисплей мы будем подключать к контактам ввода/вывода (GPIO pins) платы Raspberry Pi. Также мы рассмотрим написание программы на Python, с помощью которой мы будем передавать команды и символы на экран ЖК дисплея. Рассматриваемый в данной статье ЖК дисплей 16x2 отлично подходит для отображения различной информации от датчиков и о состоянии подключенных периферийных устройств.
В настоящее время производится достаточно много типов ЖК дисплеев. Графические ЖК дисплеи более сложные по устройству чем алфавитно-цифровые (как в нашем проекте). В этой статье мы будем использовать ЖК дисплей 16x2, который также можно использовать и как дисплей 16x1. ЖК дисплей 16x2 может одновременно отображать 32 символа: 16 на первой строке и 16 на второй. Достаточно подробно про принципы подключения ЖК дисплея 16x2 к микроконтроллерам описано в статье про его подключение к микроконтроллеру AVR – во многом описываемое в этой статье его подключение к плате Raspberry Pi похоже именно на его подключение к микроконтроллеру AVR. Также на нашем сайте мы рассматривали подключение ЖК дисплея 16x2 к плате Arduino, но там все намного проще (по сравнению с его подключением к AVR и Raspberry Pi) поскольку все рутинные функции берет на себя специальная библиотека для Arduino.
Схема расположения контактов ввода/вывода (GPIO) на плате Raspberry Pi 2 показана на следующем рисунке. Более подробно об этих контактах вы можете прочитать в статье про мигание светодиода с помощью Raspberry Pi.
Каждый из 17 универсальных контактов ввода/вывода (GPIO) может выдерживать ток до 15mA. А суммарный ток от всех контактов ввода/вывода не должен превышать 50mA – таким образом, в среднем на каждый контакт будет приходиться ток примерно 3mA.
Также на плате Raspberry Pi присутствуют силовые контакты +5V (Pin 2 & 4) и +3.3V (Pin 1 & 17), от которых можно запитывать различные датчики и модули. В нашем проекте мы будем подавать питание на ЖК дисплей от силовых контактов +5V. Мы можем передавать управляющие сигналы напряжением +3.3V на ЖК дисплей и он будет их воспринимать, но для его питания обязательно напряжение +5V, он не будет работать если вы попытаетесь его запитать от напряжения +3.3V.
Необходимые компоненты
- Плата Raspberry Pi 2 Model B или другая аналогичная (купить на AliExpress).
- ЖК дисплей 16x2 (купить на AliExpress).
- Резистор 1 кОм – 2 шт. (купить на AliExpress).
- Потенциометр 10 кОм (купить на AliExpress).
- Конденсатор 1000 мкФ (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Схема проекта
Схема подключения ЖК дисплея 16x2 к плате Raspberry Pi представлена на следующем рисунке.
Как показано на схеме, мы подключили ЖК дисплей 16x2 к 10 контактам ввода/вывода (GPIO pins) платы Raspberry Pi. Эти 10 контактов будут использоваться для управления ЖК дисплеем и передачи ему данных. Мы использовали контакты 21, 20, 16, 12, 25, 24, 23 и 18 в качестве BYTE (то есть по ним мы будем непосредственно передавать данные). Контакт GPIO21 в данном случае будет играть роль младшего значащего бита (Least Significant Bit, LSB), а контакт GPIO18 – роль старшего значащего бита (Most Significant Bit, MSB).
Модуль ЖК дисплея 16x2 имеет 16 контактов, которые можно разделить на 5 категорий: Power Pins (силовые контакты), contrast pin (контакт для управления контрастностью), Control Pins (управляющие контакты), Data pins (контакты для передачи данных) и Backlight pins (контакты подсветки). Краткое описание этих контактов приведено в следующей таблице (описание контактов не переводил - этой информации на русском полно в сети).
Общие принципы передачи данных с Raspberry Pi на ЖК дисплей
Вкратце, процесс передачи данных от платы Raspberry Pi на ЖК дисплей состоит из следующих основных операций:
- Контакт E ЖК дисплея устанавливается в состояние high (разрешение на работу дисплея), а контакт RS устанавливается в состояние low (сообщаем ЖК дисплею что мы будем передавать команду).
- Передаем на порт данных (data port) команду 0x01 – это команда очистить экран.
- Контакт E ЖК дисплея устанавливается в состояние high (разрешение на работу дисплея), контакт RS также устанавливается в состояние high (сообщаем ЖК дисплею что мы будем передавать данные).
- Передаем ASCII код символа, который необходимо отобразить на экране дисплея.
- Контакт E ЖК дисплея устанавливается в состояние low (сообщаем ЖК дисплею что мы закончили процесс передачи данных).
- Как только на контакте E будет уровень low, ЖК дисплей обрабатывает принятые данные и показывает результат на своем экране. Таким образом, контакт E необходимо устанавливать в high перед передачей данных и устанавливать в low после завершения передачи данных.
Символы, которые необходимо отобразить на экране, мы будем передавать ЖК дисплею последовательно – один за другим. Точнее сказать, мы будем передавать не сами символы, а их ASCII коды (American standard Code for Information Interchange). Таблица ASCII кодов приведена на рисунке ниже. К примеру, чтобы отобразить на экране ЖК дисплея символ “@”, мы должны передать шестнадцатеричный код 40”. А если мы передадим ЖК дисплею значение 0x73, то на его экране отобразится символ “s”. В этом проекте мы с помощью передачи ЖК дисплею соответствующих ASCII кодов отобразим на его экране строку “CIRCUITDIGEST”.
Объяснение программы для Raspberry Pi
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
После того, как все необходимые соединения в схеме сделаны, мы можем подать питание на Raspberry Pi и после загрузки ее операционной системы можно начать писать программу в ней на Python.
В программе нам первым делом необходимо подключить (импортировать) библиотеку для работы с контактами ввода/вывода. Также мы импортируем эту библиотеку RPi.GPIO под именем “IO” (то есть переименовываем ее для использования в программе), то есть далее в программе всегда, когда мы захотим обратиться к контактам ввода/вывода, мы будем использовать слово ‘IO’.
1 |
import RPi.GPIO as IO |
Иногда контакты ввода/вывода (GPIO pins), которые мы собираемся использовать в программе, могут выполнять другие функции. В этом случае во время исполнения программы мы будем получать предупреждения (warnings). Следующей командой мы укажем плате Raspberry Pi на то, чтобы она игнорировала эти предупреждения и продолжала исполнение программы.
1 |
IO.setwarnings(False) |
Мы можем обращаться к контактам ввода/вывода (GPIO pins) платы Raspberry Pi используя либо номер контакта на плате, либо его функциональный номер. Например, если смотреть распиновку контактов ввода/вывода платы Raspberry Pi, то можно увидеть, что в ней обозначение GPIO5 соответствует контакту PIN 29. То есть в зависимости от того, какой способ обращения к контактам мы выбрали, мы можем обращаться к рассмотренному контакту либо по номеру ‘29’, либо по номеру ‘5’. В данном проекте мы выберем способ обращения к контактам по их функциональным номерам, поэтому используем следующую команду:
1 |
IO.setmode (IO.BCM) |
Контакты платы Raspberry Pi, к которым подключен ЖК дисплей, инициализируем в качестве цифровых выходов – с них мы будем передавать данные ЖК дисплею и управлять режимами его работы.
1 2 3 4 5 6 7 8 9 10 |
IO.setup(6,IO.OUT) IO.setup(22,IO.OUT) IO.setup(21,IO.OUT) IO.setup(20,IO.OUT) IO.setup(16,IO.OUT) IO.setup(12,IO.OUT) IO.setup(25,IO.OUT) IO.setup(24,IO.OUT) IO.setup(23,IO.OUT) IO.setup(18,IO.OUT) |
Команду "while 1:" мы будем использовать для создания бесконечного цикла, внутри него все команды будут исполняться непрерывно.
Исходный код программы на Python
В результате исполнения программы вы увидите как на экране ЖК дисплея отобразится строка “CIRCUITDIGEST”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
import RPi.GPIO as IO # подключение библиотеки для работы с контактами ввода/вывода import time # подключение библиотеки для работы с задержками import sys IO.setwarnings(False) # отключаем показ любых предупреждений IO.setmode (IO.BCM) # мы будем программировать контакты GPIO по их функциональным номерам (BCM), то есть мы будем обращаться к PIN29 как ‘GPIO5’ IO.setup(6,IO.OUT) # инициализируем GPIO6 в качестве цифрового выхода IO.setup(22,IO.OUT) IO.setup(21,IO.OUT) IO.setup(20,IO.OUT) IO.setup(16,IO.OUT) IO.setup(12,IO.OUT) IO.setup(25,IO.OUT) IO.setup(24,IO.OUT) IO.setup(23,IO.OUT) IO.setup(18,IO.OUT) def send_a_command (command): # функция для передачи команды на ЖК дисплей pin=command PORT(pin); # вызываем функцию 'PORT' чтобы передать значение на порт данных IO.output(6,0) # устанавливаем 0 на контакте RS чтобы сообщить ЖК дисплею что мы будем передавать команду IO.output(22,1) # даем команду ЖК дисплею принять команду/данные при помощи установки на контакте EN уровня high time.sleep(0.05) IO.output(22,0) # устанавливаем на контакте EN уровень low чтобы сообщить ЖК дисплею что мы закончили передачу данных pin=0 PORT(pin); # очищаем контакты порта чтобы остановить передачу def send_a_character (character): # функция для передачи символа pin=character PORT(pin); IO.output(6,1) IO.output(22,1) time.sleep(0.05) IO.output(22,0) pin=0 PORT(pin); def PORT(pin): # функция для установки значения PIN на порт данных if(pin&0x01 == 0x01): IO.output(21,1) # если bit0 из 8bit 'pin' is true, на PIN21 устанавливаем high else: IO.output(21,0) # если bit0 of 8bit 'pin' is false, на PIN21 устанавливаем low if(pin&0x02 == 0x02): IO.output(20,1) # если bit1 of 8bit 'pin' is true, на PIN20 устанавливаем high else: IO.output(20,0) # если bit1 of 8bit 'pin' is true, на PIN20 устанавливаем low if(pin&0x04 == 0x04): IO.output(16,1) else: IO.output(16,0) if(pin&0x08 == 0x08): IO.output(12,1) else: IO.output(12,0) if(pin&0x10 == 0x10): IO.output(25,1) else: IO.output(25,0) if(pin&0x20 == 0x20): IO.output(24,1) else: IO.output(24,0) if(pin&0x40 == 0x40): IO.output(23,1) else: IO.output(23,0) if(pin&0x80 == 0x80): IO.output(18,1) # если bit7 of 8bit 'pin' is true на PIN18 устанавливаем high else: IO.output(18,0) # если bit7 of 8bit 'pin' is false на PIN18 устанавливаем low while 1: send_a_command(0x01); # передача команды 'all clear' (очистить все) send_a_command(0x38); # режим 16*2 на ЖК дисплее send_a_command(0x0E); # включаем экран и курсор на нем send_a_character(0x43); # ASCII код для 'C' send_a_character(0x49); # ASCII код для 'I' send_a_character(0x52); # ASCII код для 'R' send_a_character(0x43); # ASCII код для 'C' send_a_character(0x55); # ASCII код для 'U' send_a_character(0x49); # ASCII код для 'I' send_a_character(0x54); # ASCII код для 'T' # ASCII коды для строки символов 'DIGEST' send_a_character(0x44); send_a_character(0x49); send_a_character(0x47); send_a_character(0x45); send_a_character(0x53); send_a_character(0x54); time.sleep(1) |