Raspberry Pi Zero WをGo言語で触ってみる
※この記事は、IoTLTAdvent Calendar 2019の22日目の記事として書いています。
こんにちは、ニャンパス株式会社の登尾です。今回、手元に転がっていたRaspberry Pi Zero WをGo言語で触ってみようと思い、その模様をまとめてみました。
なぜGo言語をRaspberry Piで触ってみようとしたのかというと、下記の記事を読んで確かにJavaScriptはRaspberry Pi上でもサクッとかけて便利だけれどちょっとメンテナンスしなくなると古いランタイムでしか動かない状況になるなと思い、Go言語であればバイナリとして配布できて、安定性があると感じているため、今回Raspberry Piで試して見ました。
Rasberry Piのセットアップ
SDカードにRaspbianを入れました。今回GUI等は必要としないので、 Raspbian Buster Lite
を選んでいます。
解凍したimgファイルを、Macから書き込みました。(/dev/disk2にマウントされていることを確認して以下のコマンドを打っています。)
# diskutil unMountDisk /dev/disk2 Unmount of all volumes on disk2 was successful # sudo dd if=/Users/<user name>/Downloads/2019-09-26-raspbian-buster-lite.img of=/dev/rdisk2 bs=1m
しばらく待って書き込まれたSDカードをRaspberry Piに指し、HDMIとキーボードをつなぎます。
以下のような画面が表示され、piユーザでログインします。ログイン後に、Wifiの有効化(raspi-config
でサクッと設定)とsshdの立ち上げを行っています。
Go言語で記述したプログラムを送り込んで見る
ここからは、手元のMac環境でプログラムを書いて見ます。
IoT用のフレームワークとして、Gobotというものがあり、Raspberry Piや様々なプラットフォームに対応しているというものなので今回始めて触ってみます。
まずはインストールを行います。
go get -d -u gobot.io/x/gobot/...
しばらくまつと、以下のようにインストールされたことが確認できます。
ls ~/go/src/gobot.io/x/gobot/ CHANGELOG.md appveyor.yml drivers helpers_test.go sysfs CODE_OF_CONDUCT.md ci event.go master.go travis_build_opencv.sh CONTRIBUTING.md cli eventer.go master_test.go utils.go LICENSE.txt commander.go eventer_test.go platforms utils_test.go Makefile commander_test.go examples robot.go version.go README.md connection.go examples_test.go robot_test.go ROADMAP.md device.go go.mod robot_work.go adaptor.go doc.go go.sum robot_work_test.go api driver.go gobottest
まずはサンプルのLチカを試してみます。16番ピンを制御する以下のプログラムを記述します。
package main import ( "time" "gobot.io/x/gobot" "gobot.io/x/gobot/drivers/gpio" "gobot.io/x/gobot/platforms/raspi" ) func main() { r := raspi.NewAdaptor() led := gpio.NewLedDriver(r, "16") work := func() { gobot.Every(1*time.Second, func() { led.Toggle() }) } robot := gobot.NewRobot("blinkBot", []gobot.Connection{r}, []gobot.Device{led}, work, ) robot.Start() }
手元の環境でビルドして転送するということをするので、以下のようなMakefileを用意しました。
build: GOARM=6 GOARCH=arm GOOS=linux go build main.go deploy: scp main pi@raspberrypi.local:./
こうしておくとmake
によってビルドだけ行ったり、make build deploy
のようにビルドとデプロイを同時に行えるので便利です。(ただ、プロジェクトとして開発するのであれば、ディレクトリ構成やビルドの依存関係を記述するべきだとは思います。)
ともあれ、Lチカが実現で来ました。
GobotでAPIサーバを立てよう
Gobotのドキュメントを読んでいるとAPIサーバとしても立ち上がってくれて、かつブラウザ上で動くAPIクライアントも同梱されていることが分かりました。 最後にこの機能を使ってみようと思います。さきほどのLEDをAPI用のコマンドとして定義してます。
package main import ( "gobot.io/x/gobot" "gobot.io/x/gobot/api" "gobot.io/x/gobot/drivers/gpio" "gobot.io/x/gobot/platforms/raspi" ) func main() { master := gobot.NewMaster() api.NewAPI(master).Start() r := raspi.NewAdaptor() led := gpio.NewLedDriver(r, "16") robot := gobot.NewRobot("blinkBot", []gobot.Connection{r}, []gobot.Device{led}, ) robot.AddCommand("toggleLed", func(params map[string]interface{}) interface{} { led.Toggle() return "ok" }) master.AddRobot(robot) master.Start() }
toggleLedというコマンドが増え、このコマンドが呼ばれるとLEDの点灯が切り替わるという意図です。cURLをターミナルから実行し、実行のたびにLEDの点灯消灯が切り替わることが確認できます。
> curl 'http://raspberrypi.local:3000/api/robots/blinkBot/commands/toggleLed'
また、 http://raspberry.local:3000/ にアクセスすると、以下のように先程定義したコマンドが表示されてブラウザからも叩けるようになっています。
まとめ
軽い気持ちでRaspberry PiでGo言語のプログラムを実行してみたいということで書き始めましたが、最後にGobotのAPIサーバとしての出来に感動しました。
IoTにおいて、PoC等の用途でさくっとAPIサーバが立ち上がり、デバイスの状態を取得したりあるいは更新できるというのは大変便利な機能だと思いますので、Go言語 + Gobotの組み合わせは今後も試してみたいと思います。
コメント
コメントを投稿