PWM (Arduino IDE + ESP マイコン用ボードマネージャ)

PWM の基礎

定期的に電圧を上げ下げすることで、実効電圧を変化させることができる. これにより, 例えば LED の明るさを変化させたり, 圧電スピーカで音を鳴らすことができる.

  • LED を明るくする場合には周波数を固定し、デューティー比を大きくし、暗くする場合にはデューティー比を小さくする。
  • 音を鳴らす場合には、デューティー比を 50% で固定し、周波数を変えれば良い。

PWM を使う場合には ESP32 の LEDC ライブラリ (Arduino の ESP32 拡張) を用いると良い. C 言語版 esp-idf の API Reference の LED Control のドキュメントを参照して雰囲気を掴むことが必要となる.Overview に書かれているように, 以下の操作が必要となる.

//使用するピンのGPIOを指定
const int Pin = 19; 

//pwmの設定. 最初の引数が channel, 次が周波数, 最後が解像度(ここでは8bit = 256段階)
ledcSetup(0,12800,8); 

//ピンをチャンネルに接続
ledcAttachPin(Pin,0)

//チャンネル 0 に接続されたピンに 128 / 256 = 0.5 = 50% のデューティー比で出力. 
ledcWrite(0,128);

ESP32 は最大で 16 チャンネル分の PWM 制御を行うことができ, 複数のピンを同じチャンネルにまとめて一度に制御することもできる.

また, デューティー比は比率 (%) で与えるのではなく, 下図でいうところの「閾値」として与える.

なお, 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, である.

LED の明るさを変えるプログラムの書き方

LEDC のサンプルをそのまま使うことができる. 「スケッチ例」-> 「ESP32」-> 「AnalogOut」-> 「LEDCSoftwareFade」を選択.

スケッチ内の LED_PIN の番号を演習用マイコンボードの LED のピン番号に変更せよ.

// fade LED PIN (replace with LED_BUILTIN constant for built-in LED)
#define LED_PIN            13

コンパイルしてボードに書き込みを行うと、指定した LED の明るさが定期的に変化することがわかる

圧電ブザーを鳴らすプログラムの書き方

ブザーを鳴らす

LEDC のサンプルを利用する. 「スケッチ例」-> 「ESP32」-> 「AnalogOut」-> 「LEDCSoftwareFade」を選択.

スケッチ例 (LEDCSoftwareFade) を単純化したものが以下である.

1  // use first channel of 16 channels (started from zero)
2  #define LEDC_CHANNEL_0     0
3 
4  // use 8 bit precission for LEDC timer (0 ~ 255)
5  #define LEDC_TIMER_8_BIT  8 
6 
7  // use 5000 Hz as a LEDC base frequency
8  #define LEDC_BASE_FREQ     5000
9 
10 // ブザーの Pin
11 #define buzzerPin 15
12 
13 void setup() {
14   // Setup timer and attach timer to a buzzer pin
15   ledcSetup(LEDC_CHANNEL_0, LEDC_BASE_FREQ, LEDC_TIMER_8_BIT);
16   ledcAttachPin(buzzerPin, LEDC_CHANNEL_0);
17 }
18 
19 void loop() {
20   uint32_t pwm = 128;  //duty比 0.5 (8 bit 256 の半分)
21   ledcWrite(LEDC_CHANNEL_0, pwm);
22   // wait for 30 milliseconds to see the dimming effect
23   delay(30);
24 }
  • 2 行目: チャンネル 0 用のマクロを用意.
  • 5 行目: タイマの設定. ここでは 8 bit の分解能用のマクロを用意.
  • 8 行目: 周波数を設定. 周波数を高くすれば当然音も高くなり, キーンという感じになる.
  • 11 行目: 圧電ブザーの接続されているピンの GPIO を設定.
  • 15 行目: pwmの設定. 最初の引数 がchannel, 次が周波数, 最後が解像度(ここでは8bit = 256段階)
  • 16 行目: ピンをチャンネルに接続
  • 20-21 行目: デューティー比 50% で矩形波を作成し出力.

課題

LED, スイッチ, ブザーを用いたプログラムを作成してみよ. ただし、LED の明るさは定期的に変化させること。