目次
前
WS2812B利用
小型のマイコンボードIchigoJamに接続して
使われているシリアルLED基板(WS2812B利用)
を知人から貰いました。
シリアルLED基板を扱うArduinoのライブラリが
ないかとWEBを検索すると、次の2種があります。
- Adafruit_NeoPixel
- FastLED
Adafruitのライブラリにあるクラスメソッドは
色の指定がG(緑)、R(赤)、B(青)で
HTMLの色輝度の並びと異なるので、FastLEDを
利用することに。
ArduinoとWS2812B基板を、ブレッドボードの
ワイヤーで接続して、実験環境を整備。
シリアルLEDに輝度と位置の情報を転送するには
データ線とクロックが必要ですが、WS2812Bでは
データ線のみで、1ビットのHとLの時間をかえて
1か0を指定する仕様。
物理上の仕様は、次のようにバケツリレーの要領で
データをシフトしていくとなってます。
実際のピン配置は、3ピンだけで
輝度と位置の情報をDinから与えて
いきます。
Arduinoの8ピンにDinを接続して
動かすことにしました。
8個のLEDのうち、左右のLEDは
青、赤で点灯状態にし、乱数で
緑を点灯する位置を決めること
にします。
ソースコードを作成していきます。
FastLEDライブラリを使うには、ヘッダ
ファイルを指定。
#include <FastLED.h>
クラスインスタンスを使い、使うピンと
LEDの個数を宣言。
#define WPIN 8 /* pin number */
#define LED_CNT 8 /* LED count */
/* class instatnce */
CRGB wled[LED_CNT];
FastLEDライブラリでは、WS2812Bの1個1個を
配列変数にして扱う設計思想でした。
左右のLEDの青、赤の色と、指定位置のLEDの
色を緑にするため、関数を定義。
byte ii ;
void send_location(byte x)
{
/* judge */
if ( x > 7 ) return ;
/* all white */
for ( ii = 0; ii < LED_CNT ; ii++ ) {
/* GRB intensity */
*(wled+ii) = CRGB::Black;
if ( ii == 0 ) { *(wled+ii) = CRGB::Blue ; }
if ( ii == 7 ) { *(wled+ii) = CRGB::Red ; }
}
/* set target color */
*(wled+x) = CRGB::Green;
FastLED.show(); /* enable */
}
一度、全LEDを消灯して、青、赤、緑の
点灯を指定する仕様としました。
実際のLED点灯は、ステートマシンに任せて
楽をします。
ステートマシンの初期化と動作は、以下。
#define MYINTERVAL 250
byte state ;
byte target ;
unsigned long last ;
void init_state_machine()
{
state = 0 ;
target = 0 ;
}
void state_machine()
{
switch ( state ) {
/* set GREEN */
case 0 :
send_location( target );
state = 1 ;
break ;
/* set counter */
case 1 :
state = 2 ;
last = millis() + MYINTERVAL ;
break ;
/* delay */
case 2 :
state = 2 ;
if ( millis() > last ) { state = 3 ; }
break ;
/* return first state */
case 3 :
state = 0 ;
break ;
/* others */
default :
break ;
}
}
ステートマシンの状態遷移図は、次のように
単純にしました。
ステートマシンを用意すると、関数loop()は
次のように記述できます。
void loop() {
state_machine();
target = random(8);
}
LEDは8個あり、0から7の番号づけがされて
いるので、乱数で0から7を生成。
それをLEDを緑に点灯する位置としました。
残っている関数setup()は、以下で定義。
void setup() {
FastLED.addLeds<NEOPIXEL, WPIN>(wled,LED_CNT);
init_state_machine();
}
FastLEDでは、メソッドでターゲットデバイス
ピンアサイン、LED個数を指定する仕様。
すべての定義を合体すると、以下。
#include <FastLED.h>
#define WPIN 8 /* pin number */
#define LED_CNT 8 /* LED count */
/* class instatnce */
CRGB wled[LED_CNT];
#define MYINTERVAL 250
byte ii ;
byte state ;
byte target ;
unsigned long last ;
void send_location(byte x)
{
/* judge */
if ( x > 7 ) return ;
/* all white */
for ( ii = 0; ii < LED_CNT ; ii++ ) {
/* GRB intensity */
*(wled+ii) = CRGB::Black;
if ( ii == 0 ) { *(wled+ii) = CRGB::Blue ; }
if ( ii == 7 ) { *(wled+ii) = CRGB::Red ; }
}
/* set target color */
*(wled+x) = CRGB::Green;
FastLED.show(); /* enable */
}
void init_state_machine()
{
state = 0 ;
target = 0 ;
}
void state_machine()
{
switch ( state ) {
/* set GREEN */
case 0 :
send_location( target );
state = 1 ;
break ;
/* set counter */
case 1 :
state = 2 ;
last = millis() + MYINTERVAL ;
break ;
/* delay */
case 2 :
state = 2 ;
if ( millis() > last ) { state = 3 ; }
break ;
/* return first state */
case 3 :
state = 0 ;
break ;
/* others */
default :
break ;
}
}
void setup() {
FastLED.addLeds<NEOPIXEL, WPIN>(wled,LED_CNT);
init_state_machine();
}
void loop() {
state_machine();
target = random(8);
}
8個のWS2812Bを利用しましたが、シリアル転送で
色と輝度情報を送れるので、次のような数珠繋ぎの
シートでも対応できるはず。
目次
前