PR

【PWMの周波数】ArduinoのPWMの周波数を2つの方法で測定してみよう

arduino_pwm_freq_eyecatch
プリント基板は個人でも簡単に作れる時代!

今回は、Arduinoに標準で搭載されているPWM機能の周波数を測定してみます。

そもそも、PWMの周波数ってなんだよ?って思いましたか??

PWM制御は、Arduinoやその他マイコンボードや色々な場面で登場する電圧を制御する方法です。

電圧制御というと、ArduinoはDC5Vで駆動しますから、例えばDC3.3Vを出力したいなんてこともあると思います。

そんなとき、回路を組まずに単純に3.3Vを出力するのは難しいです。

ただ、PWMを使うと擬似的に3.3Vが出せるようになります(3.3Vでなくても出せます。)

なぜPWMを使うと擬似的に電圧が調整できるのか?についても後ほど解説しています。

 PWMについて、Arduinoの公式データの中に記載はありますが、やっぱり実際に確認してみたくなりますよね??

というわけで、ArduinoのPWMの出力を確認します。

オシロスコープで測定する方法と、割り込み処理(attachinterrupt)を使用する方法の2つをご紹介します。

使用するのは、Arduino UNO互換機とArduino pro microの2つです。

オシロスコープが無くても簡易的に測定する方法もご紹介します。

「オシロスコープなんてもってないよ…」なんて場合も対応可能です。

それでは早速やり方を紹介します。

この記事を読むことでわかること

ArduinoのPWMの機能を周波数という視点で理解できる。

自己紹介

サラリーマンしてます。

主に工場(生産現場)で使用する検査装置のアプリケーション開発してます。

ヒトの作業を自動化して簡略化するアプリケーションを日々開発中。

2022年5月に転職。現役技術系の職種一筋バリバリの技術者です。
現在は新規事業分野で装置の研究・開発をしています。電気・メカ・ソフト・検証・測定どれでもカモンという感じですが、得意なのはソフトです。

電子工作をやり始めてから電子工作+ソフトで面白いことできるじゃん!からのブログ立ち上げでした。

Youtubeチャンネルにさまざまな動画を上げています

↓↓↓こちらからYoutubeチャンネルにアクセス!! ↓↓↓

注意

本ブログはアフィリエイトを用いた広告を掲載しています。

そもそもArduinoのPWM出力はどうなっている?

Arduinoの公式リファレンスをリンクとして貼っておきます。

301 Moved Permanently

さて、これだけ読んでわかる人はいいですが、もっと簡単に説明しましょう。

PWM出力とは、Arduinoから出力されるGPIOのピンの電圧を疑似的に5V以下にできる機能です。

実際異なる出力電圧を同じピンから出すのは、物理的には難しいですよね。

可変抵抗か何か抵抗を入れれば別ですが、それをソフト的に行っているのがPWMです。

超高速で5VをONにしたり、OFFにしたりすることで、あたかも目標の電圧になったかのように錯覚させています。

実際にスケッチに書くのは、analogWrite()

というコマンドです。

analogWriteの使い方は?

 analogWriteですが、先ほど貼り付けたArduinoの公式リファレンスに詳しく記載されていますが、具体例を示しておきましょう。

  • 5V⇒2.5Vで出力する

こんな場合にスケッチに書く場合は、こんな感じになります。

analogWrite(出力するpin番号,128);

引数と呼ばれる()の中で制御のパラメータを決定します。

出力するpin番号は、arduinoのD○○というピン番号です。

128という数字は、0~255諧調のちょうど半分ということで128としています。

出力するpin番号は注意が必要。

 実は、先ほど紹介したコマンドですが、出力するpin番号は、使用するArduinoのボードの種類によってちょっと違いがあります。

これまたArduinoの公式リファレンスに掲載されていますが、例えば、Arduino UNOの場合は、

Arduino 公式リファレンスより

3,5,6,9,10,11番pinがPWM出力可能。つまり、analogWriteで指定できるpin番号ということになります。

これ意外のpin番号を指定したとしてもpwm出力はできませんので注意が必要です。

 余談ですがこう見ると、やっぱりArduino Megaの対応数は半端ないですね…

ArduinoのPWM出力をLEDで確認してみる。

 さてそれではやり方はわかったところで、実際にLEDをPWM出力で光らせてみましょう。

 使用するのはArduino UNOの互換機です。互換機とは言っていますが、純正のArduino UNOと全く同じですのでご安心ください。

 互換機じゃなくて、純正が良い!!という場合はこちらにありますので参考にしてみて下さい。

 Arduinoも、線材だったりLEDだったり小型のモーターだったりを一緒にした、電子工作キットなんかもあるので、買い足しなんかもいいかもしれないですね。

↓↓↓AmazonでArduino UNOを調べる↓↓↓

https://amzn.to/3xywZ4s

配線は簡単ですが一応載せておきます。

今回使用するのは、PWMが使用できるPin11です。

大事なことになりますのでもう一度言いますが、使用するボードによってPWM出力できるpinに制限があります。

Arduino UNO以外で行う場合はご自分のボードでどのpinが対応しているか?

確認してから適宜配線を変更してください。

arduino_pwm_led
ArduinoとLEDをつないでPWM制御。

続きまして、スケッチですね。

今回はPWMの効果がわかりやすいように、3種類明るさを変えてみましょう。

スケッチはこちらです。

void setup() {
  pinMode(11,OUTPUT);
}

void loop() {
  analogWrite(11,255);// 全開点灯
  delay(100);
  analogWrite(11,128);// 半分点灯
  delay(100);
  analogWrite(11,64);// 1/4点灯
  delay(100);
}

せっかくならもうちょっと明るさをきれいに諧調させてみましょう。

このスケッチを書き込むと、LEDが段階的に明るくなって暗くなるを繰り返します。

void setup() {
  pinMode(11,OUTPUT);
}

void loop() {
  for (int i=0;i<512;i++)
  {
    if(i<256)
    {
      analogWrite(11,i);// 光量増加
    }
    else
    {
      analogWrite(11,511-i);// 光量減少
    }
    delay(10);
  }
 }

実際にやってみた動画を撮りました。

前半が3段階、後半が諧調点灯です。

arduinoでPWM制御。詳しい内容はhobbyhappyblogで検索!!!
ArduinoのPWM制御

PWM出力の周波数をボード単体で測定する。

さて、PWM制御ができたところで、肝心の周波数について測定していきましょう。

周波数の測定には割り込み処理を使用しますが、何十行も書かないの安心してください。

まずは配線して測定できるようにする。

実験するために配線が必要です。

とはいっても、ジャンパーワイヤー1本あればできます。

arduino_pwm_freq_meas
pwmの周波数を調べるための配線方法。

11番と2番を直接つないでください。

ボード単体で測定する場合のやりかた。

まずはスケッチを記載しますね。

そのスケッチをもとにして説明をしていきます。

volatile int counter=0;
void setup() {
  pinMode(11,OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2),pwmCatch,RISING);
  Serial.begin(9600);  
}

void pwmCatch(){
  counter=counter+1;
}
void loop() { 
      analogWrite(11,1);// PWM出力
      delay(1000);
      Serial.println(counter);
      counter=0;        
 }

まずは、冒頭のこちらですが、

volatile int counter=0;

これは、割り込み処理で値を変える際には、頭にvolatileをつけないと

値を変更できないので、この宣言がつきます。

この変数は、PWM出力された回数をカウントする変数です。

続いて、setup関数です。

void setup() {
  pinMode(11,OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2),pwmCatch,RISING);
  Serial.begin(9600);  
}

attachInterruptが、割り込みの関数です。

引数は、こんな意味があります。

割り込み処理のトリガーの種類
  • digitalPinToInterrupt(pin番号)⇒割り込みのトリガーになるpin番号
  • pwmCatch⇒割り込みしたら実行される関数の名前
  • RISING⇒信号の立ち上がりを検知してトリガーになる。
    他にも立下りを検知するFALLINGなどがある。

今回は2番pinを割り込みのトリガーとしてます。ちなみに…これもまた重要なのですが、Arduinoのボードの種類によって、割り込みのトリガーにできるpinが決まっています。

ちょっと特殊なものとして、Arduino nano everyなんかは、すべてのpinが割り込みのトリガーとして機能します。が、それ以外のボードは必ず割り込みのトリガーにできるpinを選択して配線してください。

最後に一気に割り込みの関数とloop関数についてみていきましょう。

void pwmCatch(){
  counter=counter+1;
}
void loop() { 
      analogWrite(11,1);// PWM出力
      delay(1000);
      Serial.println(counter);
      counter=0;        
 }

割り込みで実行されるpwmCatchという関数には、PWMの1パルスに対して割り込みがかかります。

ですから、ここでは1000msつまり1秒の間に、PWMの信号が何回入ってくるかをカウントアップできるわけです。

1秒間で、何回発生したか?はまさしく周波数のHz(ヘルツ)の単位ですね。

割り込み関数の中にカウントアップしか入れていない理由ですが、重い処理を入れるとその分ラグが発生しますから、処理は極力軽くしたいという事情もあります。

 周波数を測定する流れの概要をおさらいしましょう。

 loop関数内でanalogWriteをしてPWM信号を出力し、1000ms待っている間に出てくる信号を割り込みでその都度キャッチしてカウントアップする。カウントアップした回数を最後にシリアルの窓に表示する。このような流れです。

ボード単体で実際にArduino UNO互換機を測定してみる。

実際にこの方法で周波数を測定した結果ですが、Arduino UNO互換機は、490回でした。

つまり、1秒で490回信号が出ているので、490Hzという計算ですね。

公式リファレンスを見てみると、490Hzと記載されていて、完全に一致しました。こんな簡易的な方法でもばっちり測定できました。

ボード単体でArduino pro microを測定してみる。

Arduino UNOと同じ流れで、Arduino pro microも測定していきましょう。

Arduino pro microは、Arduino UNOとは違い、ピンの制限はこちらになっています。

PWM出力可能なpin3,5,6,9,11,13
割り込みのトリガーに使用できるpin0,1,3,7

Arduino UNOの時は、PWM:11 割り込みのトリガー:2

としていましたから、割り込みのトリガーのみ3に変えましょう。

と、言いたいところなのですが、

Arduino pro microは、配線がGPIO11番が使用できないので、PWMのpinは5番にしました。

ですから、PWM:5 割り込みのトリガー:3としました。

結果は490。Arduinoの公式リファレンスと同じ結果でした。

PWM出力の周波数をオシロスコープで測定する。

 ここからはオシロスコープでの測定です。

電子工作するときに必要になるのは、いわゆるテスターなんて呼ばれる電圧計だけだと思っていませんか?

↓テスター

実は時系列で信号が取れるオシロスコープって、

波形でわかるので、とっても便利なんです。

わたしが今使っているものは安物ですが、

これでもはっきり言って十分ぐらいの性能です。

↓わたしが現在使用しているオシロスコープ※Amazonで確認できます。

前はこれを使用していましたが、あまりオススメできません…

 1CHしかないし…バグで動かなくなったりでいろいろあったので先ほど紹介したものにしました。

オシロスコープで測定する場合は?

オシロスコープで測定する場合は、割り込み処理を入れる必要はありません。

オシロスコープで直接電圧の立ち上がりを観察すればいいだけですからね。

ですから、スケッチは単純にこのようになります。

volatile int counter=0;
void setup() {
  pinMode(11,OUTPUT);
 }

void loop() { 
      analogWrite(11,100);// PWM出力
      delay(1000);
      }

スッキリしていていいですね。

配線に関しては、11番pin(Arduino UNOの場合)と、GNDをプローブでくわえてあげればOKです。

GNDとの電位差を波形にするイメージです。

オシロスコープでArduino UNO互換機を測定してみる。

arduino_uno_pwm_100
ArduinoUNO互換機のPWM出力をオシロスコープで測定。

これがオシロスコープで測定した画面です。

見方ですが、下のほうに、F=490.4Hzと書いてあります。

これが、波が来る頻度、つまり周波数というわけです。

先ほど割り込みで測定した結果と一致しましたね。

ちなみに…引数の100というのは、デューティー比と呼ばれるパラメータで、

この値を0~255の中から選ぶことで、疑似的に5Vを下げた状態にできる。

と説明したと思いますが、その原理はオシロスコープで測定することでわかります。

この画像はデューティー比を100から50に変更した結果です。

引数(duty比)を100から50に半減。

100の時とどこが違うでしょうか?

答えは、5Vになっている時間です。

山の太さが違うんですね。

何度も説明していますが、Arduinoは0Vか5Vしか出力できません。

その5Vを出す時間を調整して疑似的に3Vだったり1Vだったりを疑似的に出力しているわけです。

ですから、5Vに近い出力をPWMで出そうとすると、当然太い山になります。

逆に0Vに近い出力をPWMで出そうとすると、細い山になる(5Vを出す時間が少ない)というわけです。

ここまでのおさらいですが、arduinoでは約490Hzの周波数で、5Vを出す時間を調整することで0〜5Vの範囲の任意の電圧を出しています。

なんとなくイメージできましたか??

オシロスコープでArduino pro microを測定してみる。

最後にArduino pro microのPWM出力信号の波形を見てみましょう。

これはなくてもいいかもしれませんが、一応載せておきます。

arduino_pro_micro_pwm
Arduino pro microのPWM出力信号の波形。

490.2Hzというわけで、ほぼ490Hzですね。

実験と仕様がピッタリ一致するのは嬉しいですね。

今回のまとめ

今回はArduinoのPWM出力の周波数について実験してみました。

公式のリファレンスに載っているからそれでいい。

というのはあるのですが、どうせなら実際その周波数になっているか確認したいですよね?

もちろん公式のリファレンスの周波数通りになっていましたが、確認出来て満足です。

オシロスコープを最近入手して波形を見るようになりましたが、波形が目で見えるってのはやっぱり便利ですね。

もしまだお持ちでないなら、1つ持っておくといいかもしれません。

最後にもう一度私が使用しているオシロスコープを紹介しておきますね。

コメント

タイトルとURLをコピーしました