通常のanalogWrite関数では「R4」でも「R3」同様にPWM周波数が490Hzに固定されているようなんですが、「R4」には「PwmOut」というクラスが用意されていて、そっちを使うと周波数(周期)をμ秒単位で指定できて、さらにピン毎でそれぞれ異なる周波数を設定できるよう。試しにPwmOutクラスを使って、PWM周波数を変更してみました。
▼Arduino UNO R4▼
最初はR3同様、RA4M1のレジスタを触りに行こうかと思っていたのですが pwm.h なるものが準備されているのを発見。もとより準備されてる物を使った方がはるかに簡単です。
まずは普通にAnalogWriteでPWM出力
void setup() { analogWrite(2, 128); } void loop() {}
まずは通常のanalogWriteの記述してデフォルトの周波数を確認してみます。あえて2番ピンからPWM出力指示。ArduinoのデータシートではPWMの割り当ては6本だけ(2番ピンは割り当て無し)ですが、RA4M1のデータシートではかなり多くのピンにPWMの割り当てがありました。なので試しに2番ピンからPWM出力を記述してます。
出力結果
2番ピンからでもPWM出力されました。また周波数はR3同様の490Hz程度。2番ピンからのPWM出力はArduino仕様にはないので自己責任で。ちなみにR4の場合、PWMピン3/5/6/9/10/11番全てのピンでデフォルト周波数は490Hz程度でした。
PwmOutクラスを使ったPWM出力(周波数の変更)
// 2023/11/29 imo lab. // https://garchiving.com/ #include "pwm.h" PwmOut pwm3(3); PwmOut pwm5(5); PwmOut pwm6(6); void setup() { pwm3.begin(50, 25); //周期 50us = 20kHz; パルス幅 25us = 50% pwm5.begin(100, 0); //周期 100us = 10kHz; パルス幅 0us = 0% pwm5.pulse_perc(25.0); //duty 25% = 25us pwm6.begin(200, 0); //周期 200us = 5kHz; パルス幅 0us = 0% pwm6.pulseWidth_us(20); //パルス幅 20us = 10%; } void loop() {}
3番、5番、6番ピンにそれぞれ異なる周波数、パルス幅を出力するようにしてます。analogWriteに比べると少しだけ使い方が複雑です。
出力結果
上から順に3、5、6番ピンです。ともに設定通りの周波数とDuty比で PWM がそれぞれ出力されてます。ただし複数ピンで同時にPWM出力する場合には、どうもArduinoで指定されているPWMピン(3/5/6/9/10/11番ピン)からしかうまく出力されないようです。
簡単にソース解説
#include "pwm.h" PwmOut pwm3(3); PwmOut pwm5(5); PwmOut pwm6(6);
pwm.hをインクルード。インスタンス化の引数はピン番号。
pwm3.begin(50, 25); //周期 50us = 20kHz; パルス幅 25us = 50%
.beginでPWM出力を開始します。引数は、PWM周期[μs]、パルス幅[μs]。
pwm5.pulse_perc(25.0); //duty 25% pwm6.pulseWidth_us(20); //パルス幅 20us
1行目はパルス幅をDuty比[%]で設定、2行目は時間[μs]で設定できる関数です。他にも、周波数(周期)を個別で設定する関数などいろいろ準備されているようです。
とりあえず周波数1MHz(周期1μs)までは出力されることは確認しました。PWM周波数をピン毎に柔軟に設定できるのはanalogWriteよりいいですね。
コメント