mbed NUCLEO-F401REでWS2812BのフルカラーLEDストリップを使ってみた
2017年にAliexpressのこのお店から買って積んだままになっていたWS2812B搭載のフルカラーLEDストリップを動かしてみた。といっても、WS2812用の汎用ライブラリ(各ボードのクロックにあわせて、NOPの個数を調整することで、WS2812が要求するpulse width modulationの波形を出力するもの)を使っただけ。
いくつかの代表的なボードについては、WS2812_Exampleのページの方に、コンストラクタで指定すべきNOP数が掲載されています。Nucleo-F401RE用のものが運良く載っていたので(コンストラクタの引数の順番に、3, 12, 9, 12)、そのまま使わせてもらいました。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#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はじめて使ったんですが、すごいキレイ。いくらでも見てられます。