ラズパイPico DCモーターの使い方 簡単速度制御(PWM)1.5V、3Vモーター対応

Raspberry Pi Pico DCモーター制御アイキャッチ

Raspberry Pi Pico(PicoWでも同じ)でDCモーターを制御する方法を詳しく紹介します。

モーターは3Vのものを使用し、制御には低電圧(2〜10V)で駆動する「MX1502」を搭載したドライバ基板を使用して、基本的な正逆転動作から、PWM制御で速度制御(ボリュームで速度可変)、簡易的な過負荷保護まで行います。

回路図とサンプルプログラム(コピペ)も準備してますので、実際に動かしながらDCモーターの使い方について確認してみましょう。

プログラム言語は「Python」を使用し「MicroPython」と「CircuitPython」両方のサンプルプログラムを準備しています。

「ラズパイPico」の開発環境の準備や端子配列等の基本情報、基本的なプログラムについては、以下のリンクで詳しく紹介しています。

ラズパイPico/PicoWの使い方を3つの開発環境Python、ArduinoIDE、PlatformIOで紹介
Raspberry Pi Pico/Pico Wの使い方を端子配列からPython(MicroPython)とC言語の開発環境、Lチカ方法まで紹介。PythonはTonny、C言語はArduinoIDEとPlatformIOの3種類で詳しく紹介します。
ラズパイPico基本プログラムPython編(Lチカ,入出力,アナログ,PWM)
Raspberry Pi Picoの基本的なLチカや入出力,アナログ入力(ADC),PWM出力を行うPythonのコピペ用サンプルプログラムをまとめました。

「C言語」を使用した「Arduinoコマンド」でのDCモーターの速度制御方法についても、以下のリンクで詳しく紹介しています。

DCモータの速度制御方法(Arduinoコマンド)3V以下モータ対応
PWMを使用してDCモータの速度制御をする方法をArduinoコマンドを使用して詳しく紹介します。ドライバ基板MX1508で3V以下のモータに最適。ATOMS3使用
スポンサーリンク

1.動作紹介

今回動作確認には「乾電池駆動」と「三端子レギュレータ駆動」の2種類で動作確認しています。
それぞれについて実際に配線した状態の写真を使って以下から紹介します。
(配線についての詳細は「2.配線図」を参照してください。)

モーターは模型や工作用で一般的な3V用DCモーター(130モーター)であればどんなものでも動作可能と思います。今回はギヤ付きのものを使用しています。

今回使用したモーター制御用ドライバ(MX1508搭載)は2つのモーターが制御できるため、モーターは2つ使用しています。

モーターの速度はボリュームで調整してPWM制御します。
合計4つのスイッチがあり、モーターごとに正転スイッチ、逆転スイッチとして使用します。
2つ同時押しで回生(ショート)ブレーキで停止時間を短くすることができます。

・乾電池駆動

乾電池駆動の配線はブレッドボードを使用して下写真のように行ないました。
乾電池の「マイナス(ー)」とラズパイPicoの「GND」は接続して共通にしておきます。

Raspberry Pi Pico DCモーター制御、動作確認
Raspberry Pi Pico DCモーター制御、動作確認
Raspberry Pi Pico DCモーター制御、動作確認
モーター用の電源について、1.5V用モータでもドライバ基板の電源電圧が2〜10Vのため、3Vを準備してください。
1.5Vのモーターを使用する場合はPWM制御の「Duty比」を調整することで駆動できます。

・三端子レギュレータ駆動

三端子レギュレータ駆動の配線はブレッドボードを使用して下写真のように行ないました。
モバイルバッテリー等の5Vから三端子レギュレータで3.3Vに変換してドライバ基板の電源として使用します。

Raspberry Pi Pico DCモーター制御、動作確認

モバイルバッテリーの5VをUSB-DIP変換基板を使用して3.3V用の三端子レギュレータに入力すると3.3Vの電圧を得ることができるため、これをドライバ基板の入力電源に使用しています。

