Raspberry Pi Zero WでPython 〜ブラシ付きDCモーターを回す〜

模型用として使われるブラシ付きDCモーター(以下DCモーター)を回します。使用したDCモーターはFA-130RA-2270Lというもので、電気的特性として電圧範囲は1.5〜3.0Vで、無負荷時電流は200mAです。また、モーターに大きな負荷がかかり回転が停止したときに流れる静止電流は2.2Aです。

Raspberry Pi HardwareによるとGPIOのVIH(HIGHレベルの出力電流)のデフォルト値は8mAで、最大でも16mA(要ソフトウェアでの設定)なのでこのDCモーターを直接駆動することはできません。何らかのドライバー回路が必要になります。

パワーMOSFETのドライバ回路

NチャネルパワーMOSFET 2SK4017を使った駆動回路です。DCモーターの駆動電源は単三電池2個を使って3Vとしています。

モーターと並列に接続されるダイオード(D1)はフリーホイールダイオードと呼ばれ、モーターの逆起電力によって2SK4017のドレインに加わる電圧を電源電圧(3.3V)+ VF(ダイオードの順方向電圧で1N4002の場合1.1V)に制限しデバイスの破壊を防ぐ役割を果たします。

フリーホイールダイオードの役割

このフリーホイールダイオードの効果をオシロスコープの波形を観測してみます。

ゲートにかかるPWM波形と2SK4017のオン・オフ波形です。ゲートがHIGHでFETがオンになり、ゲートがLOWでオフになります。注目するのはFETがオンからオフになるタイミングです。ダイオード有りではドレイン・ソース間のピーク電圧は3.76Vとなっていますが、ダイオード無しでは65.2Vにもなっています。

2SK4017のデーターシートを見ると、ドレイン・ソース間電圧の絶対最大定格は60Vとなっており、フライホイールダイオードがない場合にはそれを超えています。

回路の接続

回路をブレッドボード上に組んでDCモーターを接続しす。モーターには軽いプロペラをつけて回転しているのがわかりやすいようにしています。

モーターのON/OFF制御で回転させる

以下のソースは単純にGPIOをON/OFFさせることでDCモーターを回しています。2秒間モーターを回転させ、2秒間モーターを停止させるプログラムです。ファイル名はtest6.pyとしています。

#!/usr/bin/python
import RPi.GPIO as GPIO # RPi.GPIOモジュールをGPIOとして使用
import time             # timeモジュールの読み込み

gpio_dcm = 18   # モーター制御ピンのGPIO番号を定義

GPIO.setmode(GPIO.BCM)          # GPIO番号で指定する設定
GPIO.setup(gpio_dcm, GPIO.OUT)  # モーター制御ピンを出力に設定

try:
  while True:
    GPIO.output(gpio_dcm, 1)
    time.sleep(2)
    GPIO.output(gpio_dcm, 0)
    time.sleep(2)
except KeyboardInterrupt:
  GPIO.cleanup()  # GPIOを解放

PWMでモーターの回転速度を変化させる

上のソースのように単純にGPIOをON/OFFさせるだけではソフトウェアのみでモーターの回転速度を変えることはできません。ふわふわLEDと同様にPWM制御を使うことでDCモーターの回転速度を変化させる事ができます。以下のソースはPWMのデューティ比を20%、40%、60%、80%そして100%と変化させ各デューティ比で3秒間回転させるプログラムです。ファイル名はtest7.pyです。

#!/usr/bin/python
import RPi.GPIO as GPIO # RPi.GPIOモジュールをGPIOとして使用
import time             # timeモジュールの読み込み

gpio_dcm = 18   # モーター制御ピンのGPIO番号を定義

GPIO.setmode(GPIO.BCM)          # GPIO番号で指定する設定
GPIO.setup(gpio_dcm, GPIO.OUT)  # モーター制御ピンを出力に設定

pw = GPIO.PWM(gpio_dcm, 100)    # モーター制御ピンを1kHz周期のPWMで制御する設定
pw.start(0)                     # PWMのデューティー比を0%で開始

try:
  while True:
    for duty in range(20, 101, 20): # dutyを20%から100%まで20%づつ増加
      pw.ChangeDutyCycle(duty)      # デューティー比を変更
      time.sleep(3)
except KeyboardInterrupt:
  pw.stop()       # PWM制御の停止
  GPIO.cleanup()  # GPIOを解放

ドライバICで正逆回転

図のように4つのスイッチで回路を構成し、スイッチのON/OFFの組み合わせでDCモーターを正逆回転させる事ができます。このような回路をHブリッジ回路と言います。

この4つのスイッチをトランジスタやMOSFETで構成することも可能ですが回路が複雑になりまた、スイッチに並列にフリーホイールダイオードを接続するなど、部品点数も多くなるのでここでは専用のICを使います。使用するドライバーICはL293Dです。このICは4つのハーフH回路から構成されていて2つの回路を使ってHブリッジ回路を構成します。

回路図は以下になります。ドライバー入力1AはGPIO23(物理ピン番号16)、ドライバー入力2AはGPIO22(物理ピン番号15)、ドラバーイネーブル信号EN1,2はGPIO18(物理ピン番号12)に接続します。

ドライバーイネーブル信号をPWMで与えることでDCモーターの回転速度を変化させることができます。

モーター駆動用の電源VCC2は最低電圧がVCC1となっているので単三乾電池4個を使って6Vを供給します。Pi Zeroの5Vからも考えられますが、モーターを駆動する時にに大きな電流が流れPi Zeroに影響がないように別電源にしています。

ここで考慮しなければいけない事があります。それは、FA-130RAの電圧範囲は3Vですのでモーターを回転させた時のモーターの両端に加わる電圧についてです。データーシートを見ると、L293DのVOH(HIGHレベル出力電圧)はTypical値でVCC-1.4VでVOL(LOWレベル出力電圧)はTypical値で1.2Vとなっていて、モーターの両端にかかる電圧はVCC-1.4-1.2=3.4Vとなり3Vを超えてしまいます。今回は、Pythonnプログラミングの確認ということで目を瞑りましょう。とは言っても実際に確認してみます。

また、FA-130RA-2270Lの静止電流が2.2Aに対してL293Dのピーク出力電流は1.2Aなので大きな負荷がかかって回転が停止する事がないように注意が必要です。

# フリーホイールダイオードを内蔵していないL293は出力電流が2Aなので制約が緩和されますが、別途ダイオードを外付けする必要があります。

このような制約があるということを理解した上でL293Dを使ってモーターの正逆回転の回路を実装します。以下のソースコードはデューティ比を50%として正転を3秒間、逆転を3秒間そして停止を1秒間というのを繰り返しています。ファイル名はtest8.pyです。

#!/usr/bin/python
import RPi.GPIO as GPIO # RPi.GPIOモジュールをGPIOとして使用
import time             # timeモジュールの読み込み

gpio_1A = 22    # 1AピンのGPIO番号を定義
gpio_2A = 23    # 2AピンのGPIO番号を定義
gpio_en = 18    # ENピンのGPIO番号を定義

GPIO.setmode(GPIO.BCM)        # GPIO番号で指定する設定
GPIO.setup(gpio_1A, GPIO.OUT) # 1Aピンを出力に設定
GPIO.setup(gpio_2A, GPIO.OUT) # 2Aピンを出力bに設定
GPIO.setup(gpio_en, GPIO.OUT) # ENピンを出力に設定

pw = GPIO.PWM(gpio_en, 100)
                    # ENピンを10m秒周期(100Hz)のPWMで制御する設定
pw.start(0)         # PWMのデューティ比を0%で開始

try:
  while True:
    # モーターを正転
    pw.ChangeDutyCycle(50)  # デューティ比を変更
    GPIO.output(gpio_1A, 1) # 1AピンをHIGH
    GPIO.output(gpio_2A, 0) # 2AピンをLOW
    time.sleep(3)           # 3秒間保持
    # モーターを逆転
    GPIO.output(gpio_1A, 0) # 1AピンをLOW
    GPIO.output(gpio_2A, 1) # 2AピンをHIGH
    time.sleep(3)
    # モーターの回転を停止
    GPIO.output(gpio_1A, 0) # 1AピンをLOW
    GPIO.output(gpio_2A, 0) # 2AピンをLOW
    time.sleep(1)           # 1秒間保持
except KeyboardInterrupt:
  pw.stop()
  GPIO.cleanup()  # GPIOを解放

さて、DCモーターの回転時(デューティ100%)の電圧を観測します。

CH1はL293Dの3ピンでDCモーターの(+)、CH2はL293Dの6ピンでDCモーターの(-)そしてMはオシロスコープの演算機能でCH1からCH2を減算した波形です。画面の下に出ている値は、オシロスコープの「Measure」機能を使って電圧の平均値を計測しています。CH1からCH2を減算した値、これはDCモーターの両端の電圧ですが、平均値で1.54Vになっているので定常的な電圧は問題のない範囲です。瞬間的には6V程度の電圧がかかっていますがこれでモーターが以上に発熱するようなことはないでしょう。

スポンサーリンク
スポンサーリンク
スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーリンク