もともと初代 Raspberry Pi 用に買ったものだけれど、初代 Raspberry Pi をいよいよ捨てたので、ついでにいろいろ調べながら再度使ってみる。

LCD-show-180817.tar.gz の中の ./LCD32-show がやっていることは以下の通り。

しかし fbcp のインストールは失敗してた。まぁとりあえず使える。

なお、どういったコントローラが使われているかスペックに書いてないが、以下の通り。

  • タッチコントローラーは SPI ads7846
  • 液晶は SPI ili9340 240x320

fbcp は何をしている?

frame buffer をコピーするアプリケーションなのは名前から明らかだけれど、何のために?と思った。結論をいうと GPU でレンダリングした結果を SPI 接続の液晶へ表示させるためのハックのようだ。GPU を使わないなら入れなくても動かすことはできる。

dtb dts

dtb ファイル (コンパイル済みのデバイスツリーブロブ) が含まれているけど、ソースファイルがない。以下のようにするとソースにディスアセンブルできる。

dtc -I dtb -O dts -o waveshare32b-overlay.dts waveshare32b-overlay.dtb

以下のような感じのデバイスツリーとなっていた。

/dts-v1/;

/ {
        compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";

        fragment@0 {
                target = <0xdeadbeef>;

                __overlay__ {
                        status = "okay";

                        spidev@0 {
                                status = "disabled";
                        };

                        spidev@1 {
                                status = "disabled";
                        };
                };
        };

        fragment@1 {
                target = <0xdeadbeef>;

                __overlay__ {

                        waveshare32b_pins {
                                brcm,pins = <0x11 0x1b 0x16>;
                                brcm,function = <0x0 0x0 0x0>;
                                linux,phandle = <0x1>;
                                phandle = <0x1>;
                        };
                };
        };

        fragment@2 {
                target = <0xdeadbeef>;

                __overlay__ {
                        #address-cells = <0x1>;
                        #size-cells = <0x0>;

                        waveshare32b@0 {
                                compatible = "ilitek,ili9340";
                                reg = <0x0>;
                                pinctrl-names = "default";
                                pinctrl-0 = <0x1>;
                                spi-max-frequency = <0xf42400>;
                                rotate = <0x5a>;
                                fps = <0x19>;
                                bgr;
                                buswidth = <0x8>;
                                reset-gpios = <0xdeadbeef 0x1b 0x0>;
                                dc-gpios = <0xdeadbeef 0x16 0x0>;
                                debug = <0x0>;
                                linux,phandle = <0x2>;
                                phandle = <0x2>;
                        };

                        waveshare35a-ts@1 {
                                compatible = "ti,ads7846";
                                reg = <0x1>;
                        };

                        waveshare32b_ts@1 {
                                compatible = "ti,ads7846";
                                reg = <0x1>;
                                spi-max-frequency = <0x1e8480>;
                                interrupts = <0x11 0x2>;
                                interrupt-parent = <0xdeadbeef>;
                                pendown-gpio = <0xdeadbeef 0x11 0x0>;
                                ti,x-plate-ohms = [00 3c];
                                ti,pressure-max = [00 ff];
                        };
                };
        };

        __overrides__ {
                speed = <0x2 0x7370692d 0x6d61782d 0x66726571 0x75656e63 0x793a3000>;
                rotate = [00 00 00 02 72 6f 74 61 74 65 3a 30 00];
                fps = [00 00 00 02 66 70 73 3a 30 00];
                debug = <0x2 0x64656275 0x673a3000>;
        };

        __symbols__ {
                waveshare32b_pins = "/fragment@1/__overlay__/waveshare32b_pins";
                waveshare32b = "/fragment@2/__overlay__/waveshare32b@0";
        };
        __fixups__ {
                spi0 = "/fragment@0:target:0", "/fragment@2:target:0";
                gpio = "/fragment@1:target:0", "/fragment@2/__overlay__/waveshare32b@0:reset-gpios:0", "/fragment@2/__overlay__/waveshare32b@0:dc-gpios:0", "/fragment@2/__overlay__/waveshare32b_ts@1:interrupt-parent:0", "/fragment@2/__overlay__/waveshare32b_ts@1:pendown-gpio:0";
        };

        __local_fixups__ {
                fixup = "/fragment@2/__overlay__/waveshare32b@0:pinctrl-0:0", "/__overrides__:speed:0", "/__overrides__:rotate:0", "/__overrides__:fps:0", "/__overrides__:debug:0";
        };
};

Device Tree って何か?

簡単にいうとそのハードウェアのドライバの用の設定ファイル。ほぼ同じ制御方法をするハードウェアであっても、細かい制御アドレスの違い・使用バス・接続されているGPIOピンの違いが存在する。これらをいちいちカーネルにハードコードしてコンパイルするのは面倒なので、設定ファイルとして分離してある。ARM Linux だと標準的に使われている。

DTS ファイルの書きかた https://elinux.org/Device_Tree_Usage

  • compatible = "ilitek,ili9340" の部分でドライバを指定している "vendor,product" 形式。

正直読むのに苦労する。完全に理解してない。

タッチコントローラのキャリブレーション

$ DISPLAY=:0 xinput_calibrator
...
Section "InputClass"
        Identifier      "calibration"
        MatchProduct    "ADS7846 Touchscreen"
        Option  "Calibration"   "195 3780 3881 252"
        Option  "SwapAxes"      "1"
EndSection
$ sudo vi /usr/share/X11/xorg.conf.d/99-calibration.conf 
# copy calibration from above
  1. トップ
  2. tech
  3. Raspberry Pi 2 B+ と 3.2inch LCD

Chromium (Chrome の OSS版) を Raspberry Pi で Kiosk モード (全画面単一アプリケーションモード) で起動して、UI を作れると便利そうなのでやってみた。たとえば動画のように、3.2inch LCD 上のUIを Web 技術で完結させることができる。

Chromium を kiosk で自動起動する

raspi-config で起動モードを Desktop (autologin) に設定する。

sudo raspi-config

マウスカーソルを自動で消すやつをいれる。

$ sudo apt-get install unclutter

不正終了で残るファイルを reboot 時に消しておく。

$ crontab -e
@reboot rm -rf ~/.config/chromium/Singleton*

Raspberry Pi は Desktop の場合 LXDE が使われる。これの起動時に必要なものを自動起動するように設定する。

chromium-browser の引数は重要。とりあえずこのあたりを指定しておくと良い。

$ vi ~/.config/lxsession/LXDE-pi/autostart
#@lxpanel --profile LXDE-pi
#@pcmanfm --desktop --profile LXDE-pi
#@xscreensaver -no-splash
#@point-rpi

@xset s off
@xset -dpms
@xset s noblank
@unclutter
@chromium-browser --remote-debugging-port=9222 --no-default-browser-check --noerrdialogs --kiosk --incognito https://example.com

Chrome を remote-debugging

    • remote-debugging-port をつけているので remote debugging が有効なのだが、おそらくループバックインターフェイスしか受け付けてないのでLAN内の他のコンピュータからは直接アクセスできなかった。このため他のコンピュータから Raspberry Pi へログインするときにポートフォワードする。
ssh -L 9223:127.0.0.1:9222 pi@192.168.0.23 

これで、ログインしたコンピュータで http://localhost:9223/ するとデバッグコンソールを出せる (タブ一覧が出るので選択すれば良い)。JS が実行できるので、raspi 上で操作しなくとも特定 URL に移動したり、リロードしたりできる。もちろんエレメントインスペクタも使うことができる。

  1. トップ
  2. tech
  3. Raspberry Pi で Chromium を起動してリモート操作

珍しく直撃コースだったので、気圧変化がなかなか面白かった。上のグラフは自宅でとっている気圧計 (BME280) のデータを prometheus 経由で grafana に表示したもの。

最低気圧 973hPa となっていて、当時の台風のほぼ中心気圧まで下がった。

オレンジの線は8時間の標準偏差で、気圧変動の激しさの目安に出しているつもり。普通は2もいかない。

P&G のプロモーションの「企業にあわせて自分を偽ったことがある」かってやつ面白いというか思うところがあった。

面接とかってなんとか良く見せなければならないという固定観念があって、なんでそう思っていたかはわからないけど、とにかくそういう気持ちがあって気が重かった。自分の場合は恵まれていて、最初ITでバイトしようと思ったとき、紹介してくれた人に面接で何言えばいいかわからないと話したら「金が欲しいんだったら金が欲しいと言えばいい」と答えていて、なるほどと思ってその通り面接で言ったのだった (それで採用された)。

これはそれまで複雑に考えすぎてたので、急にすっきりしたという感じがしたので印象に残っている。とにかく正直に話して、マッチングしないならそれでおしまいという単純な話に気付いたのがそれだったからだ。