Raspberry Pi Pico DCモーター制御、動作確認
Raspberry Pi Pico DCモーター制御、動作確認

三端子レギュレータはコンデンサ等の周辺部品が実装済のものを使用すると便利です。
LED(上写真では赤点灯)も実装されているため電源ON/OFFの確認にも使用できます。

上写真ではラズパイPicoの電源はパソコンから取るため、モーター用電源とは別にしています。
共用でも使えますが、モーターの電流が大きいとラズパイPicoが壊れたり、パソコンに悪さをする可能性もあるため、共用にする場合は自己責任で行なってください。

・簡易過負荷保護について

今回簡易的な過負荷保護機能を実装しています。
目的は、モーターの保護もありますが、どちらかというとモーター用電源を得るための三端子レギュレータICの保護用です。

モーターが過負荷になって電流が増えると、三端子レギュレータ(3.3V)の出力電圧が下がるため、この電圧をラズパイPicoのアナログ入力端子で監視して、電圧が低下した場合は過負荷と判断してモーターを停止させるようにしています。
このため、乾電池駆動の場合は正常時でも徐々に電圧が低下していくので誤動作します。
この場合はプログラムの過負荷保護レベル(OVERLOAD_VOLT)を「0.0(V)」に設定して無効にできます。

乾電池駆動の場合は、使用するモータにもよりますが、駆動部の過負荷による破損と、モーターの発熱(触れなければNG)だけ注意しておけば無効にしても特に問題ないと思います。


モーター駆動時に、開発環境のシリアルモニタにモーターの速度指定電圧とドライバ基板への入力電圧を出力するようにしています。

下画像は開発環境「Tonny」でモータ駆動時に表示されるシリアルモニタ出力の様子です。

Raspberry Pi Pico DCモーター制御、シリアルモニタ

「speed_volt」はボリュームの電圧をアナログ入力で取得して換算した電圧で、モーターの速度指定に使用します。

「protect_volt」はドライバ基板への入力電圧をアナログ入力で取得して換算した電圧で、この電圧が低下した時は過負荷としてモーターを停止させます。

今回使用したDCモーター(ギヤ付き)の「Geekservo」を1つロック(出力軸を拘束)させた時の状態ですが「protect_volt」が3.1V程度まで下がってます。

この時にモーターを停止させて保護したい場合は、サンプルプログラムの過負荷保護レベル(OVERLOAD_VOLT)を3.2(V)に設定するとモーターが停止して保護できます。

過負荷保護レベルはあまり高い数値に設定すると頻繁に停止して、ストレスを感じます。
特に乾電池駆動の場合は、モーターが過負荷でなくても電池が消耗すると電圧は低下して誤動作するため、乾電池駆動の場合は過負荷保護レベル(OVERLOAD_VOLT)を「0.0(V)」にして過負荷保護機能を無効にしてください。

※この機能はモーターや供給電源の確実な保護を保証するものではありませんので、おまけ程度に動作確認をお願いします。
スポンサーリンク

2.配線図

今回使用した配線図は下図のようになります。
スイッチはブレッドボードの都合でそれぞれGND端子が使えるような使い方をしています。

モーター用の「3V電源」は単独で準備しています。
「簡易過負荷検知」はドライバ基板の入力電圧をラズパイPicoのアナログ入力で監視して、モーター過負荷時に低下する電源電圧を検知してモーターを停止させるようにしています。

Raspberry Pi Pico DCモーター制御、配線図
乾電池を使用する場合、電圧は徐々に低下していくため「簡易過負荷検知」はうまく機能しません。
「アナログ入力端子(GP27_A1)」をモーター用電源の3Vではなく、ラズパイPicoの「3V3」端子に接続するか、プログラムの過負荷保護レベル(OVERLOAD_VOLT)を「0.0(V)」に設定して無効にしてください
※三端子レギュレータを使用する場合は、レギュレータIC保護のため、回路図の破線部を接続しておくと電圧降下を利用した簡易過負荷検知として使用できます。
スポンサーリンク

