YoctoでRaspberryPi 3B+向けのOSを作ってみる
こんにちは。
私は現在、『ラブライブ!虹ヶ咲学園スクールアイドル同好会』を視聴しています。
天王寺璃奈さんはかわいいですね。
彼女は感情を表に出すのが苦手で、普段はスケッチブックに表情を描き、コミュニケーションをとっています。
また、技術面に明るく、アイドル活動時は顔を覆うディスプレイを自在に制御し、豊かな感情を表現しています。
youtu.be
そんな折、こんなツイートを見かけました。
虹ヶ咲見たこと無いけどLinuxカーネル書き換えた自作OSで表情作ってる人がいるのは知ってる
— みつえもん (@dst0m) 2020年11月23日
ハードもソフトも自作している天王寺璃奈さん。OSもカスタマイズしていることでしょう。
きっとYocto Projectを利用しています。
というわけで僕もYoctoを触りたいと思います。
モチベーション
Advent calendar用 兼 仕事の勉強です。
ありふれた内容ですが、まずは人の真似からということで初めてみます。
ちょうどラズパイを持て余していたこともあり、
まずは最小限のラズパイ用OSをYoctoでビルドしてみます。
Yocto Projectとは
簡単に言うと、組み込みシステム向けのLinuxを作るためのツールです。
OSを作るための諸々がまとまっているものという認識でいます。
Yoctoのいい点は、オリジナルの構成を作れること、デファクトスタンダードであることです。
デファクトスタンダード最高。
詳しくは公式や「Yocto とは」でヒットした記事を読んでください。
触ってみたい方は岩松さんの『レシピの作り方入門』がいいと思います。
作業環境
以下の内容をUbuntu20.04 on VirtualBoxに割り当てて作業します。
項目 | 内容 |
---|---|
プロセッサ | Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz 8コア |
メモリ | 10GB |
ストレージ | SSD 10GB, HDD 1TB |
環境構築
まずはYocto Projectを導入していきます。 公式導入手順を参考に、必要なパッケージをインストールしていきます。
$ sudo apt install gawk wget git-core diffstat unzip texinfo gcc-multilib \ build-essential chrpath socat cpio python3 python3-pip python3-pexpect \ xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev \ pylint3 xterm
ビルドツールPokyをcloneします。
$ git clone git://git.yoctoproject.org/poky
ラズパイ用のOSを作るにあたって必要なmeta-raspberrypiをcloneします。
レイヤーはpokyにまとめておきました。
~/poky$ git clone https://github.com/agherzan/meta-raspberrypi.git
ビルド
~/poky$ source oe-init-build-env
レイヤ追加
build/conf/bblayers.conf
に、先ほどcloneしてきたレイヤmeta-raspberrypi
を追加します。
これで、ビルドツールbitbakeがレイヤを認識してくれます。
BBLAYERS ?= " \ /path/to/poky/meta \ /path/to/poky/meta-poky \ /path/to/poky/meta-yocto-bsp \ /path/to/poky/meta-raspberrypi \ "
対象マシン設定
対象マシンを設定するために、build/conf/local.conf
を編集します。
私の場合はRaspberry Pi 3B+で、SoCのBCM2837が64bitアーキテクチャを採用しています。
せっかくなので、raspberrypi3-64を採用します。
マシン名は、meta-rasberrypi/docs/layer-contents.md
や meta-rasberrypi/conf/machine/
以下で確認できます。
## Supported Machines * raspberrypi * raspberrypi0 * raspberrypi0-wifi * raspberrypi2 * raspberrypi3 * raspberrypi3-64 (64 bit kernel & userspace) * raspberrypi4 * raspberrypi4-64 (64 bit kernel & userspace) * raspberrypi-cm (dummy alias for raspberrypi) * raspberrypi-cm3
マシン名をlocal.conf
の末尾に追記します。
MACHINE ?= "raspberrypi3-64"
ビルド実行
今回は最小限の構成でビルドします。
天に3回祈って寝ます。結果は追記します。
$ bitbake core-image-minimal
(追記2020/12/03)ビルド成功してました。4時間弱かかりました......
ビルド生成物
ビルドで生成されたファイルを確認します。
生成物は、build/tmp/deploy/images/マシン名
以下にあります。
大量にありますが、今回必要なのは
Image
,core-image-minimal-raspberrypi3-64.tar.bz2
,bcm2837-rpi-3-b-raspberrypi3-64.dtb
のみです。
(ファイル名からの判断なので動作確認してません。今microSDがないので......)
トラブルシューティング
VBoxの共有フォルダ内で作業していたが、bitbakeが権限的に実行できなかった。
仕様で共有フォルダの権限を変更できないので(グループに入ることで読み書きはできるがbitbakeはnot permittedされる)、
結局、VBoxでHDDを追加、Ubuntuでマウントして作業ディレクトリを移動した。
まとめ
環境構築から記事作成までぶっ通しでやったので疲れた......。
次はGUI(wayland)を追加するのもいいかもしれない。
LoRaモジュール[ES920LR] 使用法(ラズパイ、WindowsPC)
使用機器 ES920LRA1B, ES920EB
https://tokyodevices.jp/items/252
https://tokyodevices.jp/items/253
PC(win)と接続
PCとES920EBをUSBケーブルで接続する
Tera Term設定
- TeraTerm起動
- 設定>端末 でローカルエコーON, 送信CR+LF
- 設定>シリアルポート でボーレート115200に設定
[参考]仕様書などのリンク
https://tokyodevices.jp/items/233
LoRa設定
コンフィグモード(設定)とオペレーションモード(通信)が存在する。
オペレーションモードで "config" を入力・リセットボタン押下するとコンフィグモードに移行する。
コンフィグモードで "q 2" "w" を入力・リセット押下でオペレーションモード移行
- Tera Term設定後、ES920EBのリセットボタン押下
- "Select Mode [1.terminal or 2.processor]" と出るので "1" or "2"(好きな方)を入力(再起動時オペレーションモードならコンフィグモードに移行)
- 帯域幅・拡散率を設定 "bw 3" "sf 7"とか(相手と一緒ならok)
- 通信モード設定 "q 2"入力
- 親子を設定 "node 1" または "node 2"入力(1:親 2:子)
- 設定を保存 "w"を入力
- リセットボタン押下
- 好きなメッセージを入力し送信する
相手側で受信が確認できなかった場合、"show" コマンドで IDやPANなどの設定を確認する。
参考
https://ambidata.io/samples/network/lora-2/
エラーメッセージはコマンド仕様書を参照する。
ラズパイ3と接続
ラズパイとES920EBをUSB接続する
Pythonで制御する
ラズパイ
Python2.7
参考 https://github.com/AmbientDataInc/LoRa-rssi-measure/tree/master/RPi3
lora.pyにLoRa利用系の関数が入ってる
の部分を、LoRaを接続したUSBSerialに対応するポートに変更する。
main.pyに動作を書く
while(True):内を書き換える形でコーディングする
続き
更新中
ラズパイ3B+でLEDJ
はじめに
このアカウントを見て興味を持ったのでやってみます。
LEDJ同好会 (@teamLEDJ) | Twitter
用意するもの
ラズパイ
LEDパネル
amazonに安いのがありますが、ピカリ館のほうは店舗チェック済みの商品らしいです。
LEDマトリクスパネル - akibaLED ピカリ館電源
定格に合ったACアダプタ切ってLEDパネル付属のコネクタにくっつけましたメス-オスのジャンパ線
またはコネクタ
配線
パネルが1枚の場合は😄のみ配線してください。 github.com
制御ライブラリ導入手順
Raspbian LiteをSDカードに書き込む
Desktopだといろんなドライバとかライブラリとか設定とかが邪魔して表示が乱れました(原因多すぎてよくわかってない)
参考 FAQ>Ghosting Issue Examples
開発者もLiteがいいよって言ってます GitHub - hzeller/rpi-rgb-led-matrix: Controlling up to three chains of 64x64, 32x32, 16x32 or similar RGB LED displays using Raspberry Pi GPIO
セキュリティの設定などしたら次へ進みましょうライブラリのダウンロード
gitコマンドやUSBなどで任意のディレクトリにrpi-rgb-led-matrixを保存コンパイル・デモ実行
cd rpi-rgb-led-matrix make
cat <<EOF | sudo tee /etc/modprobe.d/blacklist-rgb-matrix.conf >blacklist snd_bcm2835 >EOF sudo update-initramfs -u sudo reboot
sudo ./demo
次のようなオプション一覧が表示されれば成功です。
Expected required option -D <demo> usage: examples-api-use/demo <options> -D <demo-nr> [optional parameter] Options: -D <demo-nr> : Always needs to be set -t <seconds> : Run for these number of seconds, then exit. --led-gpio-mapping=<name> : Name of GPIO mapping used. Default "regular" --led-rows=<rows> : Panel rows. Typically 8, 16, 32 or 64. (Default: 32). --led-cols=<cols> : Panel columns. Typically 32 or 64. (Default: 32). --led-chain=<chained> : Number of daisy-chained panels. (Default: 1). --led-parallel=<parallel> : Parallel chains. range=1..3 (Default: 1). --led-multiplexing=<0..9> : Mux type: 0=direct; 1=Stripe; 2=Checkered; 3=Spiral; 4=ZStripe; 5=ZnMirrorZStripe; 6=coreman; 7=Kaler2Scan; 8=ZStripeUneven; 9=P10-128x4-Z (Default: 0) --led-pixel-mapper : Semicolon-separated list of pixel-mappers to arrange pixels. Optional params after a colon e.g. "U-mapper;Rotate:90" Available: "Rotate", "U-mapper". Default: "" --led-pwm-bits=<1..11> : PWM bits (Default: 11). --led-brightness=<percent>: Brightness in percent (Default: 100). --led-scan-mode=<0..1> : 0 = progressive; 1 = interlaced (Default: 0). --led-row-addr-type=<0..2>: 0 = default; 1 = AB-addressed panels; 2 = direct row select(Default: 0). --led-show-refresh : Show refresh rate. --led-inverse : Switch if your matrix has inverse colors on. --led-rgb-sequence : Switch if your matrix has led colors swapped (Default: "RGB") --led-pwm-lsb-nanoseconds : PWM Nanoseconds for LSB (Default: 130) --led-pwm-dither-bits=<0..2> : Time dithering of lower bits (Default: 0) --led-no-hardware-pulse : Don't use hardware pin-pulse generation. --led-slowdown-gpio=<0..2>: Slowdown GPIO. Needed for faster Pis/slower panels (Default: 1). --led-daemon : Make the process run in the background as daemon. --led-no-drop-privs : Don't drop privileges from 'root' after initializing the hardware. Demos, choosen with -D 0 - some rotating square 1 - forward scrolling an image (-m <scroll-ms>) 2 - backward scrolling an image (-m <scroll-ms>) 3 - test image: a square 4 - Pulsing color 5 - Grayscale Block 6 - Abelian sandpile model (-m <time-step-ms>) 7 - Conway's game of life (-m <time-step-ms>) 8 - Langton's ant (-m <time-step-ms>) 9 - Volume bars (-m <time-step-ms>) 10 - Evolution of color (-m <time-step-ms>) 11 - Brightness pulse generator Example: examples-api-use/demo -t 10 -D 1 runtext.ppm Scrolls the runtext for 10 seconds
結果
P6-16×32のLEDパネルです。
sudo ./demo -D 0 --led-rows=16 --led-cols=16
以降
LoRaモジュール(ES920LRA1B)起動まで
EASELが説明書出してますが見落としがあって苦戦したので起動までの流れをまとめます。 説明書と合わせて参考にしてください。
使用機器
ES920LRA1B
https://tokyodevices.jp/items/252
FTDI USBシリアル変換アダプター(5V/3.3V切り替え機能付き)
3.3Vに設定
https://www.switch-science.com/catalog/1032/
USBケーブル
ジャンパ線
10ピン2.54ピッチ(2×5)←→1.27ピッチ(1×10)変換基板 金フラッシュ(4個入)
http://akizukidenshi.com/catalog/g/gP-07380
Win7PC(TeraTerm,FTDI driver)
配線
ラベルを張っている側から見て左上のピンから1~13, 右下から14~26
配線箇所 1(GND),8(TX),9(RX),13(Vcc)
変換基盤を左側のみはんだ付け
FTDI USBシリアル変換アダプターにジャンパ線で接続
TeraTermでの操作
設定>シリアルポートから以下のように設定 あと設定>端末からローカルエコーON、送信CR+LF、受信CRに設定
接続後”1”を入力 ターミナルモードに入る(”2”でプロセッサモード)
コマンド一覧が出るので好きなように設定していく
たぶん “NG 001” (未定義)とか “NG 002”(オプション値以上)が出がち
説明書要参考
次やること
設定、一対一通信
参考
LoRa モジュール ES920LRA1
https://tokyodevices.jp/items/252
特定小電力無線モジュール ES920LR LoRaWAN 仕様ソフトウェア説明書 Version. 1.10 株式会社 EASEL
https://bit.ly/2ZtERkT
Raspberry Pi 3 ModelB+(Zero W)でBluetooth Low Energyのデータ利用
背景
BLE Nano v2→ATMEGA328p(Arduinoとして使ってる)→sakura.io で作ってたBLEレシーバが、横通り過ぎるだけだと1m以内でも検出に難があったので緊急的にラズパイをレシーバとして使う
目標
ラズパイ3B+でBLE機器のBDアドレスを取得する。 GPIOでArduino+sakura.ioにUART送信 できればZero Wでの実装を目指す。
方法
Python2.7
ライブラリ
あとpyserial
設定
GPIOとBluetoothで同時にシリアル使う Raspberry Pi 3で Bluetoothを生かしつつシリアル通信を有効にする方法(コンソール通信でログイン可能) (ラズパイ3で Bluetoothと UART通信の両方を使える様にする設定方法のまとめ。)
コード
scan.py pybluez/scan.py at master · pybluez/pybluez · GitHub
を元にBDアドレス取得、シリアル送信をできるようにした。やっつけなのでBDアドレスの合計値で照合してるけど、本来はUUIDを取得して照合して9600で送信した方が良いと思う。
from bluetooth.ble import DiscoveryService import re import serial import time import struct tags={取得したいBDアドレスの合計値}; def split_n(text, n): return [ text[i*n:i*n+n] for i in xrange(len(text)/n) ] ser = serial.Serial('/dev/ttyS0',38400,timeout=10) print(ser.portstr) while True: i=0 postList = [] service = DiscoveryService() devices = service.discover(2) for address, name in devices.items(): address = split_n(address.replace(':', '') ,2) sum = 0 for bd in address: sum += int(bd, 16) for t in tags: if t==sum: postList.append(struct.pack("B", (sum>>8))) postList.append(struct.pack("B", (sum&0x00FF))) if postList[0] != '\x00': ser.write(postList)
結果
問題だった検出距離は20m以上でも問題なく検出できた。 シリアル通信も成功
UUID取得とかわかったら追記するかもしれない
バイナリデータの符号拡張と解決(Arduino,C言語)
概要
Arduinoのソフトウェアシリアル入力で受け取った値をシリアルモニタで表示しようとするとFがめっちゃ出るやつの解決法。
起こったこと
BLEレシーバからソフトウェアシリアルで受けたBLEタグIDの一部'0x88'を出力しようと
char data = BLE.read(); Serial.print(data, HEX);
のように記述するとシリアルモニタに FFFFFF88 と表示され、視認性やその後の計算等に支障が出た。
原因
C言語でchar変数をintにキャストするとき、最上位ビットが '1' であると2の補数表現を維持しようと符号拡張を行う。
参考 marycore.jp
解決法
unsigned char変数に代入しておく
unsigned char data = BLE.read(); Serial.print(data, HEX);
てな感じで記述するとよいと思う。
char → int 0x88 → 0xFFFFFF88 unsigned char → int 0x88 → 0x88
IDなど16進数1byteのデータとして評価したい場合などにはこの方法でOK
まとめ
数値として評価したいときには便利なキャストの仕様だが、案外嵌りやすいので、バイナリデータいじってる人は頭の隅に置いてほしい。
単純なキャストの話なんですが、ArduinoIDEを使って開発しててキャストの話と気付かず"Arduino シリアルモニタ F めっちゃ出る"とかで検索してる人に届いて欲しい……