PWM (Arduino IDE + ESP マイコン用ボードマネージャ)
PWM の基礎
定期的に電圧を上げ下げすることで、実効電圧を変化させることができる. これにより, 例えば LED の明るさを変化させたり, 圧電スピーカで音を鳴らすことができる.
- LED を明るくする場合には周波数を固定し、デューティー比を大きくし、暗くする場合にはデューティー比を小さくする。
- 音を鳴らす場合には、デューティー比を 50% で固定し、周波数を変えれば良い。

PWM を使う場合には ESP32 の LEDC ライブラリ (Arduino の ESP32 拡張) を用いることになる. そのため,利用できる関数については,ESP32 マイコンのメーカーである Espressif のドキュメント LED Control を参照してほしい.
よく使う関数としては以下が挙げられる.
//使用するピンのGPIOを指定 const uint32_t Pin = 19; //ピンを PWM で使う宣言 ledcAttach(Pin, 周波数, 解像度) //デューティ比の変更 ledcWrite(Pin, デューティー比); //周波数の変更 (ledcWriteTone を使うと,Duty比は自動的に 50% に変更される) ledcWriteTone(Pin, デューティー比);
デューティー比は比率 (%) で与えるのではなく, 下図でいうところの「閾値」として与える.

なお, ESP32 のクロックは 80 MHz = 12.5 μs で動作するため, 分解能をそれよりも小さくすることはできない. 逆に言うと, タイマの解像度によって表現できる最大波長が決まる. 1 bit ならば 1 / (12.5e-6 * 2) = 40 MHz, 8 bit ならば 1 / (12.5e-6 * 256) = 312.5 kHz, 13 bit ならば 1 / (12.5e-6 * 8192) = 9765 Hz, である.
例題 1: 電圧変化 (LED の明るさを変えるプログラム)
const uint32_t channel = 0; //チャンネル
const uint32_t resolv = 8; //タイマーの解像度
const uint32_t duty[3] = {0, 100, 255}; //デューティー比
const uint32_t freq = 1000; //周波数
const uint32_t pin = 14; //LED ピン
//初期化
void setup() {
ledcAttach(pin, freq, resolv); //ピンを PWM で使う宣言
}
//ループ. デューティー比を 1 秒ごとに変化させて LED の明るさを変化させる.
void loop() {
ledcWrite(pin, duty[0]);
delay(1000);
ledcWrite(pin, duty[1]);
delay(1000);
ledcWrite(pin, duty[2]);
delay(1000);
}
例題 2: 周波数変化 (圧電ブザーを鳴らすプログラム)
const uint32_t channel = 0; //チャンネル
const uint32_t resolv = 8; //タイマーの解像度
const uint32_t duty = 128; //デューティー比
const uint32_t freq[3] = {262, 294, 330}; //周波数.ド,レ,ミ
const uint32_t pin = 15; //ブザーピン
//初期化
void setup() {
ledcAttach(pin, freq[0], resolv); //ピンを PWM で使う宣言
}
//ループ. 周波数を変化させて音を変える.
void loop() {
ledcWriteTone(pin, freq[0]);
delay(1000);
ledcWriteTone(pin, freq[1]);
delay(1000);
ledcWriteTone(pin, freq[2]);
delay(1000);
ledcWrite(pin, 0); //消音
delay(1000);
}
課題
LED, スイッチ, ブザーを用いたプログラムを作成してみよ.
- スイッチを入れたら音が鳴る
- スイッチを入れると, ブザーで「ドレミファソラシド」が鳴る.
- LED の点灯に合わせてブザーから曲が流れる.
- その他
