Arduino(アルディーノ)

ArduinoによるRGB-LEDの制御

更新日:

WS000008写真のようなテープライトはamazonや楽天などで簡単に購入することができるものです。
これには、単純にLEDのRGB個別電源ラインに対して電源供給の制御を行い様々な効果を作り出すタイプと、コントロール用の専用LSI(シリアルLED IC)が搭載され、このLSIに対して信号を送り出し効果を作り出すタイプという2つのタイプがあります。
1つ目の【単純電源制御】タイプについては、全てのLEDが同時に点灯や消灯したりフェードイン・フェードアウトが可能ですが、個別にLEDを制御することができません。
2つ目の【LSI制御】タイプは、接続されているLED全てを1個づつ個別に制御することが可能です。そのため、このタイプは『流れるテープライト』と呼ばれています。

今回はこの2種類について技術面からまとめてみます。

単純電源制御タイプ

1.テープライトの構造

WS000012

上記写真のようにLEDチップと抵抗によって構成されています。
その回路構成は下記のようになります。
WS000007この回路を見てわかるように、チップ3個をひとかたまりとして、それを並列につないでいるのがテープライトの構造です。
そのため、写真のように3個単位で接続された構造になり、3個単位で切り離し別々に使えるようになっています。
使用されているLEDチップの多くは5050というタイプで、チップ1個は約3V~4Vで動作するため、頭で12V電圧を与え、これを直列に3個使用することで1個あたり3V~4Vの電圧を得ています。
抵抗は各RGBのチップに対して必要な電流制御を行うためです。

プログラムによる制御

これは、単純にRGBの各チップに対してPWMポートを接続し、プログラムによって制御を行えばよいだけですから単純です。

LSI制御タイプ

RGB式LEDを制御するためのコントロールLSIには何種類か存在します。
その中の代表?として今回はWS2811を例にとってご説明います。

シリアルLEDチップとLEDの接続図

下記の図のように、RGB-LEDをとLSIを数珠繋ぎに繋いでます。
プログラムでは、各LSI用のバッファーを用意しておき、そこにRGBの値を代入し、一定周期のタイミングをとって送出することで各LEDをコントロールします。
WS2811の仕様書は こちら で、このハード仕様書に基づき電気的タイミングを作り制御するわけですが、これは結構シビアなクロック制御が必要となります。

WS2811

 

プログラム処理

上記仕様書に基づき制御プログラムを作成するわけですが、結構大変なのでここではネットで公開されているライブラリーを利用することにします。

1.FastLED

SPIを利用して制御しているプログラムです。
処理速度は後述Adafruit NeoPixcelよりは遅く感じます。

#include "FastLED.h"

//LEDバッファーを必要個数分用意する
CRGB leds[1];

void setup() { 
  FastLED.addLeds<NEOPIXEL, 6>(leds, 1); 
  //           |    |   |   |
  //                |     |    |   +--LEDの数量 上記配列数と同じ
  //                |     |    +--宣言したCRGBバッファ配列
  //                |     +--接続ポート番号 PWMを選択
  //                +--使用するLEDDriver WS2811はこのままでもよい
}
void loop() { 
  leds[0] = CRGB::White; //1個目色の指定
  FastLED.show();     //表示
  delay(30); 
  leds[0] = CRGB::Black; //黒にする→消す
  FastLED.show();        
  delay(30);
}

2.Adafruit_NeoPixel

内部はアセンブラーで一部かかれており、FastLEDより高速で使いやすいライブラリーです。
しかし、Arduinoの内部タイマーを使用するため、同時に2本までのLEDテープしか独立してコントロールできません。

#include <Adafruit_NeoPixel.h>

#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
                            |  |   |     |
                                            |    |    |        +--clock
                                            |    |    +---LEDの並び方
                                            |    +--接続ポート     
                                            +--LEDの数
//独立して2本までは下記のように宣言して制御可能
#define PIN2 7
Adafruit_NeoPixcel strip2=Adafruit_NeoPixcel(60,PIN2,NEO_GRB+NEO_KHZ800);

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  strip.setPixcelColor(0,strip.Color(255,0,0))
                    // |      | 
                    // |      +---赤にセット
                    // +--LED番号
  strip.show();
} 

最後に

WS2811を使用した場合、LSIに与えられたデータはDINから通りDOUTに抜けていき、次のLSIに伝達されます。
そのため、途中どこかのLSIが1個壊れるとそれ以降のLEDが一切光らない!制御できないという状態になります。
そのために、進化版としてWS2812Sが販売されています。
今後は、WS2812S使用のLEDテープライトを使用するほうが便利でしょう。
また、5050チップ以外に、下記のような防水タイプのLED球も中国サイトでは販売されています。
実は、この球を利用し、下記のようなガソリンスタンド看板をArduinoとの組み合わせで開発し、半年間屋外で元気に動作しています。

WS000014

IMG_1301

 

-Arduino(アルディーノ)

Copyright© プログラミングテクニック集キヤミー , 2020 All Rights Reserved.