MicroPythonを入れたESP32とBTS7960でDCモータを回してみる

2020/07/24 categories:ESP32| tags:ESP32|MicroPython|BTS7960|DC motor|

ESP32でBTS7960を使ってDCモーターを回してみました

モーターのピンアサイン

モーターに付属していたケーブルのピンアサインは下記の通りでした。ただし、ケーブルの色の並びがいろいろあるようで、基板を正面にしてコネクタが左側に来るように見た場合、上から順番に下記のようなピンアサインになるようです。

機能 ピン
モーター(-) 1
エンコーダ電源 2
エンコーダA相 3
エンコーダB相 4
エンコーダGND 5
モーター(+) 6

BTS7960のピンアサイン

モータードライバはBTS7960を使用しました。ピンアサインは下記の通りです

ピン 機能
VCC 電源
GND グラウンド
R_IS 電流検出とエラーフラグの出力
L_IS 電流検出とエラーフラグの出力
R_EN Rのenable
L_EN Lのenable
RPWM RのPWM
LPWM LのPWM

BTS7960の動作パターン

それぞれのピンへの入力によるモーターの動作パターンは下記の通りになります

R_EN L_EN RPWM LPWM
正転 1 1 1 0
逆転 1 1 0 1
ニュートラル 0 0 X X
ブレーキ 1 1 0 0

BTS7960のデッドタイム生成

データシート内に下記のように、ドライバIC内の回路によって保証され、MOSFETをオフしてから別のMOSFETをオンするまでにデッドタイムが発生するとあります。従って、ソフトによるデッドタイム生成は必要ないでしょう。

This is assured by a circuit in the driver IC, generating a so called dead time between switching off one MOSFET and switching on the other

動作の様子

正転後にブレーキ、逆転後にニュートラルを行い、停止時にエンコーダの値を送信するプログラムを動作させた様子です。

ソースコード

import time
from machine import Pin

class Encorder():
    def __init__(self, pin_a, pin_b):
        self.pin_a, self.pin_b = pin_a, pin_b
        self.position, self.value, self.direction = 0, 0, 0
        self.table = [
             0, 1,-1, 0,
            -1, 0, 0, 1,
             1, 0, 0,-1,
             0,-1, 1, 0
        ]
        
    def check(self, pin):
        self.value = (self.value << 2) + self.pin_a.value() + (self.pin_b.value() << 1)
        self.value = self.value & 0x0F
        self.direction = self.table[self.value]
        self.position += self.direction

class BTS7960():
    def __init__(self, r_en, l_en, rpwm, lpwm):
        self.R_EN = r_en
        self.L_EN = l_en
        self.RPWM = rpwm
        self.LPWM = lpwm
        self.neutral()

    def right(self):
        self.R_EN.on()
        self.L_EN.on()
        self.LPWM.off()
        self.RPWM.on()

    def left(self):
        self.R_EN.on()
        self.L_EN.on()
        self.RPWM.off()
        self.LPWM.on()

    def neutral(self):
        self.R_EN.off()
        self.L_EN.off()
        self.RPWM.off()
        self.LPWM.off()

    def brake(self):
        self.R_EN.on()
        self.L_EN.on()
        self.RPWM.off()
        self.LPWM.off()

## GPIO settings
encoder_a = Pin(34, Pin.IN)
encoder_b = Pin(35, Pin.IN)
r_en = Pin(25, Pin.OUT)
l_en = Pin(26, Pin.OUT)
rpwm = Pin(32, Pin.OUT)
lpwm = Pin(33, Pin.OUT)

## Encoorder settings
encorder = Encorder(encoder_a, encoder_b)

## Interrupt settings
encoder_a.irq( encorder.check )
encoder_b.irq( encorder.check )

bts7960 = BTS7960(r_en, l_en, rpwm, lpwm)

bts7960.neutral()
time.sleep(3)

print('start')

while True:

    bts7960.left()
    print('left')
    time.sleep(1)

    bts7960.brake()
    print('brake')
    print(encorder.position, encorder.direction)
    time.sleep(0.5)

    bts7960.right()
    print('right')
    time.sleep(1)

    bts7960.neutral()
    print('neutral')
    print(encorder.position, encorder.direction)
    time.sleep(0.5)

Share post

Related Posts

コメント