すでにHDMIの表示はできているので、SPIでミラーされた表示を使わなくても、タッチスクリーン機能だけを追加したい。(あ、でも生成する画像サイスがSPIのが小さくて済むかな?)
タッチコントローラは、Shenzhen Xptek Technology XPT2046が使われているようだ。XPT2046は、インターフェイス的にはads7846互換のようだ。
調べてみると、Jessie以降はドライバがkernelに取り込まれているようなので、devfsで自動認識できそうだ。
ドライバがあるのを確認する。確かにある。また、dtbもあるのでdevfsで使える。
pi@raspberrypi:~ $ sudo find / | grep ads7846
/lib/modules/4.19.57-v7l+/kernel/drivers/input/touchscreen/ads7846.ko
/lib/modules/4.19.57+/kernel/drivers/input/touchscreen/ads7846.ko
/lib/modules/4.19.57-v7+/kernel/drivers/input/touchscreen/ads7846.ko
/boot/overlays/ads7846.dtbo
起動設定でタッチスクリーンを有効に設定する。
pi@raspberrypi:~ $ sudo vi /boot/config.txt
dtparam=i2c_arm=on
dtparam=spi=on
dtoverlay=ads7846,penirq=25,speed=10000,penirq_pull=2,xohms=150
設定を有効にするために、再起動する。
pi@raspberrypi:~ $ sudo reboot
再度ssh接続して、デバイスが認識されたか確認する。認識はされているが、SPIが有効になっていない?
pi@raspberrypi:~ $ lsmod | grep ads
ads7846 24576 0
hwmon 16384 2 raspberrypi_hwmon,ads7846
pi@raspberrypi:~ $ dmesg | grep ads
[ 6.057241] ads7846 spi0.1: spi0.1 supply vcc not found, using dummy regulator
[ 6.057356] ads7846 spi0.1: Linked as a consumer to regulator.0
[ 6.057891] ads7846 spi0.1: touchscreen, irq 166
pi@raspberrypi:~ $ sudo raspi-config
5 Interfacing Options
P4 SPI
<Yes>
「The SPI interface is enabled」と表示されたら有効になった。再起動する。
pi@raspberrypi:~ $ sudo reboot
しかし、dmsgの表示結果は変わらなかった。問題のないメッセージなのかもしれない。
デバイスの変化を見る。ドライバを入れる前は、/dev/input/eventは0-2だけだった。
pi@raspberrypi:~ $ ls -l /dev/input/event*
crw-rw---- 1 root input 13, 64 Jul 10 01:21 /dev/input/event0
crw-rw---- 1 root input 13, 65 Jul 10 01:21 /dev/input/event1
crw-rw---- 1 root input 13, 66 Jul 10 01:21 /dev/input/event2
ドライバを入れた後は、/dev/input/event3が生えている。
pi@raspberrypi:~ $ ls -l /dev/input/event*
crw-rw---- 1 root input 13, 64 Nov 14 13:37 /dev/input/event0
crw-rw---- 1 root input 13, 65 Nov 14 13:37 /dev/input/event1
crw-rw---- 1 root input 13, 66 Nov 14 13:37 /dev/input/event2
crw-rw---- 1 root input 13, 67 Nov 14 13:37 /dev/input/event3
event3をcatしてから、タッチパネルをさわると、何が出ているのが確認できた。これ、自力でデコードしないといけないのかな?
pi@raspberrypi:~ $ cat /dev/input/event3
�Z�]��Z�]�5� �Z�]�5���Z�]�5�Z�]�� �Z�]��� �Z�]��1��Z�]���Z�] �Z�]� �Z�]B��Z�]�Z�]0
バイナリのようなので、hexdumpで見てみる。一回のタッチでこれだけがゾロゾロと出てくる。
pi@raspberrypi:~ $ hexdump /dev/input/event3
0000000 5d21 5dcd c8d9 0002 0001 014a 0001 0000
0000010 5d21 5dcd c8d9 0002 0003 0000 0b20 0000
0000020 5d21 5dcd c8d9 0002 0003 0001 0845 0000
0000030 5d21 5dcd c8d9 0002 0003 0018 ff5b 0000
0000040 5d21 5dcd c8d9 0002 0000 0000 0000 0000
0000050 5d21 5dcd 64ff 0003 0003 0000 0af5 0000
0000060 5d21 5dcd 64ff 0003 0003 0018 ff6c 0000
0000070 5d21 5dcd 64ff 0003 0000 0000 0000 0000
0000080 5d21 5dcd 0154 0004 0003 0000 0ad7 0000
0000090 5d21 5dcd 0154 0004 0003 0001 0836 0000
00000a0 5d21 5dcd 0154 0004 0003 0018 ff3e 0000
00000b0 5d21 5dcd 0154 0004 0000 0000 0000 0000
00000c0 5d21 5dcd 4823 0004 0001 014a 0000 0000
00000d0 5d21 5dcd 4823 0004 0003 0018 0000 0000
00000e0 5d21 5dcd 4823 0004 0000 0000 0000 0000
ASCIIで見てもよくわからない。
pi@raspberrypi:~ $ hexdump -C /dev/input/event3
00000000 df 5d cd 5d 65 72 06 00 01 00 4a 01 01 00 00 00 |.].]er....J.....|
00000010 df 5d cd 5d 65 72 06 00 03 00 00 00 ba 08 00 00 |.].]er..........|
00000020 df 5d cd 5d 65 72 06 00 03 00 01 00 e6 06 00 00 |.].]er..........|
00000030 df 5d cd 5d 65 72 06 00 03 00 18 00 33 ff 00 00 |.].]er......3...|
00000040 df 5d cd 5d 65 72 06 00 00 00 00 00 00 00 00 00 |.].]er..........|
00000050 df 5d cd 5d b8 0e 07 00 03 00 00 00 af 08 00 00 |.].]............|
00000060 df 5d cd 5d b8 0e 07 00 03 00 01 00 f1 06 00 00 |.].]............|
00000070 df 5d cd 5d b8 0e 07 00 03 00 18 00 53 ff 00 00 |.].]........S...|
00000080 df 5d cd 5d b8 0e 07 00 00 00 00 00 00 00 00 00 |.].]............|
00000090 df 5d cd 5d 90 f1 07 00 01 00 4a 01 00 00 00 00 |.].]......J.....|
000000a0 df 5d cd 5d 90 f1 07 00 03 00 18 00 00 00 00 00 |.].]............|
000000b0 df 5d cd 5d 90 f1 07 00 00 00 00 00 00 00 00 00 |.].]............|
evtestコマンドで調べる。
pi@raspberrypi:~ $ sudo apt-get install evtest
pi@raspberrypi:~ $ evtest /dev/input/event3
Input driver version is 1.0.1
Input device ID: bus 0x0 vendor 0x0 product 0x0 version 0x0
Input device name: "ADS7846 Touchscreen"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 330 (BTN_TOUCH)
Event type 3 (EV_ABS)
Event code 0 (ABS_X)
Value 2021
Min 0
Max 4095
Event code 1 (ABS_Y)
Value 2342
Min 0
Max 4095
Event code 24 (ABS_PRESSURE)
Value 0
Min 0
Max 65535
Properties:
Testing ... (interrupt to exit)
Event: time 1573740733.072495, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1573740733.072495, type 3 (EV_ABS), code 0 (ABS_X), value 2076
Event: time 1573740733.072495, type 3 (EV_ABS), code 1 (ABS_Y), value 1742
Event: time 1573740733.072495, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 65295
Event: time 1573740733.072495, -------------- SYN_REPORT ------------
Event: time 1573740733.112501, type 3 (EV_ABS), code 0 (ABS_X), value 2073
Event: time 1573740733.112501, type 3 (EV_ABS), code 1 (ABS_Y), value 1752
Event: time 1573740733.112501, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 65337
Event: time 1573740733.112501, -------------- SYN_REPORT ------------
Event: time 1573740733.152505, type 3 (EV_ABS), code 0 (ABS_X), value 2070
Event: time 1573740733.152505, type 3 (EV_ABS), code 1 (ABS_Y), value 1746
Event: time 1573740733.152505, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 65328
Event: time 1573740733.152505, -------------- SYN_REPORT ------------
Event: time 1573740733.170594, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
Event: time 1573740733.170594, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 0
Event: time 1573740733.170594, -------------- SYN_REPORT ------------
おお、フォーマット通り出てきた。指を動かした気はなかったのだけど、タッチして、少しドラッグして、離したことがわかる。
時間、タイプ、コード、値が出ている。簡単なスクリプトでタッチ位置を抽出してみる。
pi@raspberrypi:~ $ vi single-touch.sh
pi@raspberrypi:~ $ cat single-touch.sh
#!/bin/sh
input=/dev/input/event3
code_prefix="ABS"
code="${code_prefix}_[XY]"
val_regex=".*(${code_prefix}_\(.\)), value \([-]\?[0-9]\+\)"
val_subst="\1=\2"
send_axis() {
# 1. Convert axis value ($1) from device specific units
# 2. Send this axis value via UDP packet
echo $1
}
process_line() {
while read line; do
axis=$(echo $line | grep "^Event:" | grep $code | \
sed "s/$val_regex/$val_subst/")
if [ -n "$axis" ]; then
send_axis $axis
fi
done
}
if [ $(id -u) -ne 0 ]; then
echo "This script must be run from root" >&2
exit 1
fi
evtest $input | process_line
pi@raspberrypi:~ $ chmod +x single-touch.sh
pi@raspberrypi:~ $ ./single-touch.sh
This script must be run from root
pi@raspberrypi:~ $ sudo ./single-touch.sh
X=1881
Y=1844
X=1885
Y=1842
左下が0:0のようだ。分解能は結構細かい。最大でこのくらい。
X=3932
Y=3959
細いペン先で同じところをずっと押していても、数値がかなり変動する。
タッチイベントを取るだけなら、ABS_PRESSUREの値が0以上になっているのを見れば、たやすく出来る感じだ。
というわけで、描画とタッチの検出ができるようになったので、これで目的には利用できることが確認できた。
つづく
参考:
Linux Input Subsystemの使い方
http://www.tatapa.org/~takuo/input_subsystem/input_subsystem.html
How to get Coordinates of Touchscreen Rawdata using Linux - Stack Overflow
https://stackoverflow.com/questions/28841139/how-to-get-coordinates-of-touchscreen-rawdata-using-linux
[Review] KeDei 3.5" HDMI display with touch for Raspberry Pi - Raspberry Pi Forums
https://www.raspberrypi.org/forums/viewtopic.php?t=175616
KeDei 3.5 inch 480x320 TFT lcd from ali - Raspberry Pi Forums
https://www.raspberrypi.org/forums/viewtopic.php?t=124961
タッチスクリーンコントローラーは、XPT2046と書いてある。
オリジナル投稿: Raspi用表示装置4種を試す -2.3-|kinneko|pixivFANBOX
https://www.fanbox.cc/@kinneko/posts/657582


