2017年にAliexpressのこのお店から買って積んだままになっていたWS2812B搭載のフルカラーLEDストリップを動かしてみた。といっても、WS2812用の汎用ライブラリ(各ボードのクロックにあわせて、NOPの個数を調整することで、WS2812が要求するpulse width modulationの波形を出力するもの)を使っただけ。
いくつかの代表的なボードについては、WS2812_Exampleのページの方に、コンストラクタで指定すべきNOP数が掲載されています。Nucleo-F401RE用のものが運良く載っていたので(コンストラクタの引数の順番に、3, 12, 9, 12)、そのまま使わせてもらいました。
#include "WS2812.h" #include "mbed.h" // Total number of LEDs in a strip const int NUM_LEDS = 100; // Wait duration between shift const float WAIT_DURATION_SEC = 0.005; // Instantiates WS2812 class. // WS2812(PinName pin, int size, // int zeroHigh, int zeroLow, int oneHigh, int oneLow); // The following values (3,12,9,12) are confirmed to work with Nucleo-F401RE. // See https://os.mbed.com/users/bridadan/code/WS2812_Example/ for values known // to work with other boards. WS2812 ws(D8, NUM_LEDS, 3, 12, 9, 12); DigitalOut led(LED1); // Buffer that stores color data of each LED. int buffer[NUM_LEDS]; // Color data of rainbow-like gradation const size_t NUM_RAINBOW_COLORS = 21; uint32_t RAINBOW_COLORS[NUM_RAINBOW_COLORS] = { // 0xff0000, // 0xff4000, // 0xff8000, // 0xffbf00, // 0xffff00, // 0xbfff00, // 0x80ff00, // 0x40ff00, // 0x00ff00, // 0x00ff40, // 0x00ff80, // 0x00ffbf, // 0x00ffff, // 0x00bfff, // 0x0080ff, // 0x0040ff, // 0x0000ff, // 0x4000ff, // 0x8000ff, // 0xbf00ff, // 0xff00ff}; // Lower brightness by reducing RGB values. void dimmer(uint8_t numShiftedBits) { for (size_t i = 0; i < NUM_LEDS; i++) { const uint8_t red = ((buffer[i] & 0x00FF0000) >> 16) >> numShiftedBits; const uint8_t green = ((buffer[i] & 0x0000FF00) >> 8) >> numShiftedBits; const uint8_t blue = (buffer[i] & 0x000000FF) >> numShiftedBits; buffer[i] = (red << 16) + (green << 8) + blue; } } // Fills LED color buffer with rainbow data. void fillBuffer(uint32_t startIndex) { uint32_t index = 0; startIndex = startIndex % NUM_LEDS; const uint32_t endIndex = startIndex + 10; for (size_t i = 0; i < NUM_LEDS; i++) { if (startIndex <= i && i < endIndex) { buffer[i] = RAINBOW_COLORS[index]; index++; index %= NUM_RAINBOW_COLORS; } else { buffer[i] = 0; } } // Lower brightness dimmer(4); } int main() { uint32_t startIndex = 0; // Periodically shifts start position of the rainbow color. while (1) { wait(WAIT_DURATION_SEC); led = !led; fillBuffer(startIndex); startIndex++; ws.write(buffer); } }
ボードのD8ピンと、LEDストリップのデータピン、GNDとGND、5Vと5Vを接続。上記コードをコンパイルして書き込んで実行すると、虹色が動いているように光ります。フルカラーLEDはじめて使ったんですが、すごいキレイ。いくらでも見てられます。
Leave a Reply