RaspberryPi

Raspberry Pi Zero(W)でPiTFTを使う

PiTFT-01.jpg
PiZero W + 2.4インチPiTFT

PiTFTはAdafruitさんのチュートリアルにあるインストールスクリプトを走らせると使えるようになりますが、カーネルを入れ替えてしまうため、他に独自に使いたいカーネルモジュールがあると共存が難しくなります。
これらに頼らず、Device Tree等を自分で設定しきれば最新のインストールイメージでも使えるようになるので、その手法を紹介します。

2.2インチ、2.4インチ、2.8インチ、3.5インチ(いずれもResistive Touchscreen)で動作確認を取りました。2.8インチのCapacitive Touchscreenは描画は確認しましたが、タッチスクリーンのドライバを動作確認がとりきれておらず、本稿の対象外です。

事前準備

PiZero(W)とPiTFTを用意します。

PiTFT

いろんなサイズが出ていますが、現時点のオススメは2.4インチです。理由は2つ。

横幅がジャストサイズ

上側2つの穴でネジ止めがしっかりできる上に、コンパクトなケースが設計できます。2.2インチも同じ横幅ですが、タッチスクリーンがないので、ボタン操作を前提でプログラムを書く必要があります。

PiTFT-02.jpg
斜めから

高さを抑えるのが容易

他のGPIOピンが横向きで使用できるので、背の低いピンヘッダ、ピンソケットでPiZeroとPiTFTを接続すれば、割とジャストの高さまで持って行けます。

PiTFT-05.jpg
横向きのGPIOピンにGPSをUART経由で接続しています

画像の2.4インチPiTFTは、別途購入した秋月のロープロファイルピンヘッダ7.7mmとそれに合うピンソケット5.7mmを使っています。

2.4インチ、2.2インチは諸々の半田付けが必要なKitとして用意されているので、余分なコネクタを取り除く腕さえあれば直接接続する(AdafruitさんのPiGRRL Zeroチュートリアル)等、さらなる調整ができます。

しかし、2.8インチ以上は、スルーされたピンが縦向きに付いているのと、それに合わせて背の高いピンヘッダ等やスイッチが予めついてしまっているので、PiZero(W)では使いにくいかと思います。

PiTFT-03.jpg
左: 2.8インチ(Capacitive), 右: 3.5インチ(Resistive)

PiTFT-04.jpg
無理して外側のピンソケットを取り外しても直ちに使えない形状。(ピンボケしてます)

PiTFTの認識

raspi-configでI2CとSPIをオンにしておいてください。
また、エディタはvimを使用していますので、適宜読み替えてください。

画面

何も設定せずにPiTFTを接続すると電源投入後、画面は白色になりますが、下記の設定が有効になると電源投入後、黒色になります。
また、HDMI用の/dev/fb0に加え、PiTFT用の/dev/fb1が出現します。

$ sudo vim /boot/config.txt

#以下は設定済みのはず(I2CとSPI)
dtparam=i2c_arm=on
dtparam=spi=on

#以下を追加
dtoverlay=pitft28-resistive,rotate=270,speed=32000000,fps=20

dtoverlayの設定値は下記スクリプト参照になりますが、以下の値になると思います。
https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper

設定値 説明
pitft22 PiTFT 2.2インチ (タッチスクリーンなしです)
pitft28-resistive PiTFT 2.4, 2.8, 3.2インチ (解像度320x240のResistive Touchscreen)
pitft28-capacitive PiTFT 2.8インチ (解像度320x240のCapacitive Touchscreen)
pitft35-resistive PiTFT 3.5インチ (解像度480x320のResistive Touchscreen)

また、rotateは画面の向きなので0、90、180、270のどれかに適宜変更してください。270は冒頭の写真にあるように、PiTFT2.4インチのボタンが下に来る向きになります。

タッチスクリーン

Resistive TouchscreenとCapacitive Touchscreenで設定内容が異なります。

Resistive Touchscreen

カーネルモジュールとして用意されているstmpe-tsドライバを使用します。
udevの設定ファイルを新規に作成し、タッチスクリーンの出力を /dev/input/touchscreen に紐つけます。

$ sudo vim /etc/udev/rules.d/95-stmpe.rules

SUBSYSTEM=="input", ATTRS{name}=="stmpe-ts", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen" 

モジュールを再読み込みします。

$ sudo rmmod stmpe_ts; sudo modprobe stmpe_ts
$ cat /dev/input/touchscreen

PiTFTを適当に触ると何かしら出力されます。

Capacitive Touchscreen

最新のカーネル4.9より、ドライバがft6236からedt-ft5x06に変わったようで、動かしきれていません。(反応はするのですが)

コンソールの描画

コンソールを出力させます。Xが描画されればよいという場合は行わなくても構いません。

$ sudo vim /boot/cmdline.txt

#末尾にスペースを入れ、以下を追加。
#新しい行ではなく、1行目の最後に追加になります。
fbcon=map:10 fbcon=font:VGA8x8

fbcon=font:VGA8x8は小さなフォントを指定するために使っています。指定しなくても可能ですが、起動画面等で端が切れやすくなります。

PiTFT-06.jpg
fbcon=font:VGA8x8なし。行間がちょっと間延びした感じ。

PiTFT-07.jpg
fbcon=font:VGA8x8あり。行数は上記の倍以上になり、だいぶ詰め込んでいる感じ。

さらにフォントを見やすくしたい場合

下記のコマンドでさらに設定可能です。
(/boot/cmdline.txtに記述した fbcon=font:VGA8x8 の設定は見なくなります)

$ sudo dpkg-reconfigure console-setup