3.使用部品について

今回使用した主要部品について紹介します。

・DCモータードライバ MX1508

DCモーターを制御するためのドライバ基板(MX1508搭載)は下写真のようになります。
電源電圧範囲はDC2〜10V(制御電圧は1.8V〜7.0V)で、この基板1枚で2つのモーターの制御ができます。

DCモータードライバMX1508
端子が実装されていないので、これを半田付けするのがちょっと大変です。
また、端子の配置やピッチが変則的でブレッドボードと穴位置が合わない箇所が多いため扱いづらいです。機能的にはとても優秀なので残念です・・・。

今回は下写真のように端子を半田付けしています。
基板裏には高さ合わせのためにゴム足(100均)を取り付けています。

DCモータードライバMX1508
DCモータードライバMX1508

ドライバ基板の電源(+、ー)はブレッドボードに差し込み、制御用端子(INT1〜4)はジャンパー線でラズパイPicoと接続、モーターは直接「MOTORーA、B」に接続します。

DCモータードライバMX1508

DCモーターを制御するドライバ基板としては「L298N」が有名ですが、電源電圧は5V〜35Vのため、模型や工作用によく使用されるDC1.5Vや3Vモーターの駆動には「Duty比」の調整が必要で扱いにくいですし寸法も大きいです。

下写真は「L298N(左)」と「MX1508(右)」の寸法を比較したものです。

L298NとMX1508の外観比較

今回使用したドライバ基板(MX1508搭載)は電源電圧2V〜10Vで動作し、寸法も小さいため組み込み用途にも最適です。

・DCモーター

DCモーターは3Vモーターが推奨ですが、1.5Vでも制御可能です。
今回使用したものは以下の「Geekservoモータ」です。

「servo」と書かれてますが「サーボモーター」ではなく「DC(直流)モーター」です。
配線は2本でコネクタもついています。ギヤも付いているので大きなトルクが出せます。

サーボモータータイプもありますが、この場合は配線は3本なのでご注意ください。
Raspberry Pi Pico DCモーター制御 Geekservo
Raspberry Pi Pico DCモーター制御 Geekservo

「LEGOブロック」互換でブロックと組み合わせて使用できます。
出力軸もクロスシャフトになっているため「LEGOテクニックシリーズ」のタイヤや部品を取り付けることができます。

Raspberry Pi Pico DCモーター制御 Geekservo
Raspberry Pi Pico DCモーター制御 Geekservo

仕様について、販売元のサイトでは以下のようになってますが、見るサイトによって内容が違うようなので、参考までにご確認ください。

  • 最高回転数:70rpm
  • 動作電圧:3.3V~6V
  • 公称電圧:4.8V
  • 公称電流:100mA
  • ロータロック電流:550mA
  • 最大トルク:500g.cm
  • スリップ電流:450mA
  • 重量:20g

モーターは配線も端子も付いているものがそのまま使えて便利と思います。

DCモーターの動作原理や構造については、以下のリンクで動画も交えて詳しく紹介しています。

直流(DC)モーターとは?動作原理や構造を図多めで詳しく紹介
知ってるようで知らなかった直流モーターの動作原理や構造について、実際に作って動かしたりしながら順を追って詳しく、わかりやすく、できるだけ簡単に紹介していきます。

・三端子レギュレータ(DC3.3V出力)

ドライバ基板への入力電圧を得るためには、以下写真の三端子レギュレータ(10個セット)を使用しました。
3.3V出力のものですが3Vモーターでも特に問題なく使用できます。調整が必要な場合はPWM制御のDuty比で行います。

入力電圧範囲はDC4.75V〜12Vで出力電圧は3.3V固定、出力電流は0.8Aです。
コンデンサ等の周辺部品と一緒に基板に実装されていて、LED(赤)も実装されています。
端子付きで、ブレッドボードに差し込んで使用できます。
三端子レギュレータ
三端子レギュレータ

