RaspberryPIにI2C接続した2004液晶をKlipperから使う

はじめに

Raspberry PIにI2C接続した2004液晶をklipperのディスプレイとして使う方法について書く。

動機

Klipperで3Dプリンタを運用していると、3Dプリンタについてる液晶ディスプレイに温度などの情報が表示されなくなったので、その代わりに表示したかった。

RaspberryPiにOLEDディスプレイを接続してKliiperのディスプレイとして扱う例をみて、もう少しサイズの大きいディスプレイで表示したいと思った。

ブロック図

ブロック図

  • 3Dプリンタの制御にKlipperをインストールしたRaspberryPiを使う
  • RaspberryPIのGPIOに2004液晶を接続して利用する
  • KlipperをインストールしたRaspberryPiを3DプリンタのセカンドMCUとして利用する。

目次

必要なハードウェア

ハードウェア 用途 仕様とか
3Dプリンタ Klipperに対応しているやつなら何でもOK
RaspberryPI Klipper,moonraker,mainsailを動かす
3DプリンタのセカンドMCUとして使う
2004液晶ディスプレイを駆動する
Raspbian bullseye
i2c接続の2004液晶ディスプレイ Klipperのディスプレイとして情報を表示する I2C接続
LCDディスプレイのコントローラがHD44780で、
PCF8574TがI/Oエキスパンダとしてついてるタイプ
I2Cロジックレベル変換ボード LCD用の5V電源からraspberry piのGPIOに電流が流れ込んで壊れるのを防ぐためにいれる PCA9306

I2C接続の2004液晶ディスプレイ

Amazon: Longruner Display R3 Mega2560 2004 LCD Display Module IIC/I2C/TWI Blue Screen Panel Extension Board with 4-Pin Jumper Wire LK51

  • Amazonで売ってるarduino用のよくあるやつ
  • LCD側のコントローラがHD44780
  • PCF8574がi2cのI/Oエキスパンダとしてついてるタイプ
  • 5V駆動なのでI2Cのロジックレベル変換モジュール経由でRaspberry PIに接続

ロジックレベル変換ボード

switch-science: PCA9306搭載 ロジックレベル変換ボード スイッチサイエンス版

ediy-fan.com

配線

Raspberry PIのGPIO端子 ロジックレベル変換ボード 3.3V側 ロジックレベル変換ボード 5V側 2004液晶ディスプレイ(PCF8574T)
1: 3.3V— —VREF1
2: 5V— —VREF2
3: SDA— —SDA1 SDA2— —SDA
4: 5V— —VCC
5: SCL— —SCL1 SCL2— —SCL
9: GND— —GND GND— —GND

pinout.xyz

raspberry piをセカンドMCUとして設定する

Klipperの公式ドキュメントに従って、raspberry pi3DプリンタのセカンドMCUとして設定する。 I2C接続の液晶ディスプレイを使うので、「Optional: Enabling I2C」の部分も実行する。

www.klipper3d.org

klipper-mcuサービスの確認

systemctlを使って確認する

