GPIO接続LCD（ラズパイ３）の画面反転とキャリブレーション


<img width="512" alt="pi3lcd.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78212/613d7624-516c-30f9-20e6-03dec73121c3.png">
# はじめに
Raspberry Pi 3 Model B に、**GPIO接続**の3.5 inch タッチスクリーン 480*320を接続しました
これはHDMI端子を使用せず、外観がシンプルで良さそうです。
本資料は、GPIO接続タッチスクリーンの、画面反転、キャリブレーション等について記載します。
OSは Raspbian Stretch です。


# 画面の反転（:rotate=270）

電源ケーブル端子をケース上端にするため、画面を反転します。
つぎのように　「:rotate=270」を追記して、reboot します。

```/boot/config.txtに追記
dtoverlay=tft35a:rotate=270
```

つぎの設定では、画面反転しませんでした。
lcd_rotate=2
display_rotate=2
display_hdmi_rotate=2

参考情報　https://bitset.jp/application/files/2215/0295/6474/rpi_case_35inch_lcd_setup.pdf

# 入力の反転（Transformation Matrix）
タッチペンとカーソルの動きを整合させるために、つぎの最後で **Transformation Matrix**　を設定しています。

```shell_session
$ DISPLAY=:0.0 xinput list
? Virtual core pointer                          id=2    [master pointer  (3)]
?   ? Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
?   ? ADS7846 Touchscreen                       id=6    [slave  pointer  (2)]
? Virtual core keyboard                         id=3    [master keyboard (2)]
    ? Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
$ DISPLAY=:0.0 xinput list-props 6
Device 'ADS7846 Touchscreen':
        Device Enabled (116):   1
        Coordinate Transformation Matrix (117): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
        libinput Calibration Matrix (248):      1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
        libinput Calibration Matrix Default (249):      1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
        libinput Send Events Modes Available (250):     1, 0
        libinput Send Events Mode Enabled (251):        0, 0
        libinput Send Events Mode Enabled Default (252):        0, 0
        Device Node (253):      "/dev/input/event2"
        Device Product ID (254):        0, 0
$ xinput set-prop 'ADS7846 Touchscreen' 'Coordinate Transformation Matrix' 0 -1 1 1 0 0 0 0 1
```

参考情報　https://pub.slateblue.tk/memo/day3857.html


# 入力キャリブレーション（Calibration Matrix）
タッチ位置とカーソルをあわせるために、つぎの手順でキャリブレーションします。

（１）「DISPLAY=:0.0 xinput_calibrator -v」
をユーザpi で実行します。指定される４点をクリックすると、つぎのように座標が標準出力に出力されます。
DEBUG: Adding click 0 (X=78, Y=54)
DEBUG: Adding click 1 (X=407, Y=53)
DEBUG: Adding click 2 (X=83, Y=268)
DEBUG: Adding click 3 (X=407, Y=267)

（２）４つのパラメータを次式で計算します。
a = (screen_width * 6 / 8) / (click_3_X - click_0_X)
c = ((screen_width / 8) - (a * click_0_X)) / screen_width
e = (screen_height * 6 / 8) / (click_3_Y - click_0_Y)
f = ((screen_height / 8) - (e * click_0_Y)) / screen_height

それぞれ次の値になりました。
1.094224924
-0.05281155015
1.126760563
-0.06514084507

（３）Calibration Matrix　の設定
上記パラメータを使用して、つぎのように **Calibration Matrix** を設定します。
xinput set-prop  "ADS7846 Touchscreen" "libinput Calibration Matrix" a, 0.0, c, 0.0, e, f, 0.0, 0.0, 1.0

実際のコマンドはつぎのようになります。

```shell_session
DISPLAY=:0.0 xinput set-prop  "ADS7846 Touchscreen" "libinput Calibration Matrix" 1.094224924, 0.0, -0.05281155015, 0.0, 1.126760563, -0.06514084507, 0.0, 0.0, 1.0
```

（４）キャリブレーションができていることを、画面クリックして確かめます。

参考情報　https://wiki.archlinux.org/index.php/Talk:Calibrating_Touchscreen#Libinput_breaks_xinput_calibrator

#  入力の反転と入力キャリブレーションの固定化
rotate_touch_screen.sh　を新規に作成して、動作確認した２つの xinputコマンドを記述します。
つぎのように画面の起動時に自動実行します。

```/home/pi/.config/lxsession/LXDE-pi/autostart　追加
@/home/pi/.config/lxsession/LXDE-pi/rotate_touch_screen.sh
```




# その他
### 最終的な Transformation Matrix と Calibration Matrix
```shell_session
$ DISPLAY=:0.0 xinput list-props 6
Device 'ADS7846 Touchscreen':
        Device Enabled (116):   1
        Coordinate Transformation Matrix (117): 0.000000, 1.000000, 0.000000, -1.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000
        libinput Calibration Matrix (248):      1.094225, 0.000000, -0.052812, 0.000000, 1.126761, -0.065141, 0.000000, 0.000000, 1.000000
        libinput Calibration Matrix Default (249):      1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
        libinput Send Events Modes Available (250):     1, 0
        libinput Send Events Mode Enabled (251):        0, 0
        libinput Send Events Mode Enabled Default (252):        0, 0
        Device Node (253):      "/dev/input/event0"
        Device Product ID (254):        0, 0
```

### 縦置き時のパラメータ
< /boot/config.txt >
dtoverlay=tft35a:rotate=0

< /home/pi/.config/lxsession/LXDE-pi/rotate_touch_screen.sh >
DISPLAY=:0 xinput set-prop 'ADS7846 Touchscreen' 'Coordinate Transformation Matrix' 1 0 0 0 1 0 0 0 1

### stretch の Xorg のデフォルト input ドライバは libinput　（jessie は evdev ）
https://www.debian.org/releases/stretch/i386/release-notes/ch-information.ja.html

### フォント導入　sudo apt-get install fonts-noto
### ソフトウェアキーボード導入　sudo apt-get install matchbox-keyboard
画面上部の左端Menu より Accessories/Keyboard で起動できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/69b66a53-24ee-f6e4-35e8-2630ec0214e3.png)