ArduinoとシリアルLED(WS2812B)

 

シリアルLEDの仕組みと使い方をArduinoで制御しながら解説
シリアルLEDの仕組みと使い方をArduinoで制御しながら解説

この記事では、ArduinoでシリアルLED(WS2812B)を動かす方法をくわしく解説いたします。

シリアルLEDは、電流の許す限りいくつもの同じシリアルLEDを数珠つなぎで増設できるLEDです。中でもテープ状になっているシリアルLEDがよく使われます。好きな長さにカットして使うことができるので、広告看板や室内の装飾、クリスマスや小規模なプロジェクトにもお使いいただけます。シリアルLEDのライブラリを使って、Arduinoからカンタンに色や明るさを制御できますので、ぜひご参考になさってみてください。

シリアルLEDの制御に必要なデータ通信線はたったの1本です。ひとつのArduinoで数百個のシリアルLEDを制御するなんてことも不可能ではありません。しかも、各シリアルLEDは独立してRGBフルカラーで点灯可能です。

シリアルLEDとは

シリアルLEDは、もともと中国のWorldSemi社が開発したもので「NeoPixel」と呼ばれています。Neo PixelのシリアルLEDは、ひとつひとつの単品でも購入可能ですが、テープの形のものや、マトリックスになっているものが便利です。

とくに、テープ状になっているシリアルLEDは、ハサミで好きな長さにカットして使用できます。表面は柔らかい透明な樹脂でコーティングされており、裏面には両面テープが貼られてます。

▼ また、カットしたテープLEDをつなげるためには、次のようなコネクタケーブルがあると便利です。

本記事では紹介するのは「WS2812B」のシリアルLEDの制御方法となります。ご購入の際は、「WS2812B」という名前がついているものをお選びください。

開発環境

本記事でおこなった実験の開発環境は次の通りです。

項目バージョン
ArduinoデバイスSeeeduino XIAO
シリアルLEDBTF-LIGHTING WS2812B LEDテープライト 1m
Arduino IDE1.8.10
パソコンmacOS Big Sur 11.0.1

▼ 今回購入したBTF-LIGHTINGのLEDテープライトです。WS2812BのシリアルLEDが60個ついています。

購入したWS2812BのLEDテープライト
購入したWS2812BのLEDテープライト

▼ Arduinoは「Seeeduino XIAO」を使いましたが、他のArduinoでももちろん構いません。

Seeeduino XIAOの使い方はSeeeduino XIAOでArduino開発をはじめように書きました。

もしArduino初心者の方で「どのArduinoを選べばよいか分からない」といった方は、オススメArduinoどれを選べばいい?Arduinoで電子工作をはじめる方へをご参考になさってみてください。

シリアルLEDの仕組み

ここではシリアルLEDの仕組みをカンタンに説明したいと思います。

シリアルLEDの構造

シリアルLED「WS2812B」を拡大した写真をご覧ください。

シリアルLEDの拡大写真
シリアルLEDの拡大写真

シリアルLEDをよく見ると、写真のようなICチップが埋め込まれています。これによって、Arduinoなどから送られてきたデータを受け取り、赤・緑・青のRGBカラーを点灯できる仕組みとなっています。

図中のDOUTには、次のシリアルLEDのDINへ接続されます。冒頭で述べたとおり、いくつものシリアルLEDを数珠つなぎのようして接続します。また、ひとつひとつのLEDは独立して色や明るさを変えられます。

シリアルLEDArduino
VDD5V
VSSGND
DINデジタルピン
DOUT次のシリアルLEDのDIN

シリアルLEDの制御信号の流れ

シリアルLEDの制御信号の流れをカンタンに説明します。

シリアルLEDへ送る制御信号の流れ
シリアルLEDへ送る制御信号の流れ

ひとつのシリアルLEDがDINから送られてきたデータを受信すると、先頭のデータだけ取り出し、残りのデータをDOUTから他のシリアルLEDへ渡す流れになっています。それぞれのデータの中には、赤・緑・青のLEDの明るさ情報が入れられており、それに基づいて各シリアルLEDは点灯されるのです。