基板には溝が付いているので、手で割ると下写真のように1つづつ使用できます。

三端子レギュレータ
三端子レギュレータ

端子配列は「VIN」が電圧入力「OUT」が電圧出力「GND」は0Vです。

・その他

今回使用した、その他部品については以下のようになります。

「スイッチ」は基本的には何でも良いです。「ボリューム(10kΩ〜100kΩ程度)」はブレッドボードに挿せて指で回せるものが良いので、以下サンハヤト製の「スイッチ」と「ボリューム」のセットがおすすめです。


ブレッドボードは今回部品点数が多いので、一般的な1列の穴数が5個だと収めるのが大変なので、1列6穴のサンハヤト製がおすすめです。

「ラズパイPico」本体は基本的に端子は半田付けされていません。
ブレッドボードで使用する場合は、別途ピンヘッダーを購入して半田付けするか、以下のような端子が実装済のものを使用しましょう。

4.MicroPythoのサンプルプログラム(コピペ)

「MicroPython」を使用したサンプルプログラムはそれぞれ以下になります。
コピペで貼り付けて書き込んで実行してください。
※下コード(黒枠)内の右上角にある小さなアイコンのクリックでコピーできます。

パソコンに接続せずに「ラズパイPico」単体で動作させる場合は、ファイル名を「main.py」として本体に保存してください。
from machine import Pin, ADC, PWM  # 入出力とアナログ入出力、PWM制御用モジュールを準備
import time                        # タイマーモジュールを準備
        
OVERLOAD_VOLT =  3.0  # 過負荷保護レベル(V) ※0.0で無効(乾電池駆動は無効推奨)
                      #(モータ用電源電圧の電圧降下時の値を設定、電圧降下しない電源では使用不可)
OVERLOAD_COUNT = 5    # 過負荷検知確認回数(この回数過負荷が続くとモータ停止)

# 入力ピン設定(スイッチ1〜4の入力設定)
sw1 = Pin(0, Pin.IN, Pin.PULL_UP)  # スイッチのピン番号を指定してswとして入力設定(プルアップ)
sw2 = Pin(4, Pin.IN, Pin.PULL_UP)
sw3 = Pin(11, Pin.IN, Pin.PULL_UP)
sw4 = Pin(15, Pin.IN, Pin.PULL_UP)

# 出力ピン設定
led = Pin("LED", Pin.OUT)  # 本体LEDピンをledとして出力に設定

# アナログ入力ピン設定
adc_protect = ADC(Pin(27)) # 過負荷保護レベル(モータ電源電圧)アナログ入力番号を設定
adc_speed = ADC(Pin(28))   # モータ速度指示電圧用アナログ入力番号を設定

# PWMピン設定
pwm1 = PWM(Pin(18 ,Pin.OUT))  # PWM出力ピン番号を指定してpwmとしてPWM出力設定
pwm1.freq(500)                # PWM周波数を設定(隣り合った端子番号奇数と偶数は同じ周波数にする)
pwm2 = PWM(Pin(19 ,Pin.OUT))
pwm2.freq(500)
pwm3 = PWM(Pin(20 ,Pin.OUT))
pwm3.freq(500)
pwm4 = PWM(Pin(21 ,Pin.OUT))
pwm4.freq(500)

# アナログ入力(ADC)確認関数 *******************************************
def adcCheck():
    adc_speed_val = adc_speed.read_u16()                # ボリュームのアナログ入力(ADC)値を取得
    adc_speed_volt = (adc_speed_val * 3.3) / 65536      # 換算してボリュームの電圧を取得
    
    adc_protect_val = adc_protect.read_u16()            # モータ電源電圧(3.3V)のアナログ入力(ADC)値を取得
    adc_protect_volt = (adc_protect_val * 3.3) / 65536  # 換算してモータ電源電圧を取得
    print("speed_volt = {:5.2f}V /protect_volt = {:5.2f}V".format(adc_speed_volt, adc_protect_volt))  # 各電圧表示

    return adc_protect_volt  # モータ電源電圧を返す

