パソコンの修復が終了したので、再びESP32の勉強を進めます。
今回は、ESP32のPWM(Pulse Width Moduration)のテストをします。
PWM出力できるポート(GPIO)は
ポート GPIO
A4 32
A5 33
A10 4
A11 0
A12 2
A13 15
A14 13
A15 12
A16 14
A17 27
A18 25
A19 26
A13 15
A14 13
A15 12
A16 14
A17 27
A18 25
A19 26
です。A0,A3,A6,A7は入力専用なので、利用できません。
PWMに使う関数は、
ledcSetup(chan,freq,bit_num); //チャンネル,周波数,ビット数
ledcAttachPin(pin,chan); //ピン番号,チャンネル
ledcWrite(chan,duty); //チャンネル,デューティ
です。
ledcSetup()で、チャンネル(0~15),PWM周波数(~40MHz),ビット数(1~16)を設定します。PWM周波数は、PWMに供給されるがクロックが80MHzですので、ビット数(分解能)によって、ビットごとの最大周波数は次のようになります。
ビット数 分解能 最大周波数(Hz)
16 65536 1220.70
15 32768 2441.41
14 16384 4882.81
13 8192 9765.63
12 4096 19531.25
11 2048 39062.50
10 1024 78125
9 512 156250
8 256 312500
7 128 625000
6 64 1250000
5 32 2500000
4 16 5000000
3 8 10000000
2 4 20000000
1 2 40000000
ledcAttachPin()で、出力ピンをどのチャンネルに接続するかを設定します。
ledcWrite()で、チャンネルのデューティ比を設定します。デューティ比は、
デューティ比=duty/bit_numです。
例として、1000HzのPWM出力をデューティ比50%で出力してみます。チャンネル0を使い、A19(GPIO26)に出力します。
スケッチです。
void setup() {
ledcSetup(0,1000,8);
ledcAttachPin(26, 0);
ledcWrite(0,128);
}
void loop() {
}
ledcSetup(0,1000,8);
ledcAttachPin(26, 0);
ledcWrite(0,128);
}
void loop() {
}
出力波形です。1000Hz デューティ比50%
ledcWrite(0,64);とするとデューティ比25%になります。
出力波形です。
ledcWrite(0,192);とするとデューティ比75%になります。出力波形です。
最大周波数を出力してみます。
ledcSetup(0,40000000,1);
ledcAttachPin(26, 0);
ledcWrite(0,1);
とすると確かに40MHzが出力されました。ただし、デューティ比は、50%だけです。
ledcAttachPin(26, 0);
ledcWrite(0,1);
とすると確かに40MHzが出力されました。ただし、デューティ比は、50%だけです。
それでは、任意の周波数は、出力できるでしょうか。
freq=7000000と設定したときの出力です。
かなりずれた周波数を発生させました。
1000Hz,10000Hz,100000Hz,1000000Hzなどは、正しい周波数を発生させることができますが、周波数によっては、かなりずれを生じます。分周期のせいでしょうか。
正確な周波数を発生させることができるなら、VFOとして使えるかな、などと期待したのですが、ちょっと無理みたいです。
チャンネルについても、いくつか実験をしたのですが、最後に指定した1つしか使えないようです。これについて、情報がありましたら、教えてください。