Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Raspberry Pi + Go で IoT した話

259 views

Published on

golang.tokyo #26
https://golangtokyo.connpass.com/event/147175/

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Raspberry Pi + Go で IoT した話

  1. 1. Raspberry Pi + Go で IoT した話 2019-09-25 Takeshi Yaegashi golang.tokyo #26
  2. 2. 自己紹介 八重樫 剛史 Takeshi Yaegashi ● 株式会社バンダイナムコスタジオ所属 ● Linux・Unix・OSS・低レベルなことが好きなエンジニア ● ホームページ・ブログ https://l0w.dev ● Go のお仕事 ○ Raspberry Pi を使った IoT 案件 ○ スマホゲームアプリのサーバ ● Go のお話 ○ golang.tokyo #25「golang binary hacks」 ○ Go Conference 2019 Autumn「MS Graph API Library for Go (仮)」
  3. 3. Raspberry Pi + Go で IoT した事例を紹介します ※ 2018年の事例です。案件について具体的なお話はできません。申しわけありません。 本日のお話 Wi-Fi Router Cloud Services Edge DevicesThings
  4. 4. IoT エッジデバイス・組み込みシステムの開発に適した Go 言語 ● マイコン用のクロスコンパイルが驚くほど簡単 $ GOARCH=arm GOARM=6 go get ./cmd/hello ● シングルバイナリが扱いやすい ● 言語レベルの並行処理サポート: goroutine, chan ● システム構築に使えるライブラリ、パッケージの充実 ○ 様々なネットワークプロトコルのサポート ○ Linux カーネルなどのシステムプログラミング 本日のお話の背景
  5. 5. Raspberry Pi の GPIO・ストレージ・Wi-Fi を使ったデータ収集システム ● エッジデバイス (Raspberry Pi 0/1/2/3) ○ Wi-Fi によるインターネット接続 ○ GPIO などでイベント発生を監視、サーバに逐次送信 (MQTT) ○ サーバ接続不良時は発生イベントをMicroSDに蓄積、復旧時に再送 ○ ソフトウェアアップデートに対応 ● サーバ (AWS) ○ IoT + Lambda + DynamoDB (イベントデータ蓄積) ○ API Gateway + Lambda (デバイス登録APIなど) ○ S3 + CloudFront (アップデート配信) 事例紹介:システム概要
  6. 6. 事例紹介:エッジデバイス (Raspberry Pi) のシステム構成 pigpiod MQTT wpa_ supplicant I/O System Event Queue (LevelDB) AWS IoT dhcpcd GPIO EthernetWi-Fi timedated timesyncd ClockMicroSD System Daemons Go Process Hardware 💡💡💡 Goroutine Library mutex chan named pipe unix socketD-Bus TLS
  7. 7. 組み込み Linux システムを Go で動かす ● 組み込みシステム向けに改造した Raspbian stretch 上で動作 ○ 圧縮・耐障害ファイルシステム (squashfs + overlayfs) ○ 圧縮後のシステムイメージサイズは 100MB 程度 ● システムコンポーネントと仲良く ○ systemd, dhcpcd, wpa_supplicant などのデーモンを活用 ○ IPC (named pipe, unix socket, D-Bus) を利用して Go から制御 ● goroutine, chan の活用 ○ 基本はリソース専用 goroutine 割り当てと chan による相互通信・同期 ○ イベントキューは DB ライブラリ関数内部の mutex 同期を活用 事例紹介:エッジデバイスのシステム設計のポイント
  8. 8. コンポーネント紹介:MQTT Eclipse Paho MQTT Go client ● https://github.com/eclipse/paho.mqtt.golang ● 定番の MQTT 通信ライブラリ ● X.509 証明書によりクライアントの認証 ● QoS=1 でサーバへのデータ到達を保証
  9. 9. コンポーネント紹介:イベントキュー LevelDB によるイベントキューの実装 ● goleveldb - https://github.com/syndtr/goleveldb ○ LevelDB の Go による実装 ● goque - https://github.com/beeker1121/goque ○ goleveldb による stack/queue/priority queue ○ イベントキュー実装において参考にした ● DB 障害対策 ○ Micro SD に専用のパーティション・ファイルシステム (ext4) を作る ○ DB が壊れたら Recover() で修復、だめなら mkfs して初期化
  10. 10. コンポーネント紹介:Wi-Fi 制御 wpa_supplicant / dhcpcd ● wpasupplicant - https://github.com/dpifke/golang-wpasupplicant ○ wpa_supplicant と unix socket で通信するライブラリ ○ WPAのSSID/PSKの設定やAPスキャンなどができる ● dhcpcd - WPA 接続が確立すると自動的に IP アドレスを取得してくれる ● この他、エッジデバイスの設置と運用を支援するため、定期的にAPスキャンを行い Wi-Fi電波情報をイベントキューに入れてサーバに送信している
  11. 11. コンポーネント紹介:システム時刻設定 systemd-timedated / systemd-timesyncd ● システム時刻、タイムゾーン、NTP 設定は systemd により管理されている ● 基本的な NTP クライアントは systemd に内 蔵されている ● timedatectl - CLI ○ タイムゾーンや時刻設定に使用 ● godbus - https://github.com/godbus/dbus ○ D-Bus で制御することもできる $ timedatectl Local time: Wed 2019-09-25 05:03:11 JST Universal time: Tue 2019-09-24 20:03:11 UTC RTC time: n/a Time zone: Asia/Tokyo (JST, +0900) Network time on: yes NTP synchronized: yes RTC in local TZ: no $ timedatectl set-timezone Japan $ timedatectl set-ntp false $ timedatectl set-time "2019-09-25 19:00:00"
  12. 12. コンポーネント紹介:GPIO 制御 pigpio による GPIO 制御 ● pigpio - http://abyz.me.uk/rpi/pigpio/ ○ Raspberry Pi の GPIO を内蔵ハードで制御する C 言語のライブラリ ○ PCM/PWM クロックと GPU DMA で高速・高精度・低負荷な入出力 ○ スクリプティングエンジン搭載 ● pigpiod - pigpio デーモン ○ 名前つきパイプやソケットで別プロセスから制御 ● pigs - pigpiod のクライアント CLI ● apt-get install pigpio でインストール可能
  13. 13. コンポーネント紹介:GPIO 制御 # GPIO 5 状態読み取り $ pigs "R 5" 0 # GPIO 4 出力モード 500ms "1" パルス出力 $ pigs "M 4 W W 4 0" $ pigs "W 4 1 MILS 500 W 4 0" # GPIO 0-3 状態変化を /dev/pigpio0 に通知 $ pigs "NO" 0 $ pigs "NB 0 0x0000000F" $ cat /dev/pigpio0 @?2$8??!@*??;??!@9DK???!@B??B??!@QWrF??! pigpio スクリプト http://abyz.me.uk/rpi/pigpio/pigs.html
  14. 14. コンポーネント紹介:GPIO 制御 pin, err := os.OpenFile("/dev/pigpio", os.O_RDWR, 0) if err != nil { return err} defer pin.Close() pout, err := os.Open("/dev/pigout") if err != nil { return err } defer pout.Close() pin.Write([]byte("W 4 1 MILS 500 W 4 0")) // 3命令のスクリプトを実行 buf := make([]byte, 128) // 3命令の実行結果を取得 n, err := pout.Read(buf) if err != nil { return err } fmt.Printf("%sn", string(buf[:n])) // "0n0n0n"を表示(成功×3) Go + pigpiod:named pipe (文字列) や socket (バイナリ)で制御可能
  15. 15. コンポーネント紹介:GPIO 制御 Go + pigpiod:用途を選ぶが、はまれば非常に便利 ● 利点 ○ Go だけでは難しいレベルのリアルタイム I/O が可能になる ○ 全 GPIO 端子で解像度 5μs (200kHz) の入出力を実現 ○ 強力なスクリプトで様々な機能を実装可能 ■ チャタリング除去つきの入力パルス検出 ■ プロシージャによるインジケータLED自動点滅制御 ● 欠点 ○ 遅延が大きい (スクリプト制御は必ずコンテキストスイッチを伴う) ○ pigpiod の CPU 負荷が高い (3B+ で 7〜10%)
  16. 16. コンポーネント紹介:GPIO 制御 その他の Go I/O ライブラリの紹介 ● gobot.io - https://gobot.io ○ Raspberry Pi 以外もサポートする汎用のライブラリ ○ メモリマップ I/O による低遅延な入出力 ● periph.io - https://periph.io ○ gobot.io と同様な汎用ライブラリ ○ 徹底した高速化・最適化 ○ pigpio のような GPU DMA 入出力を pure Go で実装 ○ 開発が活発、現時点で一番おすすめできるライブラリ
  17. 17. まとめ Raspberry Pi + Go で IoT エッジデバイスを作った事例を紹介しました IoT や組み込みの分野で Go をもっと活用していきましょう!

×