Motor Shield¶
The Motor Shield drives two DC motors from the OpenMV Cam using a TB6612FNG dual H-bridge, with an NCP1117 5 V linear regulator that powers both the camera and the motors from a single 6.5–18 V battery input.
For full datasheet, photos, and ordering see the Motor Shield product page.
Highlights¶
Two independent motor channels with PWM speed control
Up to 2 A drive current per channel
Can also drive a bipolar stepper motor
Stacks with the Servo Shield
Pinout¶
Pin reference¶
Pin |
Function |
|---|---|
P0 |
DIR B1 (motor B direction) |
P1 |
DIR B0 (motor B direction) |
P2 |
DIR A1 (motor A direction) |
P3 |
DIR A0 (motor A direction) |
P6 |
TB6612FNG STANDBY — defaults on; pull low to enter low-power mode |
P7 |
PWM speed input for motor A |
P8 |
PWM speed input for motor B |
VBAT in |
6.5–18 V battery input on the screw terminal (NCP1117 limits) |
VIN out |
5 V from the on-board NCP1117 regulator (powers the camera) |
3.3V rail |
Powers the TB6612FNG logic |
GND rail |
Common ground |
Note
P6 drives the TB6612 STANDBY input by default. Cut the solder trace on the back of the shield to disconnect P6 if you’d rather use the pin for something else (the driver then stays enabled).
Note
The TB6612FNG drives each motor through a two-input truth table plus a PWM enable. For motor A (with STBY high and PWMA at any non-zero duty):
(P3, P2) = (H, L)→ forward(P3, P2) = (L, H)→ reverse(P3, P2) = (L, L)→ coast (outputs Hi-Z)(P3, P2) = (H, H)→ brake (outputs both low)
Driving PWMA low forces a short brake regardless of the direction
inputs — a 0 % duty cycle brakes the motor. Motor B follows the
same table on (P1, P0) with PWM on P8.
Usage¶
Cycle motor A through forward → brake → reverse → coast on a fixed PWM duty:
from machine import Pin, PWM
import time
a0 = Pin("P3", Pin.OUT) # AIN1
a1 = Pin("P2", Pin.OUT) # AIN2
pwma = PWM(Pin("P7"), freq=1_000, duty_u16=40_000) # ~60%
def drive(in1, in2):
a0.value(in1)
a1.value(in2)
while True:
drive(1, 0) # forward
time.sleep(2)
drive(1, 1) # brake
time.sleep_ms(500)
drive(0, 1) # reverse
time.sleep(2)
drive(0, 0) # coast
time.sleep_ms(500)
For variable-speed control, hold the direction inputs constant and ramp PWMA. The loop below ramps motor A from coast up to full forward and back down:
from machine import Pin, PWM
import time
Pin("P3", Pin.OUT, value=1) # AIN1=H
Pin("P2", Pin.OUT, value=0) # AIN2=L → forward direction
pwma = PWM(Pin("P7"), freq=1_000, duty_u16=0)
while True:
for duty in range(0, 65_536, 1024):
pwma.duty_u16(duty)
time.sleep_ms(10)
for duty in range(65_535, -1, -1024):
pwma.duty_u16(duty)
time.sleep_ms(10)
The TB6612’s two H-bridges can also wave-drive a bipolar stepper —
energize one coil at a time, walking through four phases. Hold both
PWM channels at the desired drive current and call step() to
advance one full sequence in either direction:
from machine import Pin, PWM
import time
a0 = Pin("P3", Pin.OUT)
a1 = Pin("P2", Pin.OUT)
b0 = Pin("P1", Pin.OUT)
b1 = Pin("P0", Pin.OUT)
PWM(Pin("P7"), freq=1_000, duty_u16=32_768) # 50% drive on A
PWM(Pin("P8"), freq=1_000, duty_u16=32_768) # 50% drive on B
SEQUENCE = [(1, 0, 0, 0), (0, 0, 1, 0), (0, 1, 0, 0), (0, 0, 0, 1)]
def step(forward=True):
for s in SEQUENCE if forward else reversed(SEQUENCE):
a0.value(s[0])
a1.value(s[1])
b0.value(s[2])
b1.value(s[3])
time.sleep_ms(5)
while True:
for _ in range(50): # ~1 revolution forward (200 phases)
step()
for _ in range(50): # ~1 revolution backward
step(forward=False)
The on-board STANDBY line defaults high (driver enabled). Pull P6 low to put the TB6612 to sleep:
from machine import Pin
Pin("P6", Pin.OUT).value(0) # standby