ESP32でRGB フルカラーLEDを使用して、さまざまな色でLEDを点灯させてみたいと思います。
ESP32とRGB LEDの接続
ESP32とRGB LEDを接続していきます。
準備するもの
今回使用するものは、以下になります。
- ESP32
- ブレッドボード
- ジャンパーワイヤー
- RGB LED
- 抵抗(220Ω)
RGB フルカラーLED
RGB LEDは、秋月電子通商様から「RGBフルカラーLED 5mm OSTA5131A カソードコモン」を購入しました。
RGB LEDは接続タイプが「カソードコモン」と「アノードコモン」のものがあり、カソードコモンは共通ピンをGNDに接続し、アノードコモンは共通ピンに電圧を加えます。
LEDが1つだけでフルカラーを表現できるのは、すごいです。
接続
部品を以下のように接続していきます。
一番長いピンがGNDになっています。LEDからピンが4つ出ているので、間違わないように注意して下さい。
プログラム作成
RGB LEDの色を設定して、点灯させるだけのプログラムになります。
プログラム
// PWM出力ピン
const int RED = 21;
const int GREEN = 19;
const int BLUE = 18;
// PWMチャンネル
const int PWM_CH_RED = 0;
const int PWM_CH_GREEN = 1;
const int PWM_CH_BLUE = 2;
int red_val = 255;
int green_val = 0;
int blue_val = 0;
void setup() {
ledcSetup(PWM_CH_RED, 1000, 8);
ledcAttachPin(RED, PWM_CH_RED);
ledcSetup(PWM_CH_GREEN, 1000, 8);
ledcAttachPin(GREEN, PWM_CH_GREEN);
ledcSetup(PWM_CH_BLUE, 1000, 8);
ledcAttachPin(BLUE, PWM_CH_BLUE);
ledcWrite(PWM_CH_RED, red_val);
ledcWrite(PWM_CH_GREEN, green_val);
ledcWrite(PWM_CH_BLUE, blue_val);
}
void loop() {
}
プログラムについて簡単に説明していきます。
2~4行目で、PWM出力用のピン番号を設定しています。設定は、RGB LEDの各ピン(RGB)の接続先になります。
7~8行目で、PWMの出力チャンネル番号を設定しています。
11~13行目で、RGB LEDピンにそれぞれ出力するための値(RGB)を定義しています。
今回のプログラムでは、setup()関数で初期化とLEDへのPWM出力を行っているだけになり、loop()関数は使用していません。
16、18、20行目で、PWMの初期設定を行い、17、19、21行目で、それぞれの出力ピンにPWMチャンネルを設定しています。
23~25行目で、各チャンネルにPWM出力を行っています。
実際に色を変更する場合は、11~13行目で定義した変数に「0~255」の値を設定することで、様々ないろを表現することが出来ます。
動作確認
実際に接続、プログラム書き込みを行って、動作させてみました。
とりあえず赤色を点灯させてみました。続いて、緑色、青色とやってみました。写真ではわかりずらいですが、きれいに色が変わっています。
指定した色にLEDを点灯させることが出来ました。写真だとちょっと微妙ですが、原色系の色は目視だとそこそこキレイに点灯させることが出来ました。
ただ結構まぶしいので、ずっと見てはいられないです。
構成の変更
色を混ぜてみようと思ったのですが、毎回プログラムを書き込むのがつらくなってきました。
なので、ロータリーエンコーダーを3つ使用して、RED、GREEN、BLUEのそれぞれの色を手動で変更できるように、回路変更とプログラム変更を行います。
といっても、単純にロータリーエンコーダーの追加だけなので簡単です。
接続
部品を以下のように接続していきます。
プログラム
プログラムを以下のように変更します。
#include <RotaryEncoder.h>
// PWM出力ピン
const int RED = 21;
const int GREEN = 19;
const int BLUE = 18;
// PWMチャンネル
const int PWM_CH_RED = 0;
const int PWM_CH_GREEN = 1;
const int PWM_CH_BLUE = 2;
// RGB LED出力値
byte red_val = 0;
byte green_val = 0;
byte blue_val = 0;
// ロータリーエンコーダー用設定
const int RTE_RED_A = 22; // RED_A入力
const int RTE_RED_B = 23; // RED_B入力
const int RTE_GREEN_A = 26; // GREEN_A入力
const int RTE_GREEN_B = 27; // GREEN_B入力
const int RTE_BLUE_A = 12; // BLUE_A入力
const int RTE_BLUE_B = 14; // BLUE_B入力
// ロータリーエンコーダークラス変数
RotaryEncoder encoderR(RTE_RED_A, RTE_RED_B, RotaryEncoder::LatchMode::TWO03);
RotaryEncoder encoderG(RTE_GREEN_A, RTE_GREEN_B, RotaryEncoder::LatchMode::TWO03);
RotaryEncoder encoderB(RTE_BLUE_A, RTE_BLUE_B, RotaryEncoder::LatchMode::TWO03);
int lasttime = 0;
void setup() {
Serial.begin(115200);
delay(100);
ledcSetup(PWM_CH_RED, 1000, 8);
ledcAttachPin(RED, PWM_CH_RED);
ledcSetup(PWM_CH_GREEN, 1000, 8);
ledcAttachPin(GREEN, PWM_CH_GREEN);
ledcSetup(PWM_CH_BLUE, 1000, 8);
ledcAttachPin(BLUE, PWM_CH_BLUE);
pinMode(RTE_RED_A, INPUT_PULLUP);
pinMode(RTE_RED_B, INPUT_PULLUP);
pinMode(RTE_GREEN_A, INPUT_PULLUP);
pinMode(RTE_GREEN_B, INPUT_PULLUP);
pinMode(RTE_BLUE_A, INPUT_PULLUP);
pinMode(RTE_BLUE_B, INPUT_PULLUP);
encoderR.setPosition(0);
encoderG.setPosition(0);
encoderB.setPosition(0);
}
// ロータリーエンコーダー制御
void encoderProc(int md, byte *value) {
switch(md){
case 0:
encoderR.tick();
*value = encoderR.getPosition();
break;
case 1:
encoderG.tick();
*value = encoderG.getPosition();
break;
case 2:
encoderB.tick();
*value = encoderB.getPosition();
break;
default:
break;
}
}
void loop() {
encoderProc(PWM_CH_RED, &red_val);
ledcWrite(PWM_CH_RED, (int)red_val);
encoderProc(PWM_CH_GREEN, &green_val);
ledcWrite(PWM_CH_GREEN, (int)green_val);
encoderProc(PWM_CH_BLUE, &blue_val);
ledcWrite(PWM_CH_BLUE, (int)blue_val);
if(millis() - lasttime > 500){
char dispChar[24] = "";
sprintf(dispChar, "0x%02x%02x%02x", red_val, green_val, blue_val);
Serial.println(dispChar);
lasttime = millis();
}
}
プログラムが少し長くなってしまいましたが、ロータリーエンコーダーの初期化と処理を3つ分追加しただけなので、難しいところは一切ありません。
75~91行目のloop()関数で、それぞれのロータリーエンコーダーの値を取得して、RGBのそれぞれのピンにPWM出力を行っています。
また、85~90行目で500msごとに、現在のRGBの出力値を16進数でシリアルモニタに出力しています。
動作確認
実際に動作させて確認してみます。
左側から、RED、GREEN、BLUEのつまみになります。それぞれ回して色とシリアルモニタの出力で、正常に動作しているか確認してみます。
シリアルモニタには、正常にRGBが16進数で表示されているようです。
とりあえず何種類か色を設定してみました。原色系はいい感じで色が設定できていました。ただ、ちょっとした色を作ろうとすると難しく、写真だと細かい判別がつきません。
左から、イエロー、アクア、ディープピンク、オレンジ、ホワイトです。
その他の色は明るいところだと微妙ですが、暗いところでぼやっとしてみると、そこそこいい感じな気がします。
まとめ
ESP32でRGBフルカラーLEDを使用して、様々な色の表示を試してみました。
LED1個で様々な色を表現できるのは、かなり楽しいです。
色の設定は、RGBの各255ビットでPWM出力を使用した設定になります。原色の赤、緑、青などは、とてもきれいに点灯させることが出来ましたが、薄い色、白が混ざるような色は なかなか設定が難しかったです。キレイに点灯させるには、原色系か、濃い色がよさそうな気がしました。
また、色見本などのRGB設定では なかなか思った色にならないので、微調整が必要です。まあ、できたと思っても しょせん私の目視なので ほぼあてになりませんが。
ただ、発光が明るすぎてしまったので、もうちょっと抵抗を大きめのものに変えたほうが目には優しそうです。
【参考図書】