データが空になれば、その先のシリアルLEDには届きません。よって予め、制御したいシリアルLEDの数分だけデータを作っておく必要があります。ただし今回はAdafruitの出しているNeo Pixcelライブラリを使用するので、難しいプログラミング作業はほとんどありませんのでご安心ください。

シリアルLEDとSeeeduino XIAOの配線

シリアルLEDとSeeeduino XIAOの配線はこちらの図のようになりました。

シリアルLEDとSeeeduino XIAOの配線図
シリアルLEDとSeeeduino XIAOの配線図

デジタルピン1番をシリアルLEDのDINへつないでいますが、もちろん他のピンでも構いません。シリアルLEDは5V電圧で動作しますが、Arduinoから電源供給するのではなく出来れば別電源を用意してお使いください。数十個のLEDを制御しようとするとArduinoからでは電流が足りなくなるからです。ただしGNDはArduinoと共通にしてください。

また、配線図ではシリアルLEDを数珠つなぎにしてますが、テープライトを使用する場合は予め数珠つなぎに配線されてますので、テープの末端のDIN端子にArduinoのデジタルピンを1つ繋げば済みます。

シリアルLEDテープライトの拡大写真
シリアルLEDテープライトの拡大写真

ライブラリのインストール

シリアルLED(WS2812B)をArduinoでカンタンに制御できるように、AdafruitがリリースしているNeoPixelのライブラリをインストールします。

Arduino IDEのメニューで、SketchInclude LibraryManage LibraresLibrary Manager を開きます。

そこで「neopixel」で検索し、Adafruit NeoPixel/Arduino library for controlling single-wire-based LED pixels and strip.をインストールします。

ライブラリマネージャから「NeoPixel」で検索
ライブラリマネージャから「NeoPixel」で検索

シリアルLEDのプログラム例

ここからは、実際にArduinoでシリアルLEDを制御していきます。

シリアルLEDを1つだけ点灯させてみよう

シリアルLEDを1つだけ点灯させた画像
シリアルLEDを1つだけ点灯させた画像

まずは、シリアルLEDを1つだけ点灯させてみましょう。プログラムは次の通りです。

/*
  Created by Toshihiko Arai.
  https://101010.fun/iot/arduino-serial-led.html
*/

#include <Adafruit_NeoPixel.h>

const int DIN_PIN = 1; // D1
const int LED_COUNT = 60; // LEDの数

Adafruit_NeoPixel pixels(LED_COUNT, DIN_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin();
}

void loop() {
  pixels.clear();
  pixels.setPixelColor(0, pixels.Color(128, 0, 0)); // 0番目の色を変える
  pixels.show();
}

プログラムの解説

まず、pixels(LEDの数, DINに繋ぐArduinoのデジタルピン, NEO_GRB + NEO_KHZ800)で初期化します。制御するシリアルLEDの数を正しくセットしてください。他の型番のシリアルLEDではNEO_GRB + NEO_KHZ800を変える必要があるので注意しましょう。

pixels.clear()を呼び出すことで、すべてのシリアルLEDがリセットされ、点灯しているLEDが消灯します。シリアルLEDの色を変える場合はpixels.setPixelColor(LED番号, 色) のように制御したいシリアルLEDの番号と色を指定します。

pixels.Color(128, 0, 0)では、赤・緑・青の順で0から255の範囲で明るさをセットします。数字が大きいほど明るくなりますが、シリアルLEDは非常に明るいので小さい値でも十分キレイです。

詳しくは、 AdafruitのNeoPixelライブラリー をご確認ください。

シリアルLEDの色を赤→緑→青の順に変える

シリアルLEDの色が赤緑青の順で変化する映像
シリアルLEDの色が赤緑青の順で変化する映像

今度は、先ほどのプログラムのloop関数の中を次のように変えてみましょう。シリアルLEDの色が、赤 → 緑 → 青の順番で変化します。

