Note
To minimize the margin of error during these tests, we suggest connecting each motor pin (specified in the example codes) to its own resistor and LED (in series). By doing so, you can distinguish between pinout errors and faulty motor driver ICs more easily (not to mention doing away with the motors’ isolated power requirements).
BiMotor test¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | """
A simple test of the BiMotor class
This iterates through a list of motor commands
and prints the ellapsed time taken to acheive each command
"""
# pylint: disable=invalid-name
import time
import board
from drivetrain import BiMotor
motor = BiMotor([board.D22, board.D13], ramp_time=2000)
Value = [-25, 25, -100, 100, 0]
for test in Value:
# send input instructions
# NOTE we convert the percentage value to range [-65535, 65535]
motor.cellerate(test * 655.35)
start = time.monotonic()
t = start
# do a no delay wait for at most 3 seconds
while motor.is_cellerating and t < start + 3:
t = time.monotonic()
print('test result {} took {} seconds'.format(motor.value, t - start))
|
PhasedMotor test¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | """
A simple test of the PhasedMotor class
This iterates through a list of motor commands
and prints the ellapsed time taken to acheive each command
"""
# pylint: disable=invalid-name
import time
import board
from drivetrain.motor import PhasedMotor
motor = PhasedMotor([board.D17, board.D18], ramp_time=2000)
Value = [-25, 25, -100, 100, 0]
for test in Value:
# send input instructions
# NOTE we convert the percentage value to range [-65535, 65535]
motor.cellerate(test * 655.35)
start = time.monotonic()
t = start
# do a no delay wait for at most 3 seconds
while motor.is_cellerating and t < start + 3:
t = time.monotonic()
print('test result {} took {} seconds'.format(motor.value, t - start))
|
StepperMotor test¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | """A simple test of the StepperMotor class driving a 5V microstepper"""
# pylint: disable=invalid-name
import time
import board
from drivetrain.stepper import StepperMotor
motor = StepperMotor([board.D13, board.D12, board.D11, board.D10])
Steps = [-256, 256, 0] # 1024, 2048, 4096]
Angle = [-15, 15, 0] # 180, 360]
Value = [-25, 25, 0] # -50, 100, 0]
for test in Value:
motor.value = test # send input instructions
# do a no delay wait for at least 2 seconds
start = time.monotonic()
t = start
end = None
while motor.is_cellerating or t < start + 2:
t = time.monotonic()
if not motor.is_cellerating and end is None:
end = t
print(repr(motor))
print('value acheived in', end-start, 'seconds')
# elif motor.is_cellerating:
# print(repr(motor))
|
Tank Drivetrain test¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | """
A simple test of the Tank drivetrain class.
This iterates through a list of drivetrain commands
and tallies up the ellapsed time taken to acheive each set of commands
as well as the ellapsed time taken for each motor to acheive each individual command
"""
# pylint: disable=invalid-name
import time
import board
from drivetrain.drivetrain import Tank, BiMotor
mymotors = [BiMotor([board.D22, board.D13], ramp_time=2000),
BiMotor([board.D17, board.D18], ramp_time=2000)]
d = Tank(mymotors)
testInput = [[100, 0],
[-100, 0],
[0, 0],
[0, 100],
[0, -100],
[0, 0]]
for test in testInput:
# use the list `end` to keep track of each motor's ellapsed time
end = []
# NOTE we convert a percentage to range of an 32 bit int
for i, t_val in enumerate(test):
test[i] = t_val * 655.35
for m in mymotors:
# end timer for motor[i] = end[i]
end.append(None)
d.go(test) # send input commands
# unanimous start of all timmers
start = time.monotonic()
t = start
# do a no delay wait for at least 3 seconds
while d.is_cellerating or t < start + 3:
t = time.monotonic()
for j, m in enumerate(mymotors):
if not m.is_cellerating and end[j] is None:
end[j] = t
print('test commands {} took {} seconds'.format(repr(test), t - start))
for j, m in enumerate(mymotors):
if end[j] is not None:
print('motor {} acheived {} in {} seconds'.format(j, m.value, end[j]-start))
else:
print("motor {} didn't finish cellerating and a has value of {}".format(j, m.value))
print(' ') # for clearer print statement grouping
|
Automotive Drivetrain test¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | """
A simple test of the Automotive drivetrain class.
This iterates through a list of drivetrain commands
and tallies up the ellapsed time taken to acheive each set of commands
as well as the ellapsed time taken for each motor to acheive each individual command
"""
# pylint: disable=invalid-name
import time
import board
from drivetrain.drivetrain import Automotive, PhasedMotor
mymotors = [PhasedMotor([board.D22, board.D13], ramp_time=2000),
PhasedMotor([board.D17, board.D18], ramp_time=2000)]
d = Automotive(mymotors)
testInput = [[100, 0],
[-100, 0],
[0, 0],
[0, 100],
[0, -100],
[0, 0]]
for test in testInput:
# use the list `end` to keep track of each motor's ellapsed time
end = []
# NOTE we convert a percentage to range of an 32 bit int
for i, t_val in enumerate(test):
test[i] = t_val * 655.35
for m in mymotors:
# end timer for motor[i] = end[i]
end.append(None)
d.go(test) # send input commands
# unanimous start of all timmers
start = time.monotonic()
t = start
# do a no delay wait for at least 3 seconds
while d.is_cellerating or t < start + 3:
t = time.monotonic()
for j, m in enumerate(mymotors):
if not m.is_cellerating and end[j] is None:
end[j] = t
print('test commands {} took {} seconds'.format(repr(test), t - start))
for j, m in enumerate(mymotors):
if end[j] is not None:
print('motor {} acheived {} in {} seconds'.format(j, m.value, end[j]-start))
else:
print("motor {} didn't finish cellerating and a has value of {}".format(j, m.value))
print(' ') # for clearer print statement grouping
|
nRF24L01 receiving test¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | """
Example of library usage receiving commands via an
nRF24L01 transceiver to control a Mecanum drivetrain.
"""
import board
from digitalio import DigitalInOut as Dio
from circuitpython_nrf24l01 import RF24
from drivetrain import Mecanum, BiMotor, NRF24L01rx
# instantiate transceiver radio on the SPI bus
nrf = RF24(board.SPI(), Dio(board.D5), Dio(board.D4))
# instantiate motors for a Mecanum drivetrain in the following order
# Front-Right, Rear-Right, Rear-Left, Front-Left
motors = [
BiMotor([board.RX, board.TX]),
BiMotor([board.D13, board.D12]),
BiMotor([board.D11, board.D10]),
BiMotor([board.D2, board.D7])
]
# NOTE there are no more PWM pins available
# instantiate receiving object for a Mecanum drivetrain
d = NRF24L01rx(nrf, Mecanum(motors))
while True: # this runs forever
d.sync()
# doing a keyboard interupt will most likely leave the SPI bus in an
# undesirable state. You must do a hard-reset of the circuitoython MCU to
# reset the SPI bus for continued use. This code assumes power is lost on exit.
|