Raspberry Pi и Pi4J. Урок 7. Работа с LCD на базе HD44780

Информации о том, что из себя представляет LCD на базе HD44780, в интернете очень много. Даже на этом сайте две статьи на эту тему (первая и вторая). Однако в этой статье речь пойдет не о нём, а о библиотеках Pi4J, что позволяют работать с данным дисплеем из Java.

Pi4J предоставляет 3 библиотеки для этих целей:

  1. com.pi4j.wiringpi.Lcd — это библиотека, позволяющая получать доступ к жидкокристаллическим дисплеям с параллельным интерфейсом через GPIO пины. Все методы этого класса нативные, так как вызываются функции wiringPi напрямую. Грубо говоря — это библиотека lcd.h, но только на Java.
  2. com.pi4j.component.lcd.impl.GpioLcdDisplay — это ООП версия com.pi4j.wiringpi.Lcd, что удобнее использовать. Для записи данных на дисплей используются функции com.pi4j.wiringpi.Lcd.
  3. com.pi4j.component.lcd.impl.I2CLcdDisplay — это библиотека для работы с жидкокристаллическими дисплеями через I2C (IIC/TWI), а именно — адаптер на чипе PCF8574. В таком случае для управления дисплеем будет использоваться всего 2 провода вместо 6 или 10.

Pi4J предоставляет возможность работы с LCD из Java на Raspberry Pi, Banana Pi, Orange Pi, Nano Pi и Odroid. Все классы и интерфейсы находятся в пакетах com.pi4j.component.lcd.*; com.pi4j.wiringpi.*; и com.pi4j.gpio.extension.pcf.*.

Ниже представлены описания интерфейсов/классов и примеры программ.

Класс Lcd

Как я уже писал выше, эта библиотека аналогична «wiringPi». Ниже вы найдёте пример программы, которая показывает, как использовать эту библиотеку для отображения строк на ЖК-дисплее.

Все нативные методы класса Lcd:

public static native int 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);
public static native void lcdHome(int handle);
public static native void lcdClear(int handle);
public static native void lcdDisplay(int handle, int state);
public static native void lcdCursor(int handle, int state);
public static native void lcdCursorBlink(int handle, int state);
public static native void lcdPosition(int handle, int x, int y);
public static native void lcdCharDef(int handle, int index, byte data[]);
public static native void lcdPutchar(int handle, byte data);
public static native void lcdPuts(int handle, String data);

Описание этих функций вы найдёте здесь.

Схема подключения LCD в 4-битном режиме

Подключение LCD 1602 HD44780 к Orange Pi в 4-битном режиме

Пример программы в 4-битном режиме

Прежде всего, мы должны выбрать платформу, иначе программа будет работать с ошибками или вообще не будет работать. В моем случае это Orange Pi PC.

PlatformManager.setPlatform(Platform.ORANGEPI);

Затем нам нужно инициализировать контроллер GPIO для работы с ним. Если он не может быть инициализирован, будет сгенерировано исключение.

if (Gpio.wiringPiSetup() != 0) {
  throw new Exception("An error has occurred and the initialization of the GPIO has failed");
}

После этого мы можем инициализировать экземпляр ЖК-дисплея.

int lcdHandle = Lcd.lcdInit(
    LCD_ROWS, /* количество строк */
    LCD_COLUMNS, /* количество символов */
    LCD_BITS, /* количество бит, используемых для связи с ЖК-дисплеем */
    LCD_RS, /* LCD бит RS */
    LCD_E, /* LCD бит Enable */
    LCD_D4, /* LCD бит данных 4 */
    LCD_D5, /* LCD бит данных 5 */
    LCD_D6, /* LCD бит данных 6 */
    LCD_D7, /* LCD бит данных 7 */
    0, 0, 0, 0);

Метод lcdInit генерирует идентификатор lcdHandle, который будет использоваться для связи именно с этим ЖК-дисплеем.

import com.pi4j.platform.Platform;
import com.pi4j.platform.PlatformManager;
import com.pi4j.wiringpi.Gpio;
import com.pi4j.wiringpi.Lcd;

public class WiringPiLcd4Bit {

  public final static int LCD_ROWS = 2;
  public final static int LCD_ROW_1 = 0;
  public final static int LCD_ROW_2 = 1;
  public final static int LCD_COLUMNS = 16;
  public final static int LCD_BITS = 4;

  public final static int LCD_RS = 4; /* RS - Выбор регистра */
  public final static int LCD_E = 5; /* E - Еnable (строб по спаду) */
  public final static int LCD_D4 = 21; /* D4 - бит данных */
  public final static int LCD_D5 = 22; /* D5 - бит данных */
  public final static int LCD_D6 = 23; /* D6 - бит данных */
  public final static int LCD_D7 = 24; /* D7 - бит данных */

  public static void main(String[] args) throws Exception {

    PlatformManager.setPlatform(Platform.ORANGEPI);

    if (Gpio.wiringPiSetup() != 0) {
      throw new Exception("An error has occurred and the initialization of the GPIO has failed");
    }

    int lcdHandle = Lcd.lcdInit(
        LCD_ROWS, /* количество строк */
        LCD_COLUMNS, /* количество символов */
        LCD_BITS, /* количество бит, используемых для связи с ЖК-дисплеем */
        LCD_RS, /* LCD бит RS */
        LCD_E, /* LCD бит Enable */
        LCD_D4, /* LCD бит данных 4 */
        LCD_D5, /* LCD бит данных 5 */
        LCD_D6, /* LCD бит данных 6 */
        LCD_D7, /* LCD бит данных 7 */
        0, 0, 0, 0);

    /* проверяет инициализацию LCD */
    if (lcdHandle == -1) {
      throw new Exception("LCD INIT FAILED");
    }

    Lcd.lcdClear(lcdHandle);
    Lcd.lcdPosition(lcdHandle, 0, LCD_ROW_1);
    Lcd.lcdPuts(lcdHandle, "site:micro-pi.ru");
    Lcd.lcdPosition(lcdHandle, 0, LCD_ROW_2);
    Lcd.lcdPuts(lcdHandle, "Hello, world!");
  }
}

Проверяем код:

  1. создаём java файл и вставляем код;
    nano WiringPiLcd4Bit.java
  2. компилируем файл;
    javac -classpath .:classes:/opt/pi4j/lib/'*' WiringPiLcd4Bit.java
  3. запускаем программу.
    sudo java -classpath .:classes:/opt/pi4j/lib/'*' WiringPiLcd4Bit

Интерфейс LCD

Интерфейс LCD содержит методы для передачи строк и символов на ЖК-дисплей. Интерфейс реализован в двух классах GpioLcdDisplay и I2CLcdDisplay, первый работает с GPIO, а второй работает с I2C контроллером PCF8574.

getRowCount() и getColumnCount()

Методы возвращают число строк и символов соответственно.

int getRowCount();
int getColumnCount();

clear()

Метод void clear() возвращает курсор в начало экрана, заодно стирая всё, что было на дисплее до этого. Метод void clear(int row) стирает один ряд, а void clear(int row, int column, int length) — только нужную часть текста.

void clear();
void clear(int row);
void clear(int row, int column, int length);

setCursorHome() и setCursorPosition()

Метод setCursorHome() устанавливает курсор в исходное положение; setCursorPosition() устанавливает положение курсора для последующего ввода текста.

void setCursorHome();
void setCursorPosition(int row);
void setCursorPosition(int row, int column);

write(…)

Записывает строку данных на ЖК-дисплей.

void write(String data);
void write(String data, Object...arguments);
void write(char[] data);
void write(byte[] data);
void write(char data);
void write(byte data);

write(int, …)

Печатает нужную строку на указанный ряд.

void write(int row, String data, LCDTextAlignment alignment);
void write(int row, String data, LCDTextAlignment alignment, Object...arguments);
void write(int row, String data);
void write(int row, String data, Object...arguments);
void write(int row, char[] data);
void write(int row, byte[] data);
void write(int row, char data);
void write(int row, byte data);

write(int, int, …)

Печатает нужную строку, начиная с указанной позиции.

void write(int row, int column, String data);
void write(int row, int column, String data, Object...arguments);
void write(int row, int column, char[] data);
void write(int row, int column, byte[] data);
void write(int row, int column, char data);
void write(int row, int column, byte data);

writeln(int, …)

Метод печатает текст на жидкокристаллическом индикаторе на указанный ряд, после переводит курсор в начало следующего.