UTF-8 -> Guess optimal character set -> Terminus -> 6x12 (framebuffer only)

こうなります。
PiTFT-08.jpg

画面をブラックアウトさせない

下記コマンドで設定できます。blankオプションの後ろの数字は分単位で、0にするとブラックアウト無効になります。

$ sudo sh -c "TERM=linux setterm -blank 0 > /dev/tty0"

毎起動時に有効にしたい場合、

$ sudo vim /etc/rc.local

#最後にある`exit 0`の手前に記載
setterm -blank 0

設定値の確認は下記コマンドで行えますが、秒単位の数字が帰ってきます。

$ cat /sys/module/kernel/parameters/consoleblank
0

タッチスクリーンの調整 (コンソール)

まず、下記を予めインストールします。

$ sudo apt-get install evtest tslib libts-bin

次にAdafruitさんのキャリブレーション用スクリプトを使います。
/etc/pointercalに正しい値を設定することが目標です。
しかしながら、2.8インチ用resistive(28r)の値が一部変なので修正します。

$ wget https://raw.githubusercontent.com/adafruit/PiTFT_Extras/master/pitft_touch_cal.py
$ vim pitft_touch_cal.py

#0度用と270度用の最後にあるパラメータ'6553636'を'65536'に直す

#修正前
CAL_CONFIG['28r']['pointercal']['0']   = '4315 -49 -889068 18 5873 -1043172 6553636'
CAL_CONFIG['28r']['pointercal']['90']  = '-30 -5902 22077792 4360 -105 -1038814 65536'
CAL_CONFIG['28r']['pointercal']['180'] = '-4228 73 16353030 -60 -5888 22004262 65536'
CAL_CONFIG['28r']['pointercal']['270'] = '-69 5859 -829540 -4306 3 16564590 6553636'

#修正後
CAL_CONFIG['28r']['pointercal']['0']   = '4315 -49 -889068 18 5873 -1043172 65536'
CAL_CONFIG['28r']['pointercal']['90']  = '-30 -5902 22077792 4360 -105 -1038814 65536'
CAL_CONFIG['28r']['pointercal']['180'] = '-4228 73 16353030 -60 -5888 22004262 65536'
CAL_CONFIG['28r']['pointercal']['270'] = '-69 5859 -829540 -4306 3 16564590 65536'

$ sudo python2 pitft_touch_cal.py

#実行例

---------------------------------
USING DISPLAY: 28r

---------------------------------
USING ROTATION: 270

---------------------------------
CURRENT CONFIGURATION

Could not determine /etc/pointercal configuration.
Could not determine /etc/X11/xorg.conf.d/99-calibration.conf configuration.
---------------------------------
NEW CONFIGURATION

New /etc/pointercal configuration:
-69 5859 -829540 -4306 3 16564590 65536

New /etc/X11/xorg.conf.d/99-calibration.conf configuration:
Section "InputClass"
    Identifier      "calibration"
    MatchProduct    "stmpe-ts"
    Option  "Calibration"   "287 3739 3817 207"
    Option  "SwapAxes"      "1"
EndSection

Update current configuration to new configuration? [y/N]: y  # <-入力
---------------------------------

Updated /etc/pointercal
Updated /etc/X11/xorg.conf.d/99-calibration.conf

動作確認をします。タッチした箇所にポインタが追従すればOKです。

$ sudo TSLIB_FBDEVICE=/dev/fb1 TSLIB_TSDEVICE=/dev/input/touchscreen ts_test

手動でキャリブレーションしたい場合は、以下のコマンドで実施します。

$ sudo TSLIB_FBDEVICE=/dev/fb1 TSLIB_TSDEVICE=/dev/input/touchscreen ts_calibrate

※Qt5.9をネイティブビルドして、X Windowsを介さずにLinuxFBでQtWidgetsを描画できていますが、なぜかタッチスクリーンの軸が入れ替わっており、QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERSも効かず、検証中です。

X Windowsの描画

Xを使わない場合は行わなくても構いません。
(Xを介さず直接描画するアプリを作っている場合等)

画面表示

PiTFTは/dev/fb1に対応しているので(fb0はHDMI)、こちらにXを描画するように変更します。

$ sudo vim /usr/share/X11/xorg.conf.d/99-fbturbo.conf

#/dev/fb0 を /dev/fb1 に変更
Section "Device"
        Identifier      "Allwinner A10/A13 FBDEV"
        Driver          "fbturbo"
        #Option          "fbdev" "/dev/fb0"
        Option          "fbdev" "/dev/fb1"
        Option          "SwapbuffersWait" "true"
EndSection

タッチスクリーンの調整 (X Windows)

こちらもAdafruitさんのチュートリアルを辿ればできますが、最近のインストールイメージ(RASPBIAN JESSIE WITH DESKTOP以降)では、input周りが変更になったためxserver-xorg-input-evdevをインストールする必要があります。(公式FAQの最後の方に追加されて記載)
https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi/help-faq#faq-20

$ sudo apt-get install xserver-xorg-input-evdev

/usr/share/X11/xorg.conf.d/ 下で新しく10-evdev.conf が作成されているはずです。また、40-libinput.confをリネームか削除してください。

$ cd /usr/share/X11/xorg.conf.d/
$ sudo mv 40-libinput.conf 40-libinput.conf~

コンソール編同様、Adafruitさんのキャリブレーションスクリプトを用います。
/etc/X11/xorg.conf.d/99-calibration.confに正しい値を反映させることが目標です。

$ wget https://raw.githubusercontent.com/adafruit/PiTFT_Extras/master/pitft_touch_cal.py
$ sudo python2 pitft_touch_cal.py

#実行例はコンソール編と同じなので省略