void loop() {
  pixels.clear();
  pixels.setPixelColor(0, pixels.Color(128, 0, 0)); // red
  pixels.show();
  delay(1000);

  pixels.clear();
  pixels.setPixelColor(0, pixels.Color(0, 128, 0)); // green
  pixels.show();
  delay(1000);

  pixels.clear();
  pixels.setPixelColor(0, pixels.Color(0, 0, 128)); // blue
  pixels.show();
  delay(1000);
}

60個のシリアルLEDを順番に点灯させる

60個シリアルLEDを高速で順番に点灯させている映像
60個シリアルLEDを高速で順番に点灯させている映像

今度は60個のシリアルLEDを順番に点灯させてみます。loop関数の中を次のように変えましょう。まるで光が生き物のように光が動いて面白いです。

void loop() {
  for(int i=0; i<LED_COUNT; i++) {
    pixels.clear();
    pixels.setPixelColor(i, pixels.Color(0, 0, 128)); // red
    pixels.show();
    delay(10);
  }
}

シリアルLEDで虹を走らせてみた

シリアルLEDテープライトで虹を走らせるている映像
シリアルLEDテープライトで虹を走らせるている映像

最後にシリアルLEDで虹を走らせてみましょう。C言語の配列を使っているのでちょっと難しく感じるかもしれませんが、少しずつ慣れていってください。

/*
  Created by Toshihiko Arai.
  https://101010.fun/iot/arduino-serial-led.html
*/

#include <Adafruit_NeoPixel.h>

const int DIN_PIN = 1; // D1
const int LED_COUNT = 60; // LEDの数

Adafruit_NeoPixel pixels(LED_COUNT, DIN_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin();
}


uint32_t red = pixels.Color(128, 0, 0);
uint32_t orange = pixels.Color(128, 82, 0);
uint32_t yellow = pixels.Color(128, 128, 0);
uint32_t green = pixels.Color(0, 128, 0);
uint32_t cyan = pixels.Color(0, 128, 128);
uint32_t blue = pixels.Color(0, 0, 128);
uint32_t purple = pixels.Color(128, 0, 128);

uint32_t rainbow_color[] = {red, orange, yellow, green, cyan, blue, purple};
int rainbow_index[] = {6, 5, 4, 3, 2, 1, 0};

void loop() {
  
  for(int i = 0; i < LED_COUNT; i++) {    
    pixels.clear();    
    for(int j = 0; j < 7; j++) {
      rainbow_index[j] = i + 6 - j;
      if(rainbow_index[j] >= LED_COUNT) rainbow_index[j] -= LED_COUNT;
      
      pixels.setPixelColor(rainbow_index[j], rainbow_color[j]);
    }
    pixels.show();
    delay(20);
  }
}

以上でシリアルLED(WS2812B)の基本的な使い方の説明を終わります。

▼ シリアルLEDを使って、実用的なRGBライトも作ってみました。よかったらこちらの記事もご参考になさってみてください。

最後に、くどいようですが、シリアルLEDを購入する際は型番に注意しましょう。「WS2812B」であれば、この記事で紹介したライブラリが使えますし、書籍やネットにも情報が多くありますのでオススメです。

記事に関するご質問などがあればTwitterへお返事ください。
この記事で紹介した商品
人気のArduino互換機
Arduinoで人気の周辺パーツ
Arduinoのオススメ参考書

▼ Arduino初心者向きの内容となっています。ほかのArduino書籍と比べて図や説明がとてもていねいで、読みやすかったです。Arduinoで一通りのセンサーが扱えるようになります。

▼ 外国人が書いた本を翻訳したものです。この手の書籍は、目からうろこな発見をすることが多いです。

▼ Arduinoの入門書を既に読んでいる方で、次のステップを目指したい人向きの本です。C言語のプログラミングの内容が中心です。ESP32だけでなく、ふつうのArduinoにも役立つ内容でした。

関連記事