# メイン処理 ---------------------------------------------------------
led.value(True)    # LEDを点灯
protect_count = 0  #過負荷保護カウント
overload = False   #過負荷フラグ

while True:  # ずっと繰り返し
    adc_speed_val = adc_speed.read_u16()  # ボリュームのアナログ入力(ADC)値を取得
    # スイッチ操作、モータ駆動
    if sw1.value() or overload:       # スイッチが押されてない、または過負荷なら
        pwm1.duty_u16(0)              # PWM1出力オフ(Duty比を0に設定)
    else:                             # スイッチが押されていれば
        pwm1.duty_u16(adc_speed_val)  # アナログ入力(ADC)値をPWMのDuty比に設定

    if sw2.value() or overload:       # スイッチが押されてない、または過負荷なら
        pwm2.duty_u16(0)              # PWM1出力オフ(Duty比を0に設定)
    else:                             # スイッチが押されていれば
        pwm2.duty_u16(adc_speed_val)  # アナログ入力(ADC)値をPWMのDuty比に設定

    if sw3.value() or overload:       # スイッチが押されてない、または過負荷なら
        pwm3.duty_u16(0)              # PWM1出力オフ(Duty比を0に設定)
    else:                             # スイッチが押されていれば
        pwm3.duty_u16(adc_speed_val)  # アナログ入力(ADC)値をPWMのDuty比に設定

    if sw4.value() or overload:       # スイッチが押されてない、または過負荷なら
        pwm4.duty_u16(0)              # PWM1出力オフ(Duty比を0に設定)
    else:                             # スイッチが押されていれば
        pwm4.duty_u16(adc_speed_val)  # アナログ入力(ADC)値をPWMのDuty比に設定

    # モータ過負荷保護(モータ用電源の電圧降下を検知)
    if not sw1.value() or not sw2.value() or not sw3.value() or not sw4.value():  # sw1〜sw4のどれかが押されている場合
        protect_vol = adcCheck()          # アナログ入力(ADC)確認関数呼び出し。モータ電源電圧取得
        if protect_vol <= OVERLOAD_VOLT:  # モータ電源電圧が過負荷保護レベル以下なら
            protect_count += 1                   # 過負荷保護カウント+1
            if protect_count == OVERLOAD_COUNT:  # 過負荷保護カウントが5なら
                overload = True                  # 過負荷フラグTrue
                led.value(False)                 # LEDを消灯
        else:                             # スイッチが押されてなければ
            protect_count = 0             # 過負荷保護カウント0リセット
    else:                  # スイッチが押されてなければ
        protect_count = 0  # 過負荷保護カウント0リセット
        overload = False   # 過負荷フラグFalse
        led.value(True)    # LEDを点灯

    time.sleep(0.1)  # 待ち時間

「sw1,2」を押すことで「Motor-A」を正逆転、「sw1,2」を同時に押すことで回生ブレーキで減速停止できます。
「sw3,4」を押すことで「Motor-B」を正逆転、「sw3,4」を同時に押すことで回生ブレーキで減速停止できます。

ブレーキ力はPWM制御のDuty比(ボリュームで調整)に依存します。
ブレーキ力を大きくしたい場合は「sw」同時押し時の「Duty比」を大きく(100%ONで最大)してください。

ボリュームの電圧値をアナログ入力で取得して、モータの速度指令として使用しています。
ボリュームの電圧を可変させることでPWM制御のDuty比を可変させて速度を変更しています。

アナログ入力とPWM制御のプログラムについては、以下のリンクで詳しく紹介しています。

ラズパイPico基本プログラムPython編(Lチカ,入出力,アナログ,PWM)
Raspberry Pi Picoの基本的なLチカや入出力,アナログ入力(ADC),PWM出力を行うPythonのコピペ用サンプルプログラムをまとめました。

PWM制御の技術的な情報は以下のリンクで詳しく紹介しています。(プログラム言語はC言語です)

PWM制御とは?Arduino(ESP32)コマンドで使い方を詳しく紹介
PWM制御の基本動作からArduinoコマンドを使ったプログラミング方法、サンプルプログラムを使用して音(ブザー)と光(LED)で動作確認しながら使い方を詳しく紹介します。

5.CircuitPythonのサンプルプログラム(コピペ)

「CircuitPython」を使用したサンプルプログラムはそれぞれ以下になります。
コピペで貼り付けて書き込んで実行してください。
※下コード(黒枠)内の右上角にある小さなアイコンのクリックでコピーできます。

パソコンに接続せずに「ラズパイPico」単体で動作させる場合は、ファイル名を「code.py」として本体に保存してください。
import digitalio      # 入出力ピン制御用モジュールを準備
import analogio       # アナログ入出力制御用モジュールを準備
import pwmio          # PWM制御用モジュールを準備
from board import *   # boardモジュールからすべてのピンの定義を準備
import time           # 時間に関連する操作を行うためのモジュールを準備

OVERLOAD_VOLT = 3.0   # 過負荷保護レベル(V) ※0.0で無効(乾電池駆動は無効推奨)
                      #(モータ用電源電圧の電圧降下時の値を設定、電圧降下しない電源では使用不可)
OVERLOAD_COUNT = 5    # 過負荷検知確認回数(この回数過負荷が続くとモータ停止)

# 入力ピン設定(スイッチ1〜4の入力設定)
sw1 = digitalio.DigitalInOut(GP0)          # スイッチのピン番号を設定
sw1.direction = digitalio.Direction.INPUT  # スイッチを入力モードに設定
sw1.pull = digitalio.Pull.UP               # 内部プルアップ抵抗を有効化

sw2 = digitalio.DigitalInOut(GP4)
sw2.direction = digitalio.Direction.INPUT
sw2.pull = digitalio.Pull.UP

sw3 = digitalio.DigitalInOut(GP11)
sw3.direction = digitalio.Direction.INPUT
sw3.pull = digitalio.Pull.UP

sw4 = digitalio.DigitalInOut(GP15)
sw4.direction = digitalio.Direction.INPUT
sw4.pull = digitalio.Pull.UP

# 出力ピン設定
led = digitalio.DigitalInOut(LED)           # 本体LEDのピンをledに設定
led.direction = digitalio.Direction.OUTPUT  # ledを出力モードに設定

# アナログ入力ピン設定
adc_protect = analogio.AnalogIn(A1)  # 過負荷保護レベル(モータ電源電圧)アナログ入力番号を設定
adc_speed = analogio.AnalogIn(A2)    # モータ速度指示電圧用アナログ入力番号を設定

# PWMピン設定
pwm1 = pwmio.PWMOut(GP18, frequency=500)  # PWM出力ピン番号と周波数を設定
pwm2 = pwmio.PWMOut(GP19, frequency=500)  #(隣り合った端子番号奇数と偶数は同じ周波数にする)
pwm3 = pwmio.PWMOut(GP20, frequency=500)
pwm4 = pwmio.PWMOut(GP21, frequency=500)

# アナログ入力(ADC)確認関数 *******************************************
def adcCheck():
    adc_speed_val = adc_speed.value                     # ボリュームのアナログ入力(ADC)値を取得
    adc_speed_volt = (adc_speed_val * 3.3) / 65536      # 換算してボリュームの電圧を取得
    
    adc_protect_val = adc_protect.value                 # モータ電源電圧(3.3V)のアナログ入力(ADC)値を取得
    adc_protect_volt = (adc_protect_val * 3.3) / 65536  # 換算してモータ電源電圧を取得
    print("speed_volt = {:5.2f}V /protect_volt = {:5.2f}V".format(adc_speed_volt, adc_protect_volt))  # 各電圧表示

    return adc_protect_volt  # モータ電源電圧を返す

# メイン処理 ---------------------------------------------------------
led.value = True   # LEDを点灯
protect_count = 0  #過負荷保護カウント
overload = False   #過負荷フラグ

while True:  # ずっと繰り返し
    # スイッチ操作、モータ駆動
    if sw1.value or overload:       # スイッチが押されてない、または過負荷なら
        pwm1.duty_cycle = 0         # PWM1出力オフ(Duty比を0に設定)
    else:                           # スイッチが押されていれば
        pwm1.duty_cycle = adc_speed.value  # アナログ入力(ADC)値をPWMのDuty比に設定

    if sw2.value or overload:       # スイッチが押されてない、または過負荷なら
        pwm2.duty_cycle = 0         # PWM2出力オフ(Duty比を0に設定)
    else:                           # スイッチが押されていれば
        pwm2.duty_cycle = adc_speed.value  # アナログ入力(ADC)値をPWMのDuty比に設定

    if sw3.value or overload:       # スイッチが押されてない、または過負荷なら
        pwm3.duty_cycle = 0         # PWM1出力オフ(Duty比を0に設定)
    else:                           # スイッチが押されていれば
        pwm3.duty_cycle = adc_speed.value  # アナログ入力(ADC)値をPWMのDuty比に設定
        
    if sw4.value or overload:       # スイッチが押されてない、または過負荷なら
        pwm4.duty_cycle = 0         # PWM2出力オフ(Duty比を0に設定)
    else:                           # スイッチが押されていれば
        pwm4.duty_cycle = adc_speed.value  # アナログ入力(ADC)値をPWMのDuty比に設定

    # モータ過負荷保護(モータ用電源の電圧降下を検知)
    if not sw1.value or not sw2.value or not sw3.value or not sw4.value:  # sw1〜sw4のどれかが押されている場合
        protect_vol = adcCheck()          # アナログ入力(ADC)確認関数呼び出し。モータ電源電圧取得
        if protect_vol <= OVERLOAD_VOLT:  # モータ電源電圧が過負荷保護レベル以下なら
            protect_count += 1                   # 過負荷保護カウント+1
            if protect_count == OVERLOAD_COUNT:  # 過負荷保護カウントが5なら
                overload = True                  # 過負荷フラグTrue
                led.value = False                # LEDを消灯
        else:                             # スイッチが押されてなければ
            protect_count = 0                    # 過負荷保護カウント0リセット
    else:                  # スイッチが押されてなければ
        protect_count = 0  # 過負荷保護カウント0リセット
        overload = False   # 過負荷フラグFalse
        led.value = True   # LEDを点灯

    time.sleep(0.1)  # 待ち時間

「sw1,2」を押すことで「Motor-A」を正逆転、「sw1,2」を同時に押すことで回生ブレーキで減速停止できます。
「sw3,4」を押すことで「Motor-B」を正逆転、「sw3,4」を同時に押すことで回生ブレーキで減速停止できます。

ブレーキ力はPWM制御のDuty比(ボリュームで調整)に依存します。
ブレーキ力を大きくしたい場合は「sw」同時押し時の「Duty比」を大きく(100%ONで最大)してください。

ボリュームの電圧値をアナログ入力で取得して、モータの速度指令として使用しています。
ボリュームの電圧を可変させることでPWM制御のDuty比を可変させて速度を変更しています。

アナログ入力とPWM制御のプログラムについては、以下のリンクで詳しく紹介しています。

ラズパイPico基本プログラムPython編(Lチカ,入出力,アナログ,PWM)
Raspberry Pi Picoの基本的なLチカや入出力,アナログ入力(ADC),PWM出力を行うPythonのコピペ用サンプルプログラムをまとめました。

PWM制御の技術的な情報は以下のリンクで詳しく紹介しています。(プログラム言語はC言語です)

PWM制御とは?Arduino(ESP32)コマンドで使い方を詳しく紹介
PWM制御の基本動作からArduinoコマンドを使ったプログラミング方法、サンプルプログラムを使用して音(ブザー)と光(LED)で動作確認しながら使い方を詳しく紹介します。

