Raspberry + дисплей по I2C + Python

В данной статье мы подключим Модуль дисплея 1602 + I2C адаптер к нашей плате Raspberry Pi 2 - Model B

Модуль дисплея 1602 с адаптером I2C

Для начала посмотрим на наш дисплей. К нему припаяна плата с микросхемой PCF8574AT, которая преобразует сигналы стандартной шины I2C в сигналы, понятные контроллеру дисплея. Для чего это сделано? А для того, чтобы не занимать больше десяти ножек разъёма GPIO платы Raspberry, а обойтись всего двумя сигнальными проводами и двумя проводами питания.

Модуль I2C для дисплея

Будьте осторожны! Уровни сигналов платы Raspberry составляют 3,3 В, а дисплея - 5 В. Поэтому если вы подключите дисплей напрямую к плате, что-нибудь обязательно сгорит.

Чтобы этого не произошло, потребуется использовать преобразователь уровней с 3,3 В до 5 В:

Преобразователь уровней

Порядок подключения преобразователя:

Преобразователь уровней Raspberry PI  Адаптер I2C дисплея
 LV  3,3В (вывод 1)
 LV1  SDA (вывод 3)
 LV2  SCL (вывод 5)
 GND  GND (вывод 6)  GND
 HV  5В (вывод 2)  VCC
 HV1  SDA
 HV2  SCL

 

Следующий шаг - включение и настройка интерфейса I2C в ОС нашей Raspberry

Запустим утилиту настроек Raspberry

sudo raspi-config

raspi-config

 

Переходим к пункту "8 Advanced Options", выбираем "A7 I2C", а затем "Yes".

Утилита запросит, хотите ли вы включить интерфейс, выберите "Yes" и "Ok".

Далее на вопрос загружать-ли модуль по умолчанию выбираем "Yes", затем "Ok" и "Finish" для возврата в командную строку.

Отредактируем файл модулей

sudo nano /etc/modules

и добавим в него две строки

i2c-bcm2708
i2c-dev

Нажмите Ctrl-X, Y и Enter для сохранения файла и выхода.

Установка утилит

Для облегчения отладки и возможности использования интерфейса I2C в языке Python мы можем установить модули python-smbus и i2c-tools:

sudo apt-get update
sudo apt-get install -y python-smbus i2c-tools

Выключаем компьютер

sudo halt

Проверим работу интерфейса I2C

После подключения дисплея к Raspberry проверим работу интерфейса. Это можно сделать при помощи команды i2cdetect, которая выдаёт список всех доступных устройств на шине I2C:

sudo i2cdetect -y 0

для плат rev. 1 (B Rev 1)

или

sudo i2cdetect -y 1

для плат rev. 2 (A, B Rev 2 или B+)

Результат выполнения команды:

i2cdetect

Результат выполнения команды i2cdetect

На картинке видно, что к нашей плате Raspberry PI подключено три устройства:

  • дисплей с адресом #27
  • микросхема AT24C32 памяти EEPROM с адресом #50
  • часы реального времени DS1307 с адресом #68. Отметка "UU" означает, что данный адрес в настоящий момент используется.

У вас могут быть указаны другие адреса: #28, #24 или любой другой. Проверить какой именно адрес занимает ваш дисплей можно отключив его от платы Raspberry и запустив ещё раз команду i2cdetect.

Python: первый скрипт

Запустим следующий файл

#!/usr/bin/python
#--------------------------------------
#    ___  ___  _ ____
#   / _ \/ _ \(_) __/__  __ __
#  / , _/ ___/ /\ \/ _ \/ // /
# /_/|_/_/  /_/___/ .__/\_, /
#                /_/   /___/
#
#  lcd_i2c.py
#  LCD test script using I2C backpack.
#  Supports 16x2 and 20x4 screens.
#
# Author : Matt Hawkins
# Date   : 20/09/2015
#
# http://www.raspberrypi-spy.co.uk/
#
# Copyright 2015 Matt Hawkins
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#--------------------------------------
import smbus
import time

# Define some device parameters
I2C_ADDR  = 0x27 # I2C device address - установка адреса устройства
LCD_WIDTH = 16   # Maximum characters per line - максимальное количество знаков в строке

# Define some device constants - определим некоторые константы
LCD_CHR = 1 # Mode - Sending data - отправка данных
LCD_CMD = 0 # Mode - Sending command - отправка команды

LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line - адрес в RAM дисплея для первой строки
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line - адрес в RAM дисплея для второй строки
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line - адрес в RAM дисплея для третье строки
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line - адрес в RAM дисплея для четвёртой строки

LCD_BACKLIGHT  = 0x08  # On - подсветка включена
#LCD_BACKLIGHT = 0x00  # Off - подсветка выключена

ENABLE = 0b00000100 # Enable bit

# Timing constants - временные константы
E_PULSE = 0.0005
E_DELAY = 0.0005

#Open I2C interface - открытие интерфейса
#bus = smbus.SMBus(0)  # Rev 1 Pi uses 0
bus = smbus.SMBus(1) # Rev 2 Pi uses 1

def lcd_init():
  # Initialise display
  lcd_byte(0x33,LCD_CMD) # 110011 Initialise - инициализация
  lcd_byte(0x32,LCD_CMD) # 110010 Initialise - инициализация
  lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction - направление движения курсора
  lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off  - дисплей включён, курсор показывает, мигание курсора выключено
  lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size - длина данных, количество строк, размер шрифта
  lcd_byte(0x01,LCD_CMD) # 000001 Clear display - очистка дисплея
  time.sleep(E_DELAY)

def lcd_byte(bits, mode):
  # Send byte to data pins
  # bits = the data
  # mode = 1 for data
  #        0 for command

  bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
  bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT

  # High bits
  bus.write_byte(I2C_ADDR, bits_high)
  lcd_toggle_enable(bits_high)

  # Low bits
  bus.write_byte(I2C_ADDR, bits_low)
  lcd_toggle_enable(bits_low)

def lcd_toggle_enable(bits):
  # Toggle enable
  time.sleep(E_DELAY)
  bus.write_byte(I2C_ADDR, (bits | ENABLE))
  time.sleep(E_PULSE)
  bus.write_byte(I2C_ADDR,(bits & ~ENABLE))
  time.sleep(E_DELAY)

def lcd_string(message,line):
  # Send string to display

  message = message.ljust(LCD_WIDTH," ")

  lcd_byte(line, LCD_CMD)

  for i in range(LCD_WIDTH):
    lcd_byte(ord(message[i]),LCD_CHR)

def main():
  # Main program block - главный блок программы

  # Initialise display  - инициализируем дисплей
  lcd_init()

  while True:

    # Send some test - отправим на дисплей тестовые строки 
    lcd_string("RPiSpy         <",LCD_LINE_1)
    lcd_string("I2C LCD        <",LCD_LINE_2)

    time.sleep(3)

    # Send some more text - ещё текст
    lcd_string(">         RPiSpy",LCD_LINE_1)
    lcd_string(">        I2C LCD",LCD_LINE_2)

    time.sleep(3)

if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
  finally:
    lcd_byte(0x01, LCD_CMD)

командой

sudo python lcd_i2c.py

Залишити відповідь