こんにちは、ENGかぴです。
ESP32シリーズにおいてPWMは通常のArduinoライブラリでなく専用のライブラリを使用する必要があります。PWMで振動波形を生成しブザーを鳴らす方法やPWMのデューティー比を変更して直流モーターを駆動する方法をまとめています。
ESP32-WROOM-32E開発ボード(秋月電子)を使用しArduino IDEで開発を行います。
ESP32-WROOM-32Eを使って動作確認したことをまとめています。
ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方
PWM波形を出力する

PWM波形でキャリア周波数を変更するとブザーの音程を変更することができます。キャリア周波数を固定しデューティー比を変更することで平均電圧を制御することができます。
PWMのチャンネル設定からピンの設定などの初期化の例やキャリア周波数を変更してブザーの音程を変える方法、デューティー比を設定する方法を説明しています。
PWM波形を出力するピンの初期化
ESP32シリーズでは通常のArduinoライブラリとはPWM波形の生成の仕方が異なります。ESP32シリーズ専用に実装された関数を組み合わせてPWM波形を出力します。
#define BUZ_PIN 5
#define MOTOR_PIN 32
void setup() {
ledcSetup(0,1000,8); //チャンネル0、キャリア周波数1kHz、8ビットレンジ
ledcAttachPin(BUZ_PIN,0); //PWMピンにチャンネル0を指定
ledcSetup(1,1000,16); //チャンネル1、キャリア周波数1kHz、16ビットレンジ
ledcAttachPin(MOTOR_PIN,1); //PWMピンにチャンネル1を指定
}
PWMは特にライブラリをインクルードする必要はありません。
ledcSetup()ではPWMを管理するチャンネルについて設定します。第1引数にチャンネル番号として0~15を指定します。
第2引数にはPWMのキャリア周波数を設定します。キャリア周波数はPWM波形のパルスの周波数となり周波数が高いほど精細なPWM波形となります。
第3引数にPWMのビット数を指定します。8ビットを指定すると0~255の範囲でデューティー比を設定でき、16ビットを指定すると0~65535の範囲でデューティー比を設定することができます。
ledAttachPin()はPWMに使用するピンの設定を行います。第1引数にPWM出力するGPIOピンの番号を指定します。第2引数にPWM設定を行ったチャンネル番号を指定します。
PR:わからないを放置せず、あなたにあった最低限のスキルを身に着けるコツを教える テックジム 「書けるが先で、理解が後」を体験しよう!
キャリア周波数を変更してブザーを鳴らす
PWMにおいてキャリア周波数が一定であるとブザーは鳴りますが音程に変化を与えることができません。音程を変更するためにはキャリア周波数を変更する必要があります。ESP32シリーズでは音名が定数として実装されています。
ledWriteTone(0, 500); //チャンネル0のキャリア周波数を500Hzにする
//使用例
ledWriteNote(0,NOTE_F,3); //チャンネル0でオクターブ3でNOTE_Fの音を出す
ledWriteTone(0,0); //音を停止する場合
ledWriteTone()で第1引数にPWM設定したチャンネルを指定します。第2引数にキャリア周波数をしていします。キャリア周波数が変更できるため音程を変えることができます。
LedWriteNote()は定数で定義された音名とオクターブを指定して音程を作ることができます。第1引数にPWM設定したチャンネルを指定します。第2引数に音名を指定します。音名の変数はnote_tとしてenumで順番に定義されています。
typedef enum {
NOTE_C, //ド
NOTE_Cs, //ド#
NOTE_D, //レ
NOTE_Eb, //レ#
NOTE_E, //ミ
NOTE_F, //ファ
NOTE_Fs, //ファ#
NOTE_G, //ソ
NOTE_Gs, //ソ#
NOTE_A, //ラ
NOTE_Bb, //ラ#
NOTE_B, //シ
NOTE_MAX
} note_t;
第3引数はオクターブを指定します。オクターブは0~8まで指定することができます。数値が大きくなるほど音色が高くなります。
PR:(即戦力のスキルを身に着ける:DMM WEBCAMP 学習コース(はじめてのプログラミングコース))
デューティー比を設定する
PWMのデューティー比はパルスのHIGHとLOWの比率です。キャリア周波数に対してHIGHの時間が長いほどデューティー比が高くなり、平均電圧が高くなります。
uint16_t duty; //デューティー比を16ビットで管理する
//使用例
ledcWrite(1,duty); //チャンネル1をdutyで指定したデューティー比で出力
ledcWrite()を使用するとledcSetup()で指定したキャリア周波数とレンジに対応したPWM波形を生成することができます。第1引数にPWM出力するチャンネルを指定します。第2引数にデューティー比を指定する値を指定します。
LedcSetup()で指定したビット数に対応してデューティー比を計算します。デューティー比を50%にしたい場合は8ビットの場合は128を指定し、16ビットの場合は32768を指定します。
デューティー比の計算方法の例
8ビット:128/255 ≒50%
16ビット: 32768/65535≒50%
PR:スキマ時間で自己啓発!スマホで学べる人気のオンライン資格講座【スタディング】まずは気になる講座を無料で体験しよう!
動作確認

ESP32-WROOM-32Eとブザーやモーターの配線例を示しています。回路図の番号はESP32-WROOM-32Eの左上を1ピンとした時反時計回りにピンを数えた場合の番号としています。ピン番号横の()内の番号はシルク印刷されているピンの名称です。
PWM0はブザーを鳴らすために使用しています。音色とオクターブを変更しながらブザーが鳴るのを確認します。オクターブが低い間はブザーの音がほとんど聞こえずにプツプツとした音が聞こえますが、オクターブが高くなる(キャリア周波数が高くなる)に連れて「ピッ」という音が聞こえるようになります。
PWM1はモーターの駆動に使用しています。デューティー比を少しずつ高くしていき平均電圧が高くなってくるとモーターが回転を始めます。トランジスタのベースを抵抗を実装していますがベース電流を絞り過ぎるとトランジスタで電流を増幅してもモーターが回転しなくなるため調整が必要です。

シリアルモニタでブザーの音が「ピッ」鳴りだすオクターブ数を確認したところ3付近でした。モーターを回転させるためのデューティー比については8000付近からモーターが回転し始めました。
ソースコード全体
ソースコードは記事作成時点において動作確認できていますが、使用しているライブラリの更新により動作が保証できなくなる可能性があります。また、ソースコードを使用したことによって生じた不利益などの一切の責任を負いかねます。参考資料としてお使いください。
リンクからZIPファイル形式のファイルをダウンロードし、任意の場所に展開していただくとテキストファイルが生成されます。
関連リンク
Arduinoのライブラリを使って動作確認を行ったことを下記リンクにまとめています。
Arduinoで学べるマイコンのソフト開発と標準ライブラリの使い方
Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方
ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方
PR:
わからないを放置せず、あなたにあったスキルを身に着けるコツを教える テックジムPython入門講座の申込
最後まで、読んでいただきありがとうございました。