Lチカをしてみる | arduino ESP32ロボットプログラミング

2023年12月7日

ESP32でLEDを点灯したり点滅させたりするにはArduinoのdigitalWrite関数を使う事もできますが、明るさを変えることはできません。QumcumにはRGB三原色のLEDがありますので、赤緑青の明るさも変えることで表現できる色が7色から何万通りもの色の表現ができるようになります。ここでは3種類のLED制御方法を試してみます。

クムクムロボット(ESP32SE,PRO)でLEDを点灯する

クムクムロボットには、RGB3色のLEDが搭載されています。

このLEDは一つのLEDに見えますが内部にRGBの3つのLEDが内蔵されています。それぞれのLEDとESP32のピンアサインは以下の通りです。

 

LED色 ESP32 IO
IO32
IO27
IO33

 

digitalWrite() 関数を使う

では一番簡単な digitalWrite() 関数を使って点灯させてみます。

void setup() {
  pinMode(32, OUTPUT); // RGB-LED(Red)
  pinMode(27, OUTPUT); // RGB-LED(Green)
  pinMode(33, OUTPUT); // RGB-LED(Blue)
}
void loop() {
  // RGB-LED(Red) ON
  digitalWrite(32, HIGH);
  delay(200);  // Wait 200msec
  // RGB-LED(Red) OFF
  digitalWrite(32, LOW);
  delay(200);  // Wait 200msec
  // RGB-LED(Green) ON
  digitalWrite(27, HIGH);
  delay(200);  // Wait 200msec
  // RGB-LED(Green) OFF
  digitalWrite(27, LOW);
  delay(200);  // Wait 200msec
  // RGB-LED(Blue) ON
  digitalWrite(33, HIGH);
  delay(200);  // Wait 200msec
  // RGB-LED(Blue) OFF
  digitalWrite(33, LOW);
  delay(200);  // Wait 200msec
}

RGBのLEDが順に点滅すれば成功です。このdigitalWrite関数ではLEDをHIGHにするかLOWにするか、つまり点灯するか消灯するかしか指定できません。次に明るさを変えてみます。

 

analogWrite() 関数を使う

analogWrite()関数は、引数に
pin: 出力に使うピンの番号
value: デューティ比(0から255)
を指定します。
valueが0で0Vの電圧が出力され、255で3.3Vが出力されます。valueは0から255の任意の数値を指定できます。ここでは、for文を使って0から255まで徐々にRGB各色LEDが順に明るくなるプログラムにしてみます。

 

void setup() {
}
const int ledport[]={32,27,33};

void loop() {
  for(int color=0;color<sizeof(ledport)/sizeof(ledport[0]);color++){
    for(int value=0;value<=256;value++){
      analogWrite(ledport[color], value%256);
      delay(10);  //Wait 10mSec
    }
  }
}

 

ledcWrite() 関数を使う

上記2つのdigitalWrite()、analogWrite() はArdunoの共通関数として使えますが、ESP32の場合は独自のライブラリに多くの関数やクラスが用意されており、ここでは、ledcWrite()を使ってみます。この関数ではPWM周波数や解像度の指定ができます。PWMとは何? については、いろんなサイトで説明がありますのでキーワード”PWM”で検索してください。PWMを使う事で実は明るさを変えるということは高速に点滅してLEDの点灯時間を変えることで実現しています。

digitalWeite()ではLEDは点灯したままですが、analogWrite()では実際にはLEDが超高速に点滅しています。それをもっと積極的に点滅の周波数や変化割合の解像度まで指定できるようにしたのがledcWrite()関数になります。ですのでledcWrite()関数を使うには周波数と解像度の設定を先に行う必要があります。

ここでは先のanalogWrite() と同じように、RGBの各LEDを徐々に明るくしてみます。解像度は8bitとしていますので、0から255までの数値が指定できます。10にすれば10bitで0から1023まで指定できますが、人の目で見てそこまで細かい解像度を使っても区別できないので8bitとしています。周波数は1kHzとしています。

 

const int ledport[]={32,27,33}; //ch0,ch1,ch2
const int n=sizeof(ledport)/sizeof(ledport[0]);

void setup() {
  for(int ch=0;ch<n;ch++){
    ledcSetup(ch, 1000, 8); //ch, 1kHz, 8bit
    ledcAttachPin(ledport[ch], ch);
  }
}

void loop() {
  for(int ch=0;ch<n;ch++){
    for(int value=0;value<=256;value++){
      ledcWrite(ch, value%256);
      delay(10);//Wait 10mSec
    }
  }
}

 

 

Espreddif社の LED Control (LEDC) 説明ページは以下のURLにありますが、Arduinoのライブラリのアップデートとドキュメントが必ずしも一致していないことがあります。

https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/ledc.html#arduino-esp32-ledc-api

ESP32はArduino CCが純正としてサポートしているマイコンではありませんので、チップメーカーのドキュメントやソースコードを確認する必要が出てきます。