6 PWM(アナログ出力)
今回の講義の目的は、マイコンを使って電圧を制御することです。電圧を上げたり下げたりできると、LEDの光る強さを変えたり、モータの回転速度を変えたりすることができます。 目次 6.1 PWM 6.2 モータの基礎 6.3 外部電源を使う時の注意 6.4 DCモータを回す 6.5 ギア 6.6 サーボモータを回す 6.7 実習 6.1 PWM マイコンの世界はデジタルなので、プログラムで電圧を制御するのは、ちょっと難しいことです。そこで、PWMという手法が登場します。 これはデジタル出力を使って擬似的にアナログ出力を実現する方法だと思ってください。 仕組み マイコンのデジタルピンからの出力は、HIGH(例えば3V)かLOW(例えば0V)のどちらかだけです。しかし、0Vから3Vまでの間で電圧を自由に変えたいという場合があります。例えば、LEDの明るさを調整したい場合などです。こういう時には、PWM(Pulse Width Modulation)という方法を用います。 PWMの仕組みを一言で説明すると、HIGHとLOWを素早く切り替えることによって、HIGHとLOWの間の電圧を擬似的に作り出す方法です。以下の図をみてください。 このようにHIGHとLOWを規則的に繰り返す信号を、パルス波と言います。上記の図で示しているパルス波は、ある一定時間で同じパターンを繰り返していますね。このような繰り返しの間隔を周期と呼び、1秒間に何周期あるかを周波数と呼びます。周期の始まりは、LOWからHIGHに変わる瞬間で、周期の終わりは、次にLOWからHIGHに変わる瞬間です。周波数1kHzと言ったら、1秒間に1000回の周期が起こるような波形を意味します。 図で示したパルス波は、1周期におけるHIGH(3V)とLOW(0V)の間隔が、ちょうど1/2ずつになっています。周波数が十分に高い場合,このデジタルピンにかかる電圧は、3V / 2 = 1.5Vとなります。これがPWMです。実際に電圧を変えるのではなくて、擬似的に電圧を変えているのです。 PWMを使った場合にデジタルピンにかかる電圧は,デューティ比(duty ratio) によって決まります。デューティ比とは,1周期の間にHIGHになっている割合のことです。HIGHが3Vの場合、デューティ比50%ならば1.5V,10%ならば0.3Vとなります。 PWMを使用する場合、どのくらいの周波数が必要かは難しい問題なので、あまり深入りしないことにしますが,1Hzではだめなことは明らかです。1Hzということは、HIGHとLOWが同じ時間であるとすると1周期内で0.5秒ずつです。LEDで実験すると単に点滅するだけです。 PWMの周波数は、デジタルピンの用途によって変わるとされています。例えばLEDを使う際に必要な周波数,モータを使う際に必要な周波数という具合です。モータの場合には10kHzから20kH位が適当でしょう。LEDだと、100Hzくらいでも大丈夫だと思います。 PWMを使って電圧を制御するには、パルス波を作り出す必要があります。パルス波は、タイマを使って作ります。非常に微小な時間をタイマによって作りだし,デジタル出力をHIGHにしたりLOWにしたりします。 例えば、1kHzの周波数でPWM 制御をしたいとしましょう。1秒間に1,000周期ですから,1周期は1ms(ミリ秒)です。1周期を10段階に分けると、1段階100µs(マイクロ秒)になります。この100µsをタイマを使って作り1単位とすれば、10%刻みでデューティ比が設定できるようになります。 試してみよう GPIO Zeroには、PWMのためのライブラリが用意されています。このライブラリを使えば、プログラムする際にタイマを設定するなどの面倒なことは必要なくなります。 PWMLEDとPWMOutputDeviceという2つのクラスがありますが、ここではPWMLEDの方を使います。この2つのクラスの詳細は、GPIO Zeroのリファランスの”API – Output Devices”を見てください。 https://gpiozero.readthedocs.io/en/stable/api_output.html LEDを光らせる回路はソース電流を使って作ります。GPIOのピンは特殊用途のピンでなければどこでも良いです。ここではGPIO 17を使います。 このプログラムは、異なるデューティ比でLEDを交互に光らせるものです。デューティ比80%の時には明るく光り、デューティ比10%の時には暗く光るはずです。 PWMLEDはデフォルトでPWMの周波数を100Hzにしています。これを変えるには以下のようにします。 先ほどの例は、ソース電流を使ってLEDを光らせましたが、シンク電流でも同じことをすることができます。以下のようにPWMLEDの引数にactive_high=Falseを指定するだけです。 もう少し複雑な例を上げておきます。これは、デューティ比を徐々に増やしながらLEDを光らせています。LEDの明るさが滑らかに変わることが観測されるはずです。 デューティ比を変えてLEDを光らせる時には、デューティ比を切り替える間に少し間隔をおく必要があるということです。5msくらいあれば大丈夫だと思います。上記の例ではsleep(0.1)で100msの間隔を空けています。これを入れないと、LEDは高速で点滅しているような感じになってしまいます。 […]