systemctl status klipper-mcu.service
● klipper-mcu.service - Starts the MCU Linux firmware for klipper on startup
     Loaded: loaded (/etc/systemd/system/klipper-mcu.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2023-07-12 21:46:43 JST; 1h 5min ago
       Docs: https://www.klipper3d.org/RPi_microcontroller.html
   Main PID: 396 (klipper_mcu)
      Tasks: 1 (limit: 1595)
        CPU: 2.906s
     CGroup: /system.slice/klipper-mcu.service
             └─396 /usr/local/bin/klipper_mcu -r -I /tmp/klipper_host_mcu

Jul 12 21:46:43 klipper systemd[1]: Started Starts the MCU Linux firmware for klipper on startup.

液晶ディスプレイの動作確認

raspberry piに接続した液晶ディスプレイがちゃんと動くか確認する。

i2cdetectの確認

sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

circuitpythonのhd44780ライブラリを使った確認

github.com

こいつはPCF8574Tにも対応しているらしい circuit python用なのでadafruitのblinkaをraspberry piにインストールする。

blinkaのインストール

learn.adafruit.com

blog.goediy.com

circuitpython-hd44780のサンプルを使った確認

exampleフォルダにlibフォルダに入ってるhd44780.pyへのシンボリックリンクを作成する

ln -s ../lib/hd44780.py hd44780.py
  • main.py
    • Hello CircuitPythonと表示したり、バックライトをON/OFFする。
  • show_charset.py
    • 文字セットを表示する
    • 半角カナが入ってた。

Klipperの改造

klipperのLCDコントロール部分の改造

spi接続のLCDコントローラhd44780用のソースコードがある。

klippy/extras/display/hd44780_spi.py

これを改造してi2c接続用にする

--- hd44780_spi.py   2022-12-16 02:02:27.605696269 +0900
+++ hd44780_i2c.py    2023-07-15 01:01:17.445932287 +0900
@@ -1,5 +1,5 @@
 # Support for HD44780 (20x4 text) LCD displays
-#
+# with PCF8574 I/O Expander
 # Copyright (C) 2018  Kevin O'Connor <kevin@koconnor.net>
 # Copyright (C) 2018  Eric Callahan <arksine.code@gmail.com>
 # Copyright (C) 2021  Marc-Andre Denis <marcadenis@msn.com>
@@ -15,19 +15,21 @@

-class hd44780_spi:
+class hd44780_i2c:
     def __init__(self, config):
         self.printer = config.get_printer()
         self.hd44780_protocol_init = config.getboolean('hd44780_protocol_init',
                                                        True)
-        # spi config
-        self.spi = bus.MCU_SPI_from_config(
-            config, 0x00, pin_option="latch_pin")
-        self.mcu = self.spi.get_mcu()
-        #self.spi.spi_send([0x01,0xa0])
-        self.data_mask = (1<<1)
-        self.command_mask = 0
-        self.enable_mask = (1<<3)
+        # i2c config
+        self.i2c = bus.MCU_I2C_from_config(config, default_addr=0x27,
+                                           default_speed=400000)
+        self.mcu = self.i2c.get_mcu()
+        self.command_mask = 0b0000
+        self.data_mask = 0b0001
+        self.enable_mask = 0b0100
+        self.backlight_mask = 0b1000
+
+

         self.icons = {}
         self.line_length = config.getchoice('line_length', LINE_LENGTH_OPTIONS,
@@ -47,12 +49,14 @@
             (self.glyph_framebuffer, bytearray(b'~'*64), 0x40) ]
     def send_4_bits(self, cmd, is_data, minclock):
         if is_data:
-            mask = self.data_mask
+            mask = self.data_mask | self.backlight_mask
         else:
-            mask = self.command_mask
-        self.spi.spi_send([(cmd & 0xF0) | mask], minclock)
-        self.spi.spi_send([(cmd & 0xF0) | mask | self.enable_mask], minclock)
-        self.spi.spi_send([(cmd & 0xF0) | mask], minclock)
+            mask = self.command_mask | self.backlight_mask
+
+        self.i2c.i2c_write([(cmd & 0xF0) | mask], minclock)
+        self.i2c.i2c_write([(cmd & 0xF0) | mask | self.enable_mask], minclock)
+        self.i2c.i2c_write([(cmd & 0xF0) | mask], minclock)
+
     def send(self, cmds, is_data=False, minclock=0):
         for data in cmds:
             self.send_4_bits(data,is_data,minclock)

hd44780_i2c.pyを使えるようにする

klippy/extras/display/display.pyを修正して、hd44780_i2cを使えるようにする

--- a/klippy/extras/display/display.py
+++ b/klippy/extras/display/display.py
@@ -6,7 +6,7 @@
 #
 # This file may be distributed under the terms of the GNU GPLv3 license.
 import logging, os, ast
-from . import hd44780, hd44780_spi, st7920, uc1701, menu
+from . import hd44780, hd44780_spi, hd44780_i2c, st7920, uc1701, menu

 # Normal time between each screen redraw
 REDRAW_TIME = 0.500
@@ -17,7 +17,8 @@ LCD_chips = {
     'st7920': st7920.ST7920, 'emulated_st7920': st7920.EmulatedST7920,
     'hd44780': hd44780.HD44780, 'uc1701': uc1701.UC1701,
     'ssd1306': uc1701.SSD1306, 'sh1106': uc1701.SH1106,
-    'hd44780_spi': hd44780_spi.hd44780_spi
+    'hd44780_spi': hd44780_spi.hd44780_spi,
+    'hd44780_i2c': hd44780_i2c.hd44780_i2c,
 }

klipperのconfigファイル(printer.cfg)にdisplayの設定を追加する

[mcu rpi]
serial: /tmp/klipper_host_mcu

[display]
lcd_type: hd44780_i2c
i2c_mcu: rpi
i2c_bus: i2c.1
i2c_address: 39 #(0x27)

Klipperからの制御の確認

ファイルを修正して、Klipperを再起動する。 2004液晶ディスプレイにこの記事の冒頭のような表示がでたらOK

mainsailのG-codeコンソールから以下のコマンドを送って、2004液晶にメッセージが反映されるかテストする。

M117 TEST Message

参考にさせて頂いたもの

Klipper OLED接続 - HackMD

LCD1602をRaspberry PiとPCF8574を使って制御する方法

PicBasic ProでI2Cアダプター「PCF8574」を使ってLCD(液晶表示器)に表示

LCD1602Aや2004AをI2C接続で使いこなす【ハード編】 | M5Stack沼人の日記

DE0でFPGAマスターをめざせ! - 20x4 LCD/OLED

LCD Interface

TC2004A-01.pdf

RK-10290_410.pdf