NOBのArduino日記!

NOBのArduino日記!

趣味は車・バイク・自転車・ラジコン・電子工作です。

ArduinoUNOでPWMのデューティー比を測る!

イメージ 1
 
  デューティー比(以下”D比”)をArduinoで測るのにだいぶハマりました・・・2年程
 
※超非効率なDuty比測定プログラム(測定精度はそこそこで、測定時間がかなり長い)から始まり、測定精度と測定速度向上を狙いローパスフィルターを使ってPWMを電圧に変換してDuty比を測定する(OPアンプを4~8個も使う?な回路)等々紆余曲折しました。
 
 ラジコンの制御はサーボモーターもDCモーターも全てPWM信号のDuty比を変化させる事で動作しており、Arduinoでラジコンを半自動運転(半とは自分もラジコンで遊びたいのでプロポで操作も可能にするの意味です、全自動ではなく半自動にしたのがハマりポイントでした)するにはどうしてもDuty比を高速・高精度に測定する必要が有りました。
 

1. プログラム

 色々遠回りしましたが結局プログラムの作り方が悪かったと言うオチでした(;'∀')
 Arduinoには割り込みと言う便利な機能が備わっており、この機能を使うことで必要な時に最低限の処理で高精度にDuty比の値をリアルタイムで取得できます。
 以下割り込みを使ったDuty比測定プログラムです。
// PWM信号のD比測定
volatile unsigned long UpNew;
volatile unsigned long UpOld;
volatile unsigned long DownNew;
volatile unsigned long DownOld;
volatile float Duty;                  //測定したD比

void setup() {
  pinMode(2, INPUT_PULLUP);           //割込を監視する2番ピンをプルアップし入力に設定
  attachInterrupt(0, SUB, CHANGE);    //2番ピンの電圧変化時にSUBを実行
  Serial.begin(9600);                 //シリアル通信を9600bpsで開始
}

void loop() {
  Serial.println(Duty);               //SUBルーチンで測定したDuty比をPCに送信
  delay(1000);                        //1000ms(一秒)待つ
}

void SUB() {
  if (digitalRead(2) == LOW) {        //もし2番ピンがLOWなら{}内を実行する
    DownOld = DownNew;                //DownOldに前回の電圧の立下り時刻を保存
    DownNew = micros();               //DownNewに現在の時刻を保存
    Duty = ((DownNew - UpNew) * 1000) / ((UpNew - UpOld)) * 0.1; //D比計算
  }
  else {                              //もし2番ピンがLOWでなかったら(HIGHなら)以下の{}内を実行する
    UpOld = UpNew;                    //UpOldに前回の電圧の立上り時刻を保存
    UpNew = micros();                 //UpNewに現在の時刻を保存
    Duty = ((DownNew - UpOld) * 1000) / (UpNew - UpOld) * 0.1; //D比計算
  }
}
イメージ 1
図1:プログラム例

 

 

2. 測定限界の確認!

2.1 周波数 
 オシロスコープ(DSO Nano v3)にはPWM信号を出力する機能が備わっているので、オシロスコープ出力端子をArduinoUNOの2番ピンとGNDに、それぞれプラスとマイナスを接続します。
 接続後オシロスコープからD比50%PWM信号の周波数を50、100、200、500、1000、2000、5000Hzと出力し、何処までDuty比をArduinoUNOで測定可能か試してみました。  測定の結果2000Hz迄ArduinoUNOでDuty比を測定出来ました。
イメージ 3
図1:周波数2,000Hz迄測定可能!
 
2.2 デューティー
 周波数はラジコンのPWM信号で一般的に使用する50Hzとし、オシロスコープ(DSO Nano v3)からDuty比10~90%を10%刻みで出力し、ArduinoUNOでDuty比を測定した結果、全てのDuty比で出力値+0~-0.1の精度でDuty比が測定出来る事を確認しました!
イメージ 2
図2:ArduinoUNOでDuty比10%を測定した結果

3. まとめ

 ArduinoでDuty比を測ろうと思い立ってから苦節2年!足踏みしていた状態からやっと一歩前進し、ラジコンの自動運転化に希望が見えてきました

 
イメージ 1 イメージ 3
励みになりますのでよければクリック下さい(^o^)/

↩【ローパスフィルター回路の色々!】目次に戻る