目次

WS2812B利用

 小型のマイコンボードIchigoJamに接続して
 使われているシリアルLED基板(WS2812B利用)
 を知人から貰いました。



 シリアルLED基板を扱うArduinoのライブラリが
 ないかとWEBを検索すると、次の2種があります。

 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を利用しましたが、シリアル転送で
 色と輝度情報を送れるので、次のような数珠繋ぎの
 シートでも対応できるはず。


目次

inserted by FC2 system