void writeln(int row, String data);
void writeln(int row, String data, Object...arguments);
void writeln(int row, String data, LCDTextAlignment alignment);
void writeln(int row, String data, LCDTextAlignment alignment, Object...arguments);

Перечисление LCDTextAlignment

Это перечисление используется с методами отображения текста на ЖК-дисплее (write и writeln) для выравнивания текста.

  • ALIGN_CENTER — используется для размещения текста в середине экрана;
  • ALIGN_LEFT — для размещения текста слева от экрана;
  • ALIGN_RIGHT — для размещения текста справа.

Класс GpioLcdDisplay

Класс GpioLcdDisplay реализует интерфейс LCD для работы с дисплеем через GPIO. Конструктор класса используется для инициализации ЖК-дисплея 8-битном или 4-битном режиме:

public GpioLcdDisplay(int rows, int columns, Pin rsPin, Pin strobePin, Pin... dataPins)

Параметры:
int rows — количество строк;
int columns — количество символов;
Pin rsPin — пин выбора регистра;
Pin strobePin — пин строба;
Pin... dataPins — пины данных;

Схема подключения LCD в 8-битном режиме

Подключение LCD 1602 HD44780 к Orange Pi в 8-битном режиме

Пример инициализации в 8-битном режиме

import com.pi4j.component.lcd.impl.GpioLcdDisplay;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.OrangePiPin;
import com.pi4j.platform.Platform;
import com.pi4j.platform.PlatformManager;

public class GpioLcd8Bit {

  public final static int LCD_ROWS = 2;
  public final static int LCD_ROW_1 = 0;
  public final static int LCD_ROW_2 = 1;
  public final static int LCD_COLUMNS = 16;
  public final static int LCD_BITS = 4;

  public static void main(String[] args) throws Exception {
    PlatformManager.setPlatform(Platform.ORANGEPI);

    GpioController gpio = GpioFactory.getInstance();

    GpioLcdDisplay lcd = new GpioLcdDisplay(
        LCD_ROWS, /* число строк */
        LCD_COLUMNS, /* число символов */
        OrangePiPin.GPIO_07, /* LCD бит RS */
        OrangePiPin.GPIO_01, /* LCD бит Еnable */
        OrangePiPin.GPIO_04, /* LCD бит данных 0 */
        OrangePiPin.GPIO_05, /* LCD бит данных 1 */
        OrangePiPin.GPIO_11, /* LCD бит данных 2 */
        OrangePiPin.GPIO_21, /* LCD бит данных 3 */
        OrangePiPin.GPIO_22, /* LCD бит данных 4 */
        OrangePiPin.GPIO_23, /* LCD бит данных 5 */
        OrangePiPin.GPIO_24, /* LCD бит данных 6 */
        OrangePiPin.GPIO_25); /* LCD бит данных 7 */

    lcd.clear();
    Thread.sleep(1000);

    lcd.write(LCD_ROW_1, "The Pi4J Project");
    lcd.write(LCD_ROW_2, "site:micro-pi.ru");
    gpio.shutdown();
  }
}

Схема подключения LCD в 4-битном режиме

Подключение LCD 1602 HD44780 к Orange Pi в 4-битном режиме

Пример инициализации в 4-битном режиме

import com.pi4j.component.lcd.impl.GpioLcdDisplay;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.OrangePiPin;
import com.pi4j.platform.Platform;
import com.pi4j.platform.PlatformManager;

public class GpioLcd4Bit {

  public final static int LCD_ROWS = 2;
  public final static int LCD_ROW_1 = 0;
  public final static int LCD_ROW_2 = 1;
  public final static int LCD_COLUMNS = 16;
  public final static int LCD_BITS = 4;

  public static void main(String[] args) throws Exception {
    PlatformManager.setPlatform(Platform.ORANGEPI);

    GpioController gpio = GpioFactory.getInstance();

    GpioLcdDisplay lcd = new GpioLcdDisplay(
        LCD_ROWS, /* число строк */
        LCD_COLUMNS, /* число символов */
        OrangePiPin.GPIO_04, /* LCD бит RS */
        OrangePiPin.GPIO_05, /* LCD бит Еnable */
        OrangePiPin.GPIO_21, /* LCD бит данных 4 */
        OrangePiPin.GPIO_22, /* LCD бит данных 5 */
        OrangePiPin.GPIO_23, /* LCD бит данных 6 */
        OrangePiPin.GPIO_24); /* LCD бит данных 7 */

    lcd.clear();
    Thread.sleep(1000);

    lcd.write(LCD_ROW_1, "The Pi4J Project");
    lcd.write(LCD_ROW_2, "site:micro-pi.ru");
    gpio.shutdown();
  }
}

Класс I2CLcdDisplay

Класс I2CLcdDisplay — это второй класс, который реализует интерфейс LCD.java для передачи данных на ЖК-дисплей через протокол I2C. В этих случаях используются адаптеры на основе чипов PCF8574. В моем случае — это адаптер FC-113 на базе FCF8574AT, что имеет диапазон адресов от 38h до 3Fh.

Этот класс содержит дополнительные методы для включения и выключения подсветки ЖК-дисплея.

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

Подключение LCD 1602 HD44780 к Orange Pi по I2C с использованием адаптера PCF8574
Если хотите подключить LCD к 5В, тогда необходимо использовать I2C преобразователя логических уровней 5-3.3В по линиям SDA и SCL.
Подключение LCD 1602 HD44780 к Orange Pi по I2C с использованием адаптера PCF8574 и I2C Преобразователя логических уровней 5-3.3В

Orange Pi Преобразователь PCF8574
LV/3.3В HV/5.0В
HV VCC
3.3В LV
GND GND GND GND
SDA.0 LV2 HV2 SDA
SCL.0 LV1 HV1 SCL

Пример программы

Эта программа инициализируется для работы с Orange Pi;

PlatformManager.setPlatform(Platform.ORANGEPI);

создает экземпляр класса I2CLcdDisplay. Стоит заметить, что бывают разные адаптеры на базе FCF8574AT и распиновка тоже разная;

I2CLcdDisplay lcd = new I2CLcdDisplay(
    LCD_ROWS, /* число строк */
    LCD_COLUMNS, /* число символов */
    I2CBus.BUS_0, /* I2C шина */
    PCF8574GpioProvider.PCF8574A_0x3F, /* I2C адрес */
    PCF8574Pin.GPIO_03.getAddress(), /* LCD бит подсветки */
    PCF8574Pin.GPIO_00.getAddress(), /* LCD бит RS */
    PCF8574Pin.GPIO_01.getAddress(), /* LCD бит RW */
    PCF8574Pin.GPIO_02.getAddress(), /* LCD бит Еnable */
    PCF8574Pin.GPIO_07.getAddress(), /* LCD бит данных 7 */
    PCF8574Pin.GPIO_06.getAddress(), /* LCD бит данных 6 */
    PCF8574Pin.GPIO_05.getAddress(), /* LCD бит данных 5 */
    PCF8574Pin.GPIO_04.getAddress()); /* LCD бит данных 4 */

записывает строку на ЖК-дисплей на первый ряд по центру;

lcd.write(LCD_ROW_1, "micro-pi.ru", LCDTextAlignment.ALIGN_CENTER);

выключает и включает подсветку;

lcd.setBacklight(false, true);
lcd.setBacklight(true, true);

и выводит текущее время;

while (true) {
  /* записывает строку на ЖК-дисплей: второй ряд по центру */
  lcd.writeln(LCD_ROW_2, formatter.format(new Date()), LCDTextAlignment.ALIGN_CENTER);
  Thread.sleep(1000);
}

Полный код программы:

import java.text.SimpleDateFormat;
import java.util.Date;

import com.pi4j.component.lcd.LCDTextAlignment;
import com.pi4j.component.lcd.impl.I2CLcdDisplay;
import com.pi4j.gpio.extension.pcf.PCF8574GpioProvider;
import com.pi4j.gpio.extension.pcf.PCF8574Pin;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.platform.Platform;
import com.pi4j.platform.PlatformManager;

public class I2cLcdPCF8574AT {

  public final static int LCD_ROWS = 2;
  public final static int LCD_ROW_1 = 0;
  public final static int LCD_ROW_2 = 1;
  public final static int LCD_COLUMNS = 16;

  public static void main(String[] args) throws Exception {
    PlatformManager.setPlatform(Platform.ORANGEPI);

    I2CLcdDisplay lcd = new I2CLcdDisplay(
        LCD_ROWS, /* число строк */
        LCD_COLUMNS, /* число символов */
        I2CBus.BUS_0, /* I2C шина */
        PCF8574GpioProvider.PCF8574A_0x3F, /* I2C адрес */
        PCF8574Pin.GPIO_03.getAddress(), /* LCD бит подсветки */
        PCF8574Pin.GPIO_00.getAddress(), /* LCD бит RS */
        PCF8574Pin.GPIO_01.getAddress(), /* LCD бит RW */
        PCF8574Pin.GPIO_02.getAddress(), /* LCD бит Еnable */
        PCF8574Pin.GPIO_07.getAddress(), /* LCD бит данных 7 */
        PCF8574Pin.GPIO_06.getAddress(), /* LCD бит данных 6 */
        PCF8574Pin.GPIO_05.getAddress(), /* LCD бит данных 5 */
        PCF8574Pin.GPIO_04.getAddress()); /* LCD бит данных 4 */

    /* очищает LCD */
    lcd.clear();
    Thread.sleep(1000);

    /* записывает строку на ЖК-дисплей: первый ряд по центру */
    lcd.write(LCD_ROW_1, "micro-pi.ru", LCDTextAlignment.ALIGN_CENTER);
    Thread.sleep(1000);

    /* выключает подсветку */
    lcd.setBacklight(false, true);
    Thread.sleep(1000);

    /* включает подсветку */
    lcd.setBacklight(true, true);

    SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");

    /* обновляет текущее время каждую секунду */
    while (true) {
      /* записывает строку на ЖК-дисплей: второй ряд по центру */
      lcd.writeln(LCD_ROW_2, formatter.format(new Date()), LCDTextAlignment.ALIGN_CENTER);
      Thread.sleep(1000);
    }
  }
}

Проверяем код:

  1. создаём java файл и вставляем код;
    nano I2cLcdPCF8574AT.java
  2. компилируем файл;
    javac -classpath .:classes:/opt/pi4j/lib/'*' I2cLcdPCF8574AT.java
  3. запускаем программу.
    sudo java -classpath .:classes:/opt/pi4j/lib/'*' I2cLcdPCF8574AT

Результат

Подключение LCD 1602 HD44780 к Orange Pi по I2C с использованием адаптера PCF8574 - Результат Подключение LCD 1602 HD44780 к Orange Pi по I2C с использованием адаптера PCF8574 - РезультатЕсли у Вас будут вопросы — можете задать их в комментариях.

Материалы

LCD Library (HD44780U)
PCF8574_PCF8574A.pdf
Sainsmart 16×2 I2C lcd

Похожие записи

Комментарии 2

  • По поводу подключения LCD по i2c. У вас подключение к плате без преобразования уровней. Разве GPIO Orange PI толерантны к 5В ой логике?

  • Dreams Casino has more than just slot machine games and offers a significant number of table games. The games available are a few Poker and Baccarat games, and under the section “21 games”, you can find a Blackjack section should you want to play that. French Roulette, European Roulette and American Roulette complete Dream Casino’s game collection. They can be easily found under the Speciality section. Having said that, many other games such as Bingo, Dice, Sic Bo, and Keno are also available. All these games can be downloaded or instantly played across many different devices. Embrace the magic of Desert Nights Casino, where dreams soar on the wings of imagination and fortune smiles upon the daring. Sign up today to begin your quest for glory in an online casino that blends the thrill of Vegas with the mystique of a desert oasis and the enchantment of a world where magic knows no bounds.
    https://www.equilitta.com.br/ideas-on-how-to-earn-in-the-jet-x-resources-and-strategies-2025/
    There are also numerous filtering options that allow you to adjust the list of new online casinos to match your preferences. Since many players today prefer mobile casinos, you can select the ‘Mobile-friendly casinos’ filter from the ‘Popular Filters’ section to see the newest options. This section also lets you find new crypto casinos or the latest live dealer casino sites. Mr. Gamble’s listing process for all new online casinos is the industry’s strictest yet most transparent. To receive a rating, licensed operators must demonstrably pass the rigorous multi-round testing by casino experts – putting new casinos under our close review where the team can assess the following categories: Brand-new online casinos are platforms that have launched within the past year and are active on the global market, offering a worldwide experience for players. These casinos are typically built on the latest technology, providing enhanced security features, innovative game selections, and unique bonus structures.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *