Raspberry PiからWS2812BというLEDを操作してみました。Amazonで60個のLEDが繋がっているものを購入しましたが、白黒、防水の有無で4種類あります。防水の白を買いました。
Golangインストール
とりあえず、Golangインストールします。アーキテクチャが armv6l
のものを選択します。
$ version=1.10.1 $ wget https://storage.googleapis.com/golang/go${version}.linux-armv6l.tar.gz $ sudo tar -C /usr/local -xzf go${version}inux-armv6l.tar.gz $ echo "export PATH=\$PATH:/usr/local/go/bin" >> ~/.profile $ . ~/.profile $ go version go version go1.10.1 linux/arm
WS2812操作用ライブラリ
WS2812の操作にはこちらのライブラリを利用します。
git cloneしてきた後はSCons使ってビルドします。
$ sudo apt-get install scons
$ git clone https://github.com/jgarff/rpi_ws281x.git
$ cd rpi_ws281x/
$ scons
ビルドしたCのライブラリを所定のフォルダにインストールしておきます。
$ sudo cp -ai ./ws2811.h ./rpihw.h ./pwm.h /usr/local/include/ $ sudo cp -ai ./libws2811.a /usr/local/lib/
Golangのライブラリをインストールします。
$ go get -u github.com/jgarff/rpi_ws281x/golang/ws2811
exampleプログラム
Exampleが用意されているので、まずは実行してみます。
$ cd ~/go/src/github.com/jgarff/rpi_ws281x/golang/examples/
変数の調整
以下の3つの変数で動きを調整できます。
const ( pin = 18 // GPIOピン(PWM) count = 16 // 操作するLEDの数 brightness = 255 // LEDの明るさ )
LEDの数の 60
を count
の変数に入れます。
他にも変数名の通り、 pin
でGPIOを指定、brightness
でLEDの明るさを指定できます。
example実行
これでexampleのプログラムの準備ができました。ビルドしてsudoで実行します。
$ cd golang/examples/
$ go build basic.go
$ sudo ./basic
動かしてみたところです。
exampleを改造してみる
このexampleのコアになっているws2811.goというファイルはかなりシンプルなので、読みながら何ができるか試せばすぐに使い方がわかってきます。
サンプルプログラム
簡単なサンプルプログラムです、赤、青、白の帯が動きます。
設定
以下の設定ができるようにしました。
const ( pin = 18 // GPIOピン series = 4 // 同じ色のLEDが連続する数 count = 60 // LEDの数 brightness = 100 // LEDの明るさ interval = time.Millisecond * 100 // 動きのスピード )
色も適当にコメントアウトしたり外したりします。
var ( colors = []uint32{ 0xFFFFFF, //white //0xFF0000, //green 0x00FF00, //Red 0x0000FF, //Blue //0x00FFFF, //pink //0xFFFF00, //yellow //0xFF00FF, //light blue } )
ソース全体
package main import ( "fmt" "time" "github.com/jgarff/rpi_ws281x/golang/ws2811" ) const ( pin = 18 series = 4 count = 60 brightness = 100 interval = time.Millisecond * 100 ) var ( colors = []uint32{ 0xFFFFFF, //white //0xFF0000, //green 0x00FF00, //Red 0x0000FF, //Blue //0x00FFFF, //pink //0xFFFF00, //yellow //0xFF00FF, //light blue } ) func main() { defer ws2811.Fini() err := ws2811.Init(pin, count, brightness) if err != nil { fmt.Println(err) } else { gen := genLedSet() for { set := gen() for i, c := range set { if i == count { break } ws2811.SetLed(i, c) } err := ws2811.Render() if err != nil { ws2811.Clear() } time.Sleep(interval) } } } func color() func() uint32 { i := -1 return func() uint32 { i++ return colors[i%len(colors)] } } func vLeds() []uint32 { alength := series * len(colors) for { if alength >= count { break } alength += alength } return make([]uint32, alength) } func genLedSet() func() []uint32 { color := color() base := 0 return func() []uint32 { vled := vLeds() for i := base; i < base+len(vled); { color := color() for j := 0; j < series; j++ { vled[i%len(vled)] = color i++ } } base++ return vled } }
動かしてみるとこんな感じです。
簡単なのに、なかなか迫力あります。