6.モーターの速度制御、過負荷検知プログラムについて

モーターの速度制御方法と、過負荷検知のプログラムの詳細は以下のようになります。

・速度制御

モーターの速度制御はボリュームの電圧をアナログ入力で取得して行います。

ボリュームの電圧は0〜3.3Vの範囲で可変するため、アナログ入力で取得して「speed_volt」として電圧換算します。
換算した電圧はモーター駆動時に開発環境のシリアルモニタで確認できます。

以下は開発環境「Thonny」のシリアルモニタ表示です。
ボリュームを調整してボリュームの電圧換算値(speed_volt)を約1.5Vに調整しています。
(「protect_volt」はドライバ基板の入力電圧で過負荷検知に使用します。)

Raspberry Pi Pico DCモーター制御、シリアルモニタ

1.5Vモータを使用する場合はドライバ基板の入力電圧(3V)はそのままで、ボリュームのメモリを半分程度に合わせてPWM制御のDuty比を調整することで、ドライバ基板からモータへ約1.5Vが出力されて動作させることができます。

実際にモーターの電圧をテスターで測定すると、無負荷回転の時は2V以上あり、負荷がかかると電圧は下がっていきました。速度を安定させるにはエンコーダ等で回転数を確認してPWM制御のDuty比を制御する必要があります。

・過負荷検知

過負荷検知はドライバ基板への電源電圧の低下を検知して行なっています。
モーターの保護というより、ドライバ基板へ供給する電源回路の保護を目的としています。

特にドライバ基板への電源供給に三端子レギュレータを使用する場合は、モーター過負荷時に電流が増えると、三端子レギュレータはそれなりに発熱します。
許容電流を超えると出力電圧が低下するため、この時にモータを停止させて保護するようにしています。

以下は開発環境「Thonny」のシリアルモニタ表示です。

Raspberry Pi Pico DCモーター制御、シリアルモニタ

今回使用したモーター「Geekservo」を2つ駆動して、出力軸をロックさせた状態です。
「protect_volt」は3.3Vから下がっていき、設定(OVERLOAD_VOLTで設定)した3.0Vを下回って停止しました。

サンプルプログラムでは「OVERLOAD_VOLT」に設定した電圧を「OVERLOAD_COUNT」の回数下回った状態が続くと過負荷としてモーターを停止させています。
この設定は使用するモータに合わせて調整してください。
無効にする場合は「OVERLOAD_VOLT」を「0.0(V)」に設定してください。

7.まとめ

Raspberry Pi Pico(PicoW)を使用して、簡単にDCモータの正逆転、速度制御(PWM制御、ドライバ基板MX1508使用)や過負荷保護をする方法をサンプルプログラム(コピペ)で詳しく紹介しました。

プログラム言語は「Python」を使用して「MicroPython」と「CircuitPython」の両方で紹介しました。「MicroPython」の方がシンプルで分かりやすいと思います。

DCモーターの速度制御を行うには「PWM制御」を使用します。
ラズパイPicoのようなマイコンボードは扱える電流が小さいため、モーターのような比較的大きな電流を制御するには専用のドライバ基板を使用する必要があります。

今回使用したドライバ基板(MX1508搭載)は電源電圧範囲が「2V〜10V」で模型や工作用の3Vモータの駆動に最適です。PWM制御で調整すれば1.5Vモータの駆動も可能です。

1つのドライバ基板で2つのモーターを制御できるため、左右のモーターを個別に駆動させるラジコンに最適なので、今後はWi-Fi搭載のラズパイPicoWを使って遠隔操作できるラジコンなんかも作って紹介していきたいと思います。

ラズパイPicoW Wi-Fi通信、遠隔操作&表示 MicroPython編
Raspberry Pi PicoWのWi-Fi無線通信を使用してMicroPythonでパソコンやスマホのブラウザから遠隔操作,データ表示する方法を詳しく紹介

コメント

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