not logged in | [Login]
I made a dual dc motor driver for my pyboard on a bit of 12x8 perfboard using nothing more than a Texas Instruments SN 754110 quad h-bridge, and it works fine. The accompanying module requires my pwm module for speed control (at the moment).
Each attached motor can be driven forwards or backwards at 0-255 different speeds. This is a 5v chip, so the logic needs to be driven by Vin Pin, not a 3.3v Pin and may be subject to risk if you power your pyboard via other than USB (although I've used it with the pyboard powered by a 9v battery and 'no harm came of it').
An external battery is required - this supplies the current that drives the dc motors ... an EE would be required to figure a shared power configuration.
The skin is designed to sit on either the Y or X orientation on the pyboard, in the Y position the two motors are referred to as Y1 and Y2 and in the X position as X1 and X2 (for initialising an instance of the class only).
Don't have a proper schematic of the skin, as it was botched together, my hookup was as follows, but the general code could easily be adapted to any configuration (note: on my skin the h-bridge chip is 'upside down' in relation to the pyboard, hence the odd pin numbering);
TI SN 754410 NE
Quad H-bridge
-----------------------
Pin Vin -> |16 +ve 1,2EN 1| -> Pin Y8
Pin Y1 -> |15 4A 1A 2| -> Pin Y7
Motor 2 -> |14 4Y 1Y 3| -> Motor 1
Gnd & -ve Bat -> |13 Gnd Gnd 4| -> Gnd & -ve Bat
Gnd & -ve Bat -> |12 Gnd Gnd 5| -> Gnd & -ve Bat
Motor 2 -> |11 3Y 2Y 6| -> Motor 1
Pin Y2 -> |10 3A 2A 7| -> Y6
Pin Y3 -> |9 3,4EN +ve Bat 8| -> +ve Bat
-----------------------
>>> import dcmotor
>>> m1 = dcmotor.DCMOTOR(dcmotor.Y1) #skin in Y position, create an object to control motor Y1
>>> m2 = dcmotor.DCMOTOR(dcmotor.Y2, reverse_pols=True) #reverse input to motor on Y2
>>> m1.forwards() #run m1 forwards full tilt
>>> m1.backwards() # backwards, full tilt
>>> m1.stop() #stop
>>> m1.forwards(255/2) #forward half speed
>>> m1.stop() #stop
>>> m1.state(255/2) #forwards half speed
>>> m1.state(-255) #backwards full tilt
>>> m1.state() #return current speed
-255
dcmotor.py
import pyb, pwm
FORWARDS = 255
BACKWARDS = -FORWARDS
STOP = 0
#possible dcmotor configurations, depends on skin orientation
Y1 = {'enable':pyb.Pin.board.Y8,'control0':pyb.Pin.board.Y6,'control1':pyb.Pin.board.Y7}
Y2 = {'enable':pyb.Pin.board.Y3,'control0':pyb.Pin.board.Y2,'control1':pyb.Pin.board.Y1}
X1 = {'enable':pyb.Pin.board.X8,'control0':pyb.Pin.board.X6,'control1':pyb.Pin.board.X7}
X2 = {'enable':pyb.Pin.board.X3,'control0':pyb.Pin.board.X2,'control1':pyb.Pin.board.X1}
class DCMOTOR:
"""dirty DC Motor Class"""
def __init__(self, pins_dict, reverse_pols=False):
self.__enable = pins_dict['enable']
self.__control0 = pins_dict['control0'] if not reverse_pols else pins_dict['control1']
self.__control1 = pins_dict['control1'] if not reverse_pols else pins_dict['control0']
self.__pwm = pwm.PWM(self.__enable)
self.__control0.init(pyb.Pin.OUT_PP)
self.__control0.low()
self.__control1.init(pyb.Pin.OUT_PP)
self.__control1.low()
def state(self,value=None):
"""get or set motor state as -ve|0|+ve as backwards|stop|forwards"""
if value == None:
if self.__pwm.duty() > 0:
if self.__control0.value() and not self.__control1.value():
return -self.__pwm.duty()
elif not self.__control0.value() and self.__control1.value():
return self.__pwm.duty()
else:
raise ValueError('Inconsistent state')
else:
return 0
elif value < 0:
self.__control0.high()
self.__control1.low()
self.__pwm.duty(abs(value))
elif value > 0:
self.__control0.low()
self.__control1.high()
self.__pwm.duty(value)
elif value == 0:
self.__pwm.duty(0)
else:
raise ValueError('Invalid state value passed')
def backwards(self,value=-BACKWARDS):
self.state(-value)
def forwards(self,value=FORWARDS):
self.state(value)
def stop(self):
self.state(STOP)
def emergency_stop(self,brakes_for=50):
if self.state() != 0:
self.__control0.value(int(not(self.__control0.value())))
self.__control1.value(int(not(self.__control1.value())))
pyb.delay(brakes_for)
self.stop()
Last edited by PinkInk, 2014-07-29 17:05:14