RaspberryPi×Go言語で電子工作

raspberrypi_go

エウレカでPairsのweb開発を担当しています、小島です。

業務ではPairsフルスクラッチでGo言語尽くしな毎日で、自宅では自作スマート家電・夢のスマートホームを目指しRaspberryPi等を使用して電子工作したりしています。

今回は RaspberryPi × Go言語 で環境構築から簡単に外部ハードウェアと連携させて動かす何かをつくってみようとおもいます。

使用機器

本体:Raspberry Pi TypeB 512MB http://www.amazon.co.jp/dp/B00CBWMXVE
OS:Raspbian JESSIE https://www.raspberrypi.org/downloads/raspbian/
SDカード:32GB http://www.amazon.co.jp/dp/B004BDNLZI

Go環境の設定

golangをapt-getでインストールできれば一番手っ取り早かったのですが、うまく動かない・1.3未満の古いバージョンしか無い など辛くなってくるのでここはGoのソースをクローンして直接ビルドします。

  1. まずは各種必要なパッケージをいれます。
$ sudo apt-get install -y gcc libc6-dev mercurial
  1. Goのソースコードをクローンします。
$ cd /usr/local
$ sudo hg clone -u default https://code.google.com/p/go

作業フォルダ直下にgoがダウンロードされます。

  1. goのソースコードをビルド
$ cd go/src
$ sudo ./make.bash

※ビルドに30分以上はかかりますので、ご辛抱ください。

  1. 最後にGOROOT,PATH,GOPATHを設定
<br />#ダウンロードしたgoファイルパスを指定
export GOROOT=/path/to/go
# go コマンドを使用するためのパス設定
export PATH=$PATH:$GOROOT/bin
# go get でソースをダウンロードするファイルパス
export GOPATH=/repos/gohome # どのディレクトリでも指定可

さて、これでGoを使用できる環境が整いました。

Goを動かしてみる

「Hello World」で動作を確認します。
適当なディレクトリに下記main.goファイルを作成し、go runコマンドで実行します。

package main

import "fmt"

func main() {
    fmt.Println("Hello world!")
}
$ go run main.go
Hello world!

これでやっとRaspberryPiでGoの実行環境が整いました。
次はハードウェアとの連携をしてみましょう。

LEDを光らせる

まずはLEDを点滅させてみましょう。

使用部品

・LED 1つ
・ブレッドボード 1つ
・ジャンパーワイヤ(オス-メス)2本
・抵抗器(270Ω) 1つ

電子工作自体が初めての場合はRaspberryPiの初心者キットが販売されているので、それを購入するのがおすすめです。ほとんどのセットには上記部品が含まれていると思います。(念のためご確認を…)

実装する

今回はGo言語製ロボティクスフレームワークのgobotを使用して、開発します。
Raspberry PiはもちろんArduinoやLeap Motionなど各種ハードウェア連携に対応させる事ができ、サンプルも充実しています。

まずはgobotをgo getしましょう。

$ go get github.com/hybridgroup/gobot

サンプルには既にRaspberryPiでLEDを光らせるプログラムが用意されているので、そちらを動かしてみます。

・github.com/hybridgroup/gobot/examples/raspi_blink.go

package main

import (
    "time"

    "github.com/hybridgroup/gobot"
    "github.com/hybridgroup/gobot/platforms/gpio"
    "github.com/hybridgroup/gobot/platforms/raspi"
)

func main() {
    gbot := gobot.NewGobot()

    r := raspi.NewRaspiAdaptor("raspi")
    led := gpio.NewLedDriver(r, "led", "7")

    work := func() {
        gobot.Every(1*time.Second, func() {
            led.Toggle()
        })
    }

    robot := gobot.NewRobot("blinkBot",
        []gobot.Connection{r},
        []gobot.Device{led},
        work,
    )
    gbot.AddRobot(robot)
    gbot.Start()
}

とりあえず実行確認

・LED点滅実行確認

$ go run github.com/hybridgroup/gobot/exsamples/raspi_blink.go
2015/12/07 06:33:46 Initializing Robot blinkBot ...
2015/12/07 06:33:46 Initializing connections...
2015/12/07 06:33:46 Initializing connection raspi ...
2015/12/07 06:33:46 Initializing devices...
2015/12/07 06:33:46 Initializing device led ...
2015/12/07 06:33:46 Starting Robot blinkBot ...
2015/12/07 06:33:46 Starting connections...
2015/12/07 06:33:46 Starting connection raspi...
2015/12/07 06:33:46 Starting devices...
2015/12/07 06:33:46 Starting device led on pin 7...
2015/12/07 06:33:46 Starting work...

これで動くかと思いきや、停止させた際にエラーが発生

・エラー

2015/12/07 07:30:58 Error: Robot "blinkBot": Connection "raspi": open /sys/class/gpio/unexport: permission denied

調べるとGPIOの操作にはroot権限がいるようです。
なのでsudoをつけて再実行し、エラーが出なくなりました!

部品を配置

次は電子部品を電子基板(今回はブレッドボード)に設置していきます。
以下gobotのledサンプルページに設置例が載っているので以下のページを参考に配置します。
参考:http://gobot.io/documentation/drivers/led/

GPIOのピンはRaspberryPiのSDカードスロットを上に向けた時下記のようにピンに番号が振られています。

SDカードスロット側
1 2
3 4
5 6
7 8
︙
23 24
25 26

まず、GND側(-)の線を25番ピンへ・そしてPIN側(+)の線をサンプルコードで指定している7番ピンへと差し込みます。

これで準備は完了です。
そして再度実行

$ sudo go run github.com/hybridgroup/gobot/exsamples/raspi_blink.go
2015/12/07 06:33:46 Initializing Robot blinkBot ...

LED点滅が確認出来ました!

赤外線モーションセンサーを使ってみる

次は赤外線モーションセンサーを使用します。

使用部品

・赤外線モーションセンサー 1つ
・ブレッドボード 1つ
・ジャンパーワイヤ(オス-メス)2本
・抵抗器(270Ω) 1つ

モーションセンサーを付ける

・赤外線モーションセンサー
20151209_172610_jpg__2322×4128_

手前にある3っつのピンを左からRaspberryPiの25番, 7番, 2番へとそれぞれつなぐ様に配線していきます。
20151209_172535_jpg__2322×4128_

下記の用な感じです。
20151209_190310

実装

gobotにはモーションセンサー用のドライバーが用意されていません。
なので、下記のようにして”RaspiAdaptor”が持っているピンのデータから直接センサーの値を読み取ります。

v, _ := r.DigitalRead("7")

これで取れる値を計測してみると

通常時:0, 検知:1

で取れていました。これは都合いいですね。
今回はセンサーが検知したらスラックへ通知を飛ばす実装も追加します。

main.go

package main

import (
"time"

"github.com/bsoo/rasp_motion_censor/slack"
"github.com/hybridgroup/gobot"
"github.com/hybridgroup/gobot/platforms/raspi"
)

const (
SensorValueDetect   = 1
SensorValueUndetect = 0
)

func main() {
gbot := gobot.NewGobot()
r := raspi.NewRaspiAdaptor("raspi")
postData := slack.NewPostData(`何かが動きました…`, `rasp`, `:ghost:`)

work := func() {
gobot.Every(3*time.Second, func() {
// 7番ピンから直接センサーの値を読み取る
v, _ := r.DigitalRead("7")
if v == SensorValueDetect {
slack.Post(postData)
}
})
}
robot := gobot.NewRobot("blinkBot",
[]gobot.Connection{r},
nil,
work,
)
gbot.AddRobot(robot)
gbot.Start()
}

slack/slack.go

package slack

import (
"encoding/json"
"net/http"
nurl "net/url"
"strings"
)

const (
url = `https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
)

type PostData struct {
Text      string `json:"text"`
UserName  string `json:"username"`
IconEmoji string `json:"icon_emoji"`
}

func NewPostData(txt, userName, icon string) PostData {
return PostData{
Text:      txt,
UserName:  userName,
IconEmoji: icon,
}
}

func Post(d PostData) error {
// json
jsonBody, err := json.Marshal(d)
if err != nil {
return err
}

// parameters
v := nurl.Values{}
v.Add("payload", string(jsonBody))

// request
req, err := http.NewRequest("POST", url, strings.NewReader(v.Encode()))
if err != nil {
return err
}

req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

client := http.Client{}
resp, err := client.Do(req)

if err != nil {
return err
}

defer resp.Body.Close()
return nil
}

これで完成です。
これを実行し、センサーに手をかざしてみると…
Slack 5

通知が来ました!

最後に

gobot使えるようになると扱えるデバイスが増えるので、Go言語・ハードウェア・電子工作に興味があるなら触っておくべきフレームワークだと思います。
今回は軽く動作を確かめる程度の物しか作れていないので、今度は複数センサーを同時に使う等、もっと凝った物作ってみます。

  • このエントリーをはてなブックマークに追加

エウレカでは、一緒に働いていただける方を絶賛募集中です。募集中の職種はこちらからご確認ください!皆様のエントリーをお待ちしております!

Recommend

No UIという考え方とUIデザイナーのこれから

DIを使ってAndroidでイイ感じにテストを書く