Arduino Uno のPWMキャリア周波数を20kHzにする
【 古いブログで掲載した記事(2020/4/4)を一部修正して再掲載します。】
Nゲージ鉄道模型で自動運転を楽しんでいます。
自動運転は、マイコンとして Arduino の Uno や Nano Every を使ってPWM制御を使って速度を調整しています。今回は Uno の場合を紹介します。
PWMキャリア周波数を 20kHz にアップする方法について、皆さんの情報をもとに自分でも調査しました。その結果、次のような実験にて確認しました。 まず実験方法はパソコンと Arduino Uno とオシロを使いました。
接続状態は下のようにオシロ用の端子を出力ポートに接続しただけの状態です。
そしてオシロで確認した波形を下に示します。
CH1はD10ポートで、CH2はD3ポートです。
CH1はD5ポートで、CH2はD3ポートです。
CH1はD9ポートで、CH2はD910ポートです。
CH1はD6ポートで、CH2はD5ポートです。
D3、D5、D10ポートでは、キャリア周波数は 20.0kHz となり、狙いどうりです。しかし、D6、D9、D11ポートではその半分の周波数で、かつ、デューティ比が50%の波形となっています。
また、正常に出力している D3、D5、D10ポート間の波形を観察すると、波形ごとにタイミングがズレている事が分かります。そして、リセットを掛けてもその状態が変わらなかったので、このタイミングのズレは内部的な必然と思われます。
実験にで使用したスケッチは、次の通りです。
// Uno 20KHzPWM test
// 2020.4.3
#include <avr/io.h>
void setup() {
pinMode(3,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
TCCR0A = 0b01100011; TCCR0B = 0b00001010; OCR0A = 99;
TCCR1A = 0b01100011; TCCR1B = 0b00011010; OCR1A = 99;
TCCR2A = 0b01100011; TCCR2B = 0b00001010; OCR2A = 99;
}
void loop() {
int vol=20;
// OCR0B = vol;
// OCR1B = vol;
// OCR2B = vol;
analogWrite(5,vol);
analogWrite(10,70);
analogWrite(3,40);
}
setup 部分で関係するレジスタの設定を行い、loop の部分でデューティ比を設定してPWMを出力しています。最初は、//の部分のようにレジスタに直接アクセスして設定しましたが、その後、analogWrite( ) のコマンドを使ってみると、正常に出力されることを確認しました。
このコマンドが使用出来るのです!
上記に示した波形は、この状態で出力した時のオシロ波形なのです。
この方法では、デューティ比を設定できるPWM出力は、D3、D5、D10ポートのみです。
D6、D9、D11ポートはデューティ比が50%の半分の周波数しか出力していませんし、これ以外に使用出来ないのです。即ち、この方法では、このポートを他の用途として使用出来ない事を示しています。これもチャンとした理由があります。
また、D3、D5、D10ポートのタイミングも一致していませんが、これもチャンとした理由があります。 その理由を下記のサイトで説明しいますので参照してください。
鉄道模型工作実験室 Arduino Uno のPWMキャリア周波数を20kHzにする
ただし、注意が必要です。
今回の処理は、ノコギリ波のトップの値を 255 から 99 に変更して20kHz 化を実施しています。従ってデューティ比の指定は0~99までしか指定できません。このため、スケッチでのanalogWritr( ) のコマンドは使用できるものの、その指定値には注意が必要です。99以上の値は無効なので、結果的にはデューティ比100%の状態になるものと推定します(未確認ですが・・・・・)。
しかし幸いなことに、0~99までで 0~100%を指定することになるので、デューティ比のパーセント表示そのままの値を使用すれば良い事になります。