Resuming Long Stalled SPV (Smart Pico Vehicle) Project
Part 1
This project has be stalled for over a month, and I have forgotten what I did last time. So I need now to refresh my memory. The first thing is to make sure the basic Pico hardware still running OK. My first test procedure is to run the “toggle system led program”. Luckily all looks well. Below is the updated toggle led program, with sample output.
# Program Name
# toggle_pico_system_led_v04.py - tlfong01 2021aug16hkt1606
# Configuration
# Thonny 3.3.3, Acer Intel CORE i5 Chinese Windows 10 (64-bit), Python 3.7.9 (32-bit), Tk 8.6.9, USB COM Port #4
# Intepreter
# Micropython (Rapsberry Pi Pico)
# Program Function
# Toggle Pico system LED at GPIO pin 15 (run program to switch on LED, run again to switch off)
# User Guide
# Run code to toggle LED from On to Off or Off to On
from machine import Pin
systemLed = Pin(25, Pin.OUT)
print('Testing Toggling Pcio System LED, v0.4 tlfong01 2021aug16hkt1613')
systemLed.toggle()
# END
# Sample Output - tlfong01 2021aug16hkt1614
'''
>>> %Run -c $EDITOR_CONTENT
Testing Toggling Pcio System LED, v0.4 tlfong01 2021aug16hkt1613
>>> %Run -c $EDITOR_CONTENT
Testing Toggling Pcio System LED, v0.4 tlfong01 2021aug16hkt1613
>>>
'''
Part 2 - Checking the 2WD Wiring
I vaguely remember that I first tested one TT130 toy motor with the very simple MX1508 driver, as described by the Tom’s Hardware tutorial. Then I moved on to used TB6616 motr driver, with two N20 motors with speed encoders. I vaguely remember that I used Pico GPIO to read the one of the two encoder output signals, and got a rough idea of the motor speed vs encoder signal periods. So I need to resume from this point. But before that, I need to make sure the motor driver and motor can still move. First step is check out the hardware setup and wiring, and run the basic test program.
Actually I forgot the details of the hardware. So I read my old post to refresh my memory: Making a Rpi Pico Based Smart Vehicle.
The following image is a good memory refresher:
Part 3 - Manual Jumper Wire Motor Moving Testing
Now I am using the following cheat sheet to refresh my memory on how to use jumper wires to off line testing moving motors
To move Motor 1 CW, Motor 2 CCW, I am using the following conifg/wiring
-
IN1, IN2 (Yellow, Blue) to Low High or High Low
-
PWM (Purple) = High
-
StdBy (Brown) = High
Part 4 - Using MicroPython to test moving motors
Now I am using the following Pico MicroPython program is move one motor forward, backward, and stop, and found everything OK.
# Program Name
# move_one_motor_v01.py - tlfong01 2021aug16hkt2218
# Reference
# Pi-Top Forum - making-a-rpi-pico-based-smart-vehicle/924
# https://forum.pi-top.com/t/making-a-rpi-pico-based-smart-vehicle/924
# Configuration
# Thonny 3.3.3, Windows 10 (64-bit), Python 3.7.9 (32-bit), Tk 8.6.9, USB COM Port #4
# Intepreter
# Micropython (Rapsberry Pi Pico)
# DC Motor
# (a) TT130 DC3~6V DC Gear Motor - AliEXpress US$1
# https://www.aliexpress.com/item/32855311589.html
# (b) N20 Gear Motor
#
# DC Motor Driver
# (a) MX1508 2~10V, 1.5A, Dual H-Bridge DC Motor Driver - AliExpress US$1
# https://www.aliexpress.com/item/32688083107.html
# (b) TB6612FNG Dual DC Motor Driver
# Program Function
# Move DC motor forward, backward, and stop
# User Guide
# (a) Connect PWMA (purple), PWMB (purple) to High (Vcc)
# (b) Connect Standby (brown) to High
# (c) Run program to move motor forward, backward, and stop
import utime
from machine import Pin
motor1a = Pin(10, Pin.OUT)
motor1b = Pin(11, Pin.OUT)
def moveMotorForward():
motor1a.low()
motor1b.high()
def moveMotorBackward():
motor1a.high()
motor1b.low()
def stopMotor():
motor1a.low()
motor1b.low()
def test():
print(' Begin move motor test()')
moveMotorForward()
utime.sleep(1)
moveMotorBackward()
utime.sleep(1)
stopMotor()
print(' End test()')
for i in range(2):
print('Test ', i)
test()
# *** End of program ***
# *** Sample Output - tlfong01 2021jul01hkt1707
'''
>>> %Run -c $EDITOR_CONTENT
Test 0
Begin move motor test()
End test()
Test 1
Begin move motor test()
End test()
>>>
'''
Part 5 - Moving two motors
Now that my little demo microPython program moving one N20 motor goes well, I am now upgrading it to move two motors. Now I have a problem of mixing up the getting complicated jumper wires, and therefore find it difficult to do troubleshooting. So I need to do some proper documentation, starting with the photo below.
Now the time has come to use Pico MicroPython to move two motors. The following program is tested OK.
# Program Name
# move_two_motors_v05.py - tlfong01 2021aug17hkt1607
# Reference
# Pi-Top Forum - making-a-rpi-pico-based-smart-vehicle/924
# https://forum.pi-top.com/t/making-a-rpi-pico-based-smart-vehicle/924
#
# Configuration
# Acer Intel COIRE i5 PC Chinese Windows 10 (64-bit), Thonny 3.3.3, Python 3.7.9 (32-bit), Tk 8.6.9, USB COM Port #4
#
# Thonny MicroPython Intepreter
# Micropython (Rapsberry Pi Pico)
# DC Motor
# N20 1:48 6V DC Gear Motor with quadrature encoder signals A, B
#
# DC Motor Driver
# TB6612FNG Dual DC Motor Driver
# Program Function
# Move Two DC motors forward, backward, and stop
# User Guide
# (a) Connect PWMA (purple), PWMB (purple) to High (Vcc)
# (b) Connect Standby (brown) to High (Vcc)
# (c) Pico GP 10, 11 (Blk, Bwn) to Motor Driver AIN1, AIN2 (Yel, Blu)
# (d) Pico GP 12, 13 (Red, Orn) to Motor Driver BIN1, BIN2 (Yel, Blu)
# (c) Run program to move motor forward, backward, and stop
import utime
from machine import Pin
motorDict01 = {
'1': {'IN1': 10, 'IN2': 11},
'2': {'IN1': 12, 'IN2': 13},
'3': {'IN1': 0, 'IN2': 0},
'4': {'IN1': 0, 'IN2': 0},
}
motorDictDict = {
'1': motorDict01,
'2': motorDict01,
}
def setupMotor(motorDictNum, motorNum):
motorDict = motorDictDict[str(motorDictNum)]
motorIn1 = Pin(motorDict[str(motorNum)]['IN1'], Pin.OUT)
motorIn2 = Pin(motorDict[str(motorNum)]['IN2'], Pin.OUT)
motorInList = [motorIn1, motorIn2]
return motorInList
def moveMotorForward(motorDictNum, motorNum):
motorInList = setupMotor(motorDictNum, motorNum)
motorInList[0].high()
motorInList[1].low()
return motorInList
def moveMotorBackward(motorDictNum, motorNum):
motorInList = setupMotor(motorDictNum, motorNum)
motorInList[0].low()
motorInList[1].high()
return motorInList
def moveMotorStop(motorDictNum, motorNum):
motorInList = setupMotor(motorDictNum, motorNum)
motorInList[0].low()
motorInList[1].low()
return motorInList
# *** Tests ***
moveMotorForward(motorDictNum = 1, motorNum = 1)
utime.sleep(1)
moveMotorBackward(motorDictNum = 1, motorNum = 1)
utime.sleep(1)
moveMotorStop(motorDictNum = 1, motorNum = 1)
moveMotorForward(motorDictNum = 1, motorNum = 2)
utime.sleep(2)
moveMotorBackward(motorDictNum = 1, motorNum = 2)
utime.sleep(2)
moveMotorStop(motorDictNum = 1, motorNum = 2)
# *** End of program ***
# *** Sample Output - tlfong01 2021jul01hkt1707
'''
'''
Part 6 - Moving two motors with program controlling StandBy and PWM
The following program moving two motor and program control StandBy and PWM is tested OK.
# Program Name
# move_two_motors_v09.py - tlfong01 2021aug17hkt2014
# Reference
# Pi-Top Forum - making-a-rpi-pico-based-smart-vehicle/924
# https://forum.pi-top.com/t/making-a-rpi-pico-based-smart-vehicle/924
#
# Configuration
# Acer Intel COIRE i5 PC Chinese Windows 10 (64-bit), Thonny 3.3.3, Python 3.7.9 (32-bit), Tk 8.6.9, USB COM Port #4
#
# Thonny MicroPython Intepreter
# Micropython (Rapsberry Pi Pico)
# DC Motor
# N20 1:48 6V DC Gear Motor with quadrature encoder signals A, B
#
# DC Motor Driver
# TB6612FNG Dual DC Motor Driver
# Program Function
# Move Two DC motors forward, backward, and stop
# User Guide
# (a) Connect PWMA (purple), PWMB (purple) to High (Vcc)
# (b) Connect Standby (brown) to High (Vcc)
# (c) Pico GP 10, 11 (Blk, Bwn) to Motor Driver AIN1, AIN2 (Yel, Blu)
# (d) Pico GP 12, 13 (Red, Orn) to Motor Driver BIN1, BIN2 (Yel, Blu)
# (c) Run program to move motor forward, backward, and stop
import utime
from machine import Pin
driverDict01 = {
'Title' : 'TB6612FNG Dual DC Motor Driver',
'STANDBY' : 5,
'1': {'IN1': 10, 'IN2': 11, 'PWM' : 3, 'ENCODE': 14},
'2': {'IN1': 12, 'IN2': 13, 'PWM' : 4, 'ENCODE': 15},
'3': {'IN1': 0, 'IN2': 0, 'PWM' : 0},
'4': {'IN1': 0, 'IN2': 0, 'PWM' : 0},
}
driverDictDict = {
'1': driverDict01,
'2': driverDict01,
}
def setupDriver(driverDictNum):
driverDict = driverDictDict[str(driverDictNum)]
standBy = Pin(driverDict['STANDBY'], Pin.OUT)
standBy.high()
return
def setupMotor(driverDictNum, motorNum):
driverDict = driverDictDict[str(driverDictNum)]
motorIn1 = Pin(driverDict[str(motorNum)]['IN1'], Pin.OUT)
motorIn2 = Pin(driverDict[str(motorNum)]['IN2'], Pin.OUT)
motorPwm = Pin(driverDict[str(motorNum)]['PWM'], Pin.OUT)
motorControlPinList = [motorIn1, motorIn2, motorPwm]
return motorControlPinList
def moveMotorForward(driverDictNum, motorNum):
motorControlPinList = setupMotor(driverDictNum, motorNum)
motorControlPinList[0].low()
motorControlPinList[1].high()
motorControlPinList[2].high()
return
def moveMotorBackward(driverDictNum, motorNum):
motorControlPinList = setupMotor(driverDictNum, motorNum)
motorControlPinList[0].high()
motorControlPinList[1].low()
motorControlPinList[2].high()
return
def moveMotorStop(driverDictNum, motorNum):
motorControlPinList = setupMotor(driverDictNum, motorNum)
motorControlPinList[0].low()
motorControlPinList[1].low()
motorControlPinList[2].high()
return
# *** Motor Test Functions ***
def motorTest01(driverDictNum, motorNum):
# *** Setup Driver ***
setupDriver(driverDictNum)
# *** Move motor forward ***
moveMotorForward(driverDictNum, motorNum)
utime.sleep(1)
# *** Move motor backward ***
moveMotorBackward(driverDictNum, motorNum)
utime.sleep(1)
# *** Move motor stop ***
moveMotorStop(driverDictNum, motorNum)
return
# *** Main Tests ***
# Setup motor driver, Move Motor 1 forward, backward, stop
motorTest01(driverDictNum = 1, motorNum = 1)
# Setup motor driver, Move Motor 2 forward, backward, stop
motorTest01(driverDictNum = 1, motorNum = 2)
# *** End of program ***
# *** Sample Output - tlfong01 2021jul01hkt1707
'''
>>> %Run -c $EDITOR_CONTENT
'''
Part 6 - Reading Encoder Signals
The following program give N20 1:100 gear speed of around 400rpm
# Program Name
# measure_motor_speed_v09.py - tlfong01 2021aug18hkt1120
# Reference
# Pi-Top Forum - making-a-rpi-pico-based-smart-vehicle/924
# https://forum.pi-top.com/t/making-a-rpi-pico-based-smart-vehicle/924
#
# Configuration
# Acer Intel COIRE i5 PC Chinese Windows 10 (64-bit), Thonny 3.3.3, Python 3.7.9 (32-bit), Tk 8.6.9, USB COM Port #4
#
# Thonny MicroPython Intepreter
# Micropython (Rapsberry Pi Pico)
#
# DC Motor
# N20 1:100 6V DC Gear Motor with quadrature encoder signals A, B
# N20 Gear Motor Spec (6V gear 1:100 no load speed = 300 rpm (https://www.pololu.com/search/compare/173)
#
# DC Motor Driver
# TB6612FNG Dual DC Motor Driver
# Program Function
# Measure speed of DC motor N20 with quadrature encoder
import utime
from machine import Pin
driverDict01 = {
'Title' : 'TB6612FNG Dual DC Motor Driver',
'STANDBY' : 5,
'1': {'IN1': 10, 'IN2': 11, 'PWM' : 3, 'ENCODE': 14},
'2': {'IN1': 12, 'IN2': 13, 'PWM' : 4, 'ENCODE': 15},
'3': {'IN1': 0, 'IN2': 0, 'PWM' : 0},
'4': {'IN1': 0, 'IN2': 0, 'PWM' : 0},
}
driverDictDict = {
'1': driverDict01,
'2': driverDict01,
}
def setupDriver(driverDictNum):
driverDict = driverDictDict[str(driverDictNum)]
standBy = Pin(driverDict['STANDBY'], Pin.OUT)
standBy.high()
return
def setupMotor(driverDictNum, motorNum):
driverDict = driverDictDict[str(driverDictNum)]
motorIn1 = Pin(driverDict[str(motorNum)]['IN1'], Pin.OUT)
motorIn2 = Pin(driverDict[str(motorNum)]['IN2'], Pin.OUT)
motorPwm = Pin(driverDict[str(motorNum)]['PWM'], Pin.OUT)
motorEncode = Pin(driverDict[str(motorNum)]['ENCODE'], Pin.IN, Pin.PULL_DOWN)
motorControlPinList = [motorIn1, motorIn2, motorPwm, motorEncode]
return motorControlPinList
def moveMotorForward(driverDictNum, motorNum):
motorControlPinList = setupMotor(driverDictNum, motorNum)
motorControlPinList[0].low()
motorControlPinList[1].high()
motorControlPinList[2].high()
return
def moveMotorBackward(driverDictNum, motorNum):
motorControlPinList = setupMotor(driverDictNum, motorNum)
motorControlPinList[0].high()
motorControlPinList[1].low()
motorControlPinList[2].high()
return
def moveMotorStop(driverDictNum, motorNum):
motorControlPinList = setupMotor(driverDictNum, motorNum)
motorControlPinList[0].low()
motorControlPinList[1].low()
motorControlPinList[2].high()
return
def readMotorEncodeValue(driverDictNum, motorNum):
motorControlPinList = setupMotor(driverDictNum, motorNum)
encodeValue = motorControlPinList[3].value()
return encodeValue
# *** Motor Test Functions ***
def testMoveMotor01(driverDictNum, motorNum):
# *** Setup Driver ***
setupDriver(driverDictNum)
# *** Move motor forward ***
moveMotorForward(driverDictNum, motorNum)
utime.sleep(1)
# *** Move motor backward ***
moveMotorBackward(driverDictNum, motorNum)
utime.sleep(1)
# *** Move motor stop ***
moveMotorStop(driverDictNum, motorNum)
return
def testReadMotorEncodeValue01(driverDictNum, motorNum):
# *** Setup Driver ***
setupDriver(driverDictNum)
# *** Read motor encode value ***
print('Move motor by hand and read encode value every second, ...')
for secondCount in range(100):
encodeValue = readMotorEncodeValue(driverDictNum, motorNum)
print(' motor encode value =', encodeValue)
utime.sleep(1)
return
def testReadMotorEncodeValue02(driverDictNum, motorNum):
# *** Setup Driver ***
setupDriver(driverDictNum)
# *** Move motor forward ***
moveMotorForward(driverDictNum, motorNum)
# *** Read motor encode value ***
print('Move motor by hand and read encode value every second, ...')
for secondCount in range(100):
encodeValue = readMotorEncodeValue(driverDictNum, motorNum)
print(' motor encode value =', encodeValue)
utime.sleep(1)
return
def testMeasureMotorSpeed01(driverDictNum, motorNum):
# *** Setup Driver ***
setupDriver(driverDictNum)
# *** Move motor forward ***
moveMotorForward(driverDictNum, motorNum)
# *** Measure Motor Speed ***
# *** Start counting 10 revolutions ***
usTicks1 = utime.ticks_us()
# *** Find lapse time of 100 revolutions ***
revCount = 0
while revCount < 10:
if readMotorEncodeValue(driverDictNum, motorNum) == 0:
revCount = revCount + 1
utime.sleep(0.000001)
usTicks2 = utime.ticks_us()
rev10Us = utime.ticks_diff(usTicks2, usTicks1)
revUs = int(rev10Us / 10)
rps = int(1000000 / revUs)
rpmRaw = int(rps * 60)
rpmGear100 = int(rpmRaw / 100)
print('revUs =', revUs)
print('rps =', rps)
print('rpm raw =', rpmRaw)
print('rpm 100 =', rpmGear100)
moveMotorStop(driverDictNum, motorNum)
return
# *** Main Tests ***
# *** Test move motor forward, backward, stop ***
# testMoveMotor01(driverDictNum = 1, motorNum = 1)
# testMoveMotor01(driverDictNum = 1, motorNum = 2)
# *** Test measure motor speed ***
testMeasureMotorSpeed01(driverDictNum = 1, motorNum = 1)
# ***
#moveMotorStop(driverDictNum = 1, motorNum = 1)
# *** End of program ***
# *** Sample Output - tlfong01 2021aug18hkt1120
'''
>>> %Run -c $EDITOR_CONTENT
revUs = 1250
rps = 800
rpm raw = 48000
rpm 100 = 480
>>>
'''
Part 7 - Using PWM to control speed of N20 Motor
Now I have written the following program to test basic PWM functions. I need to use my scope to display the 1kHz, 50% duty cycle waveform, before trying to use this PWM signal to control the speed of the N20 motor.
# *** PWM Functions ***
def setupPwm(motorDriverDictNum, motorNum, pwmFreq, dutyCycle):
motorDriverDict = motorDriverDictDict[str(motorDriverDictNum)]
pwmPinNum = motorDriverDict[str(motorNum)]['PWM']
motorPwm = PWM(Pin(pwmPinNum))
motorPwm.freq(pwmFreq)
motorPwm.duty_u16(int(65536 / 100) * dutyCycle)
print('PWM freq (Hz) =', motorPwm.freq())
print('PWM duty (%) =', int((motorPwm.duty_u16() / 65536) * 100))
print('PWM width (ns) =', motorPwm.duty_ns())
return
# *** Motor Test Functions ***
def testMoveMotor01(motorDriverDictNum, motorNum):
# *** Setup Driver ***
setupMotorDriver(motorDriverDictNum)
# *** Move motor forward ***
moveMotorForward(motorDriverDictNum, motorNum)
utime.sleep(1)
# *** Move motor backward ***
moveMotorBackward(motorDriverDictNum, motorNum)
utime.sleep(1)
# *** Move motor stop ***
moveMotorStop(motorDriverDictNum, motorNum)
return
def testMeasureMotorSpeed01(motorDriverDictNum, motorNum):
measureMotorSpeed(motorDriverDictNum, motorNum)
return
def testSetupMotorPwm01(motorDriverDictNum, motorNum, pwmFreq, dutyCycle):
setupPwm(motorDriverDictNum, motorNum, pwmFreq, dutyCycle)
return
# *** Main Tests ***
# *** Test move motor forward, backward, stop ***
# print('Test Motor #1 Move Forward, Backward, Stop')
# testMoveMotor01(motorDriverDictNum = 1, motorNum = 1)
# print('Test Motor #2 Move Forward, Backward, Stop')
# testMoveMotor01(motorDriverDictNum = 1, motorNum = 2)
# *** Test measure motor speed ***
# print('\nTest Measure Motor #1 Speed')
#testMeasureMotorSpeed01(motorDriverDictNum = 1, motorNum = 1)
# *** Test PWM Funcions ***
print('\nTest PWM Funcions')
testSetupMotorPwm01(motorDriverDictNum = 1, motorNum =1, pwmFreq = 1000, dutyCycle = 50)
# *** End of program ***
# *** Sample Output - tlfong01 2021aug18hkt1120
'''
>>> %Run -c $EDITOR_CONTENT
revUs = 1250
rps = 800
rpm raw = 48000
rpm 100 = 480
>>>
'''
'''
>>> %Run -c $EDITOR_CONTENT
Test PWM Funcions
PWM freq (Hz) = 1000
PWM duty (%) = 49
PWM width (ns) = 499728
>>>
'''
I have modified my old program to use PWM pin to control the speed of the motor (earlier I only used PWM pin as high/low logical signal to turn motor fully on or off. Now I am using PWM 1kHz and duty cycle 0~100% to control speed of motor. I found, as expected, motor moves slowly with duty cycle small and quickly with high duty cycle. However, I found the speed measurement function not reliable, mainly because I use counting 100 logical low level signals/revolutions from encoder, and I did not set the between low levels appropriately. Now I am thinking of using interrupt to detect number of high to low falling edges in a specified time period to calculate the motor speed. This way the measurement of speed should be more accurate.
Anyway, I am listing my old speed measurement program to do interrupt driven method to compare and contrast.
Note - I found that this long post exceeds the forum’s 32k words limit. So I am deleting some functions to fit the bill.
# Program Name
# measure_motor_speed_v16.py - tlfong01 2021aug19hkt1132
# docs and functions deleted
import utime
from machine import Pin, PWM
# *** Configuration ***
motorDriverDict01 = {
'TITLE' : 'TB6612FNG Dual DC Motor Driver Dictionary',
'STANDBY' : 5,
'1': {'IN1': 10, 'IN2': 11, 'PWM' : 3, 'ENCODE': 14},
'2': {'IN1': 12, 'IN2': 13, 'PWM' : 4, 'ENCODE': 15},
'3': {'IN1': 0, 'IN2': 0, 'PWM' : 0, 'ENCODE': 0},
'4': {'IN1': 0, 'IN2': 0, 'PWM' : 0, 'ENCODE': 0},
}
motorDriverDictDict = {
'1': motorDriverDict01,
'2': motorDriverDict01,
}
# *** Read Motor Encoder, Measure Motor Speed ***
def readMotorEncodeValue(motorDriverDictNum, motorNum):
motorControlPinList = setupMotor(motorDriverDictNum, motorNum)
encodeValue = motorControlPinList[3].value()
return encodeValue
def measureMotorSpeed(motorDriverDictNum, motorNum):
# *** Setup Motor Driver ***
setupMotorDriver(motorDriverDictNum)
# *** Move motor forward ***
moveMotorForward(motorDriverDictNum, motorNum)
# *** Measure Motor Speed ***
# *** Start counting 10 revolutions ***
usTicks1 = utime.ticks_us()
# *** Find lapse time of 100 revolutions ***
revCount = 0
while revCount < 10:
if readMotorEncodeValue(motorDriverDictNum, motorNum) == 0:
revCount = revCount + 1
utime.sleep(0.000001)
usTicks2 = utime.ticks_us()
rev10Us = utime.ticks_diff(usTicks2, usTicks1)
revUs = int(rev10Us / 10)
rps = int(1000000 / revUs)
rpmRaw = int(rps * 60)
rpmGear100 = int(rpmRaw / 100)
print(' uS per revolution =', revUs)
print(' rps raw =', rps)
print(' rpm raw =', rpmRaw)
print(' rpm gear 1:100 =', rpmGear100)
return rpmGear100
# *** PWM Functions ***
def setupMotorDriverPwm(motorDriverDictNum):
motorDriverDict = motorDriverDictDict[str(motorDriverDictNum)]
# print(' motDriverDictNum =', motorDriverDictNum)
standBy = Pin(motorDriverDict['STANDBY'], Pin.OUT)
standBy.high()
return
def setupMotorPwm(motorDriverDictNum, motorNum, pwmFreq, dutyCycle):
motorDriverDict = motorDriverDictDict[str(motorDriverDictNum)]
motorIn1Pin = motorDriverDict[str(motorNum)]['IN1']
motorIn2Pin = motorDriverDict[str(motorNum)]['IN2']
motorPwmPin = motorDriverDict[str(motorNum)]['PWM']
# print(' IN1 pinNum =', motorIn1Pin)
# print(' IN2 pinNum =', motorIn2Pin)
# print(' PWM pinNum =', motorPwmPin)
motorIn1 = Pin(motorIn1Pin, Pin.OUT)
motorIn2 = Pin(motorIn2Pin, Pin.OUT)
motorPwm = PWM(Pin(motorDriverDict[str(motorNum)]['PWM']))
motorPwm.freq(pwmFreq)
motorPwm.duty_u16(int(65536 / 100) * dutyCycle)
pwmPinNum = motorDriverDict[str(motorNum)]['PWM']
# print(' Setup PWM')
# print(' PWM freq (Hz) =', motorPwm.freq())
# print(' PWM duty (%) =', int((motorPwm.duty_u16() / 65536) * 100))
# print(' PWM width (ns) =', motorPwm.duty_ns())
motorEncode = Pin(motorDriverDict[str(motorNum)]['ENCODE'], Pin.IN, Pin.PULL_DOWN)
motorControlPinList = [motorIn1, motorIn2, motorPwm, motorEncode]
return motorControlPinList
def moveMotorForwardPwm(motorDriverDictNum, motorNum, pwmFreq, dutyCycle):
motorControlPinList = setupMotorPwm(motorDriverDictNum, motorNum, pwmFreq, dutyCycle)
motorControlPinList[0].low()
motorControlPinList[1].high()
motorControlPinList[2].freq(pwmFreq)
motorControlPinList[2].duty_u16(int(65536 / 100) * dutyCycle)
return
def measureMotorSpeedPwm(motorDriverDictNum, motorNum):
# *** Setup Motor Driver ***
# setupMotorDriver(motorDriverDictNum)
# *** Move motor forward ***
# moveMotorForwardPwm(motorDriverDictNum, motorNum, pwmFreq, dutyCycle)
# *** Measure Motor Speed ***
# *** Start counting 10 revolutions ***
usTicks1 = utime.ticks_us()
# *** Find lapse time of 100 revolutions ***
revCount = 0
while revCount < 10:
if readMotorEncodeValue(motorDriverDictNum, motorNum) == 0:
revCount = revCount + 1
utime.sleep(0.0001) # <<<<<<<<<<<<
usTicks2 = utime.ticks_us()
rev10Us = utime.ticks_diff(usTicks2, usTicks1)
revUs = int(rev10Us / 10)
rps = int(1000000 / revUs)
rpmRaw = int(rps * 60)
rpmGear100 = int(rpmRaw / 100)
# print(' uS per revolution =', revUs)
# print(' rps raw =', rps)
# print(' rpm raw =', rpmRaw)
# print(' rpm gear 1:100 =', rpmGear100)
return rpmGear100
# *** Motor Test Functions ***
def testMoveMotor01(motorDriverDictNum, motorNum):
# *** Setup Driver ***
setupMotorDriver(motorDriverDictNum)
# *** Move motor forward ***
moveMotorForward(motorDriverDictNum, motorNum)
utime.sleep(1)
# *** Move motor backward ***
moveMotorBackward(motorDriverDictNum, motorNum)
utime.sleep(1)
# *** Move motor stop ***
moveMotorStop(motorDriverDictNum, motorNum)
return
def testMeasureMotorSpeed01(motorDriverDictNum, motorNum):
measureMotorSpeed(motorDriverDictNum, motorNum)
return
#def testSetupMotorPwm01(motorDriverDictNum, motorNum, pwmFreq, dutyCycle):
# setupPwm(motorDriverDictNum, motorNum, pwmFreq, dutyCycle)
# return
def testMoveMotorForwardPwm01(motorDriverDictNum, motorNum, pwmFreq, dutyCycle):
setupMotorDriverPwm(motorDriverDictNum)
moveMotorForwardPwm(motorDriverDictNum, motorNum, pwmFreq, dutyCycle)
utime.sleep(4)
moveMotorStop(motorDriverDictNum, motorNum)
return
def testMeasureMotorSpeedPwm01(motorDriverDictNum, motorNum, pwmFreq, dutyCycle):
setupMotorDriverPwm(motorDriverDictNum)
moveMotorForwardPwm(motorDriverDictNum, motorNum, pwmFreq, dutyCycle)
utime.sleep(2)
speedRpmGear = measureMotorSpeedPwm(motorDriverDictNum, motorNum)
print('dutyCycle =', dutyCycle)
print('speed (rpmGear) =', speedRpmGear)
# moveMotorStop(motorDriverDictNum, motorNum)
return
# *** Main Tests ***
# *** Test move motor forward, backward, stop ***
# print('Test Motor #1 Move Forward, Backward, Stop')
# testMoveMotor01(motorDriverDictNum = 1, motorNum = 1)
# print('\nTest Motor #2 Move Forward, Backward, Stop')
# testMoveMotor01(motorDriverDictNum = 1, motorNum = 2)
# *** Test measure motor speed ***
# print('\nTest Measure Motor #1 Speed')
# testMeasureMotorSpeed01(motorDriverDictNum = 1, motorNum = 1)
# *** Test Move Motor / Measure Speed PWM Funcions ***
print('Test Move Motor Forward')
# testMoveMotorForwardPwm01(motorDriverDictNum = 1, motorNum = 1, pwmFreq = 1000, dutyCycle = 100)
# testMoveMotorForwardPwm01(motorDriverDictNum = 1, motorNum = 1, pwmFreq = 1000, dutyCycle = 50)
# testMoveMotorForwardPwm01(motorDriverDictNum = 1, motorNum = 1, pwmFreq = 1000, dutyCycle = 10)
print('Test Measure Motor Speed')
testMeasureMotorSpeedPwm01(motorDriverDictNum = 1, motorNum = 1, pwmFreq = 1000, dutyCycle = 80)
print('Test Measure Motor Speed')
testMeasureMotorSpeedPwm01(motorDriverDictNum = 1, motorNum = 1, pwmFreq = 1000, dutyCycle = 50)
print('Test Measure Motor Speed')
testMeasureMotorSpeedPwm01(motorDriverDictNum = 1, motorNum = 1, pwmFreq = 1000, dutyCycle = 40)
print('Stop Motor')
moveMotorStop(motorDriverDictNum = 1, motorNum = 1)
# *** End of program ***
# *** Sample Output - tlfong01 2021aug18hkt1120
'''
MicroPython v1.16 on 2021-06-18; Raspberry Pi Pico with RP2040
Type "help()" for more information.
>>> %Run -c $EDITOR_CONTENT
Test Move Motor Forward
Test Measure Motor Speed
dutyCycle = 80
speed (rpmGear) = 479
Test Measure Motor Speed
dutyCycle = 50
speed (rpmGear) = 479
Test Measure Motor Speed
dutyCycle = 40
speed (rpmGear) = 524
Stop Motor
>>>
'''
'''
>>> %Run -c $EDITOR_CONTENT
Test PWM Funcions
PWM freq (Hz) = 1000
PWM duty (%) = 49
PWM width (ns) = 499728
>>>
'''
Note - This reply post is getting too long, exceeding the forum’s 32k word limit. So I am breaking up to another reply.
/ to continue, …