こんにちは、キャスレーコンサルティング・SI(システム・インテグレーション)部のfkmtです。

前回の「GoでLチカ」の続きです。

まずは「Lピカ」、その後に「Lチカ」を行います。


go-rpio

GoでGPIO(ラズパイの端に剣山のように突き出しているアレ)を制御するライブラリを
公開している方がいらっしゃたので、ありがたく利用させていたきます。

https://github.com/stianeikeland/go-rpio

最近は、各種言語にパッケージ管理のツールがありますが、Goではgo getというコマンドで行います。

# `go get ${githubのURL}` とやると
# src配下にソースがダウンロードされ、pkg配下にビルドされる
go get github.com/stianeikeland/go-rpio

# v3.0.0のタグに切り替えて、念のためリビルド
cd $GOPATH/src/github.com/stianeikeland/go-rpio

git checkout -b v3.0.0 refs/tags/v3.0.0

go clean -x -i

go install

$GOPATH/pkg/*/github.com/stianeikelandに「go-rpio.a」ができていればOKです。

Lピカ

チカチカさせる前に、まずはピカッと点灯させてみます。

package main

import (
	"fmt"
	"os"
	"time"

	"github.com/stianeikeland/go-rpio"
)

func main() {
	fmt.Println("start")

	// 準備
	err := rpio.Open()

	if err != nil {
		// エラーだったら終わり
		fmt.Println(err)
		os.Exit(1)
	}

	// GPIOは21ピンを使用(※1)
	pin := rpio.Pin(21)
	// 21ピンを出力にする(※2)
	pin.Output()

	// 点灯
	pin.High()

	// 3秒寝る
	time.Sleep(3 * time.Second)

	// 消灯
	pin.Low()

	// 後始末
	rpio.Close()
	fmt.Println("stop")
}

特に難しいことはしていないので、ご覧になればおおよそ分かるかと思いますが、
※印の箇所について補足をいたします。

※1: GPIOピン
各ピンは使い道が決められていて、5Vや3.3Vの出力、Groundなどがあります。
今回は何番のピンでも構わないのですが、挿し間違えないように、端のGPIO21のピンを使っています。
詳しく知りたい方は、RaspberryPi公式サイトをご覧ください。(⇒こちら
※2: 出力モード
GPIOピンには入力と出力のモードがあり、今回はLEDに対する出力に使うので「出力」に設定しています。
センサーからの入力などに使う場合は、「入力」の設定します。

上記コードを$GOPATH/src/sample/light.goに配置し、
$GOPATH/src/samplego run light.goというコマンドを叩くと、3秒光って終了します。

Lチカ

次は、チカチカ点滅させます。
しかし、それだけだと味気ないので、無限ループにしてCtrl-Cで停止するようにします。

シグナルを処理するためにchannelを使って、Go言語の機能の一端に触れてみましょう。

package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/stianeikeland/go-rpio"
)

func main() {
	fmt.Println("start")

	err := rpio.Open()

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	pin := rpio.Pin(21)
	pin.Output()

	// SIGINTを受信する用のチャネル
	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGINT)

	loop := true

	for loop {
		select {
		case s := <-ch:
			fmt.Printf("signal receive: %v\n", s)
			if s == syscall.SIGINT {
				// SIGINTを受けたらループを終わらせる
				loop = false
			}
		default:
			// HighとLowを切り替え
			pin.Toggle()
			// 1秒は緩慢すぎてチカチカ感がでないので25ミリ秒に
			time.Sleep(25 * time.Millisecond)
		}
	}

	// タイミングにより、LEDが点灯したままになるので消灯させる
	pin.Low()

	rpio.Close()
	fmt.Println("stop")
}

上記コードを、$GOPATH/src/sample/blink.goに配置し、
$GOPATH/src/samplego run blink.goというコマンドを叩くと、
25ミリ秒おきに点灯/消灯を繰り返し、Ctrl-Cで停止します。


おわりに

今回はGo言語でのLチカをご紹介しましたが、いかがでしたでしょうか。

Lチカという内容のためgoroutineを使う機会がなく、Go言語の紹介としては物足りなさがあります。
次の機会にGo言語を使ったブログを、書きたいと思います。

最後までお読みいただき、ありがとうございます。