Uncategorized

Making a Rpi Pico Based Smart Vehicle

Making a Rpi Pico Based Smart Vehicle

Projects

Jun 2021

27 / 27

Nov 2021

Nov 2021

1 MONTH LATER

16 DAYS LATER

25 DAYS LATER

tlfong01

Nov ’21

BlueTooth UART Modules for Pico Smart 4WD

Now I am adding two BlueTooth UART slave modules to the smart 4WD, so I can use an Android smart phone with built in accelerometer and magnetometer to play with the 2WD through 2.4GHz BlueTooth.


hc02_pico_2021nov17011024×731 276 KB


# *** pico_4wd_v85.py - tlfong01, 2021nov17hkt1937 ***

# Brief Description
# 1. Smart 4WD based on Rpi Pico, TB6612FNG, DC/BLDC motors, 433MHz HC12, 2.6GHz BLE HC02, Androd smart phone with
#    acceleromter and magnetometer

# Contents
# 1. Pico 4WD with TB6612 DC Motor Drivers and gear encoder motors N20, tt130, and TM310
#    1.1 Interrupt functions
#    1.2 DC motor function
# 2. Pico 4Wd with BLDC motors with built motor drivers (ie, TB6612FNG is not required
# 3. HC12 433MHz RF transceivers
#    3.1  uart loop back functions
#    3.2  HC12 transmit/receive echo functions
# 4. HC02 2.6GHz BLE slave modules
# 5. Integrating Parts 1, 2 with Parts 3, 4

# ========= ========= ========= ========= ========= ========= ========= ========= ========= =========
# ========= ========= ========= ========= ========= ========= ========= ========= ========= =========

from machine import Pin, PWM
import utime

# *** Pico GP pin assignments ***

uart0TxDNum  = 0 # HC12 #1 TxD
uart0RdDNum  = 1 # HC12 #2 RxD

hc12Setup1   = 2 # Reserved for SPI0 Sck
hc12Setup2   = 3 # Reserved for SPI0 Tx
i2c0Sda      = 4 # Reserved for SPI0 Rx
i2c0Scl      = 5 # Reserved for SPI0 Csn  

# *** PWM Pins ***

aPwmPinNum0  = 6 #0
bPwmPinNum0  = 7 #1

uart1TxdNum  = 8 # HC12 #2 TxD
uart1RxdNum  = 9 # HC12 #2 RxD

aPwmPinNum1  = 10 #2
bPwmPinNum1  = 11 #3

# *** Inrerrupt Pins ***

intPinNum0 = 12 #4 
intPinNum1 = 13 #5 
intPinNum2 = 14 #6 
intPinNum3 = 15 #7 

# *** Motor Driver Control Pins (TB6612FNG) ***

stdByPinNum0 = 16 #8
stdByPinNum1 = 17 #9

aIn1PinNum0  = 18 #10
aIn2PinNum0  = 19 #11
bIn1PinNum0  = 20 #12
bIn2PinNum0  = 21 #13

aIn1PinNum1  = 22 #14
aIn2PinNum1  = 23 #15
bIn1PinNum1  = 27 #16
bIn2PinNum1  = 28 #17

# *** Interrupt Pin Dicts ***

intGpPinNumDict = {'0': intPinNum0, 
                   '1': intPinNum1, 
                   '2': intPinNum2, 
                   '3': intPinNum3, 
                  }

intPinNumList = [intPinNum0, intPinNum1, intPinNum2, intPinNum3]

# Comments
# 1. There are 4 GP pins to read interrupts: intPinNum0, inPinNum1, intPinNum2, intPinNum3.

# ========= ========= ========= ========= ========= ========= ========= ========= ========= =========
# ========= ========= ========= ========= ========= ========= ========= ========= ========= =========

# *** Sleep time dicts ***

secondsDict = {'OneSecond'    :   1,
               'TwoSeconds'   :   2,
               'FourSeconds'  :   4,
               'TenSeconds'   :  10,               
               'SixtySeconds' :  60,
               'ThreeMinutes' : 180,
              }

def hold(secondsName):
    utime.sleep(secondsDict[secondsName])
    return

# Comments
# 1. Hold function is friendly version of utime.sleep.

# ========= ========= ========= ========= ========= ========= ========= ========= ========= =========
# ========= ========= ========= ========= ========= ========= ========= ========= ========= =========

# *** Interrupt global variables and dicts ***

global intCount0 
global intCount1
global intCount2
global intCount3

intCount0 = 0
intCount1 = 0
intCount2 = 0
intCount3 = 0

intCountDict = {
    '0': intCount0,
    '1': intCount1,
    '2': intCount2,
    '3': intCount3,
    }

# Comments
# 1. There are four global variable to hold interrupt event counts.
# 2. For this 4WD, the four interrupt signals are the four motor's rotary encoder output signals.
    
# *** Interrupt Callback Functions ***   

def intCallBack0(pin):
    global intCount0
    intCount0 = intCount0 + 1    
    return

def intCallBack1(pin):
    global intCount1
    intCount1 = intCount1 + 1    
    return

def intCallBack2(pin):
    global intCount2
    intCount2 = intCount2 + 1    
    return

def intCallBack3(pin):
    global intCount3
    intCount3 = intCount3 + 1    
    return

intCallBackDict = {
    '0': intCallBack0,
    '1': intCallBack1,
    '2': intCallBack2,
    '3': intCallBack3,    
    }

def countIntPinIntPeriod(intPinNum, countPeriod):
    global intCount0
    global intCount1
    global intCount2
    global intCount3
    
    intCount0 = 0
    intCount1 = 0
    intCount2 = 0
    intCount3 = 0

    utime.sleep(countPeriod)
 
    if intPinNum  == 0:
        intCount = intCount0
    elif intPinNum == 1:    
        intCount = intCount1
    elif intPinNum == 2:    
        intCount = intCount2
    else:    
        intCount = intCount3                
    return intCount

def countIntPinNumListIntPeriod(intPinNumList, countPeriod):
    intCountList = [0] * len(intPinNumList)
    for index in range(len(intPinNumList)):
        intCountList[index] = countIntPinIntPeriod(intPinNumList[index], countPeriod)                       
    return intCountList

# Comments
# 1. countIntPinIntPeriod(intPinNum, countPeriod) is to count the number of interrupts at the interrupt pin denoted by the
#      interrupt pin number.

# *** Test functions ***

def repeatCountIntPinNumListIntPeriod(intPinNumList, countPeriod, pauseTime, repeatTimes):
    print('\n  countIntPinNumListIntPeriod()')
    intGpPinNumList = [0] * len(intPinNumList)
    for index in range(len(intGpPinNumList)):
        intGpPinNumList[index]     = intGpPinNumDict[str(index)]
    print('    intPinNumList           =', intPinNumList)
    print('    intGpPinNumList         =', intGpPinNumList)
    print('    countPeriod (seconds)   =', countPeriod)
    print('    pauseTime (seconds)     =', pauseTime)    
    print('    repeat count times      =', repeatTimes)
    print('')
    
    for count in range(repeatTimes):
        ppsList             = countIntPinNumListIntPeriod(intPinNumList, countPeriod)
        print('    countList =', ppsList, end = '')
        print(' , min ', min(ppsList), end = '')
        print(' , max ', max(ppsList), end = '')
        print(' , dif ', max(ppsList) - min(ppsList), end = '')
        print(' , avg ', int(sum(ppsList) / len(ppsList)))      
        utime.sleep(pauseTime)    
    return

# Comments
# 1. repeatCountIntPinNumListIntPeriod(intPinNumList, countPeriod, pauseTime, repeatTimes)
#      repeatedly counts and prints tinterrupt events in countPeriod and p

# ========= ========= ========= ========= ========= ========= ========= ========= ========= =========
# ========= ========= ========= ========= ========= ========= ========= ========= ========= =========

# *** Part 3 - TB6612FNG Motor Driver Functions ***

# Comments
# 1. This 4WD uses two TB6612FNG DC motor drivers, each with two driver channels, with a total of 4 channels for four motors.
# 2. BLDC motor have built in motor drivers, therefor is not handled by TB6612 motor driver.

defaultPwmFreq   = 1000
defaultDutyCycle = 90

dutyCycleDict = {
    'VeryVerySlow' : 95,
    'VeryFast'     : 90,
    'Fast'         : 80,
    'Normal'       : 50,
    'Slow'         : 40,
    'VerySlow'     : 30,
    'VeryVerySlow' : 25,
    }


'''
motorConfigDict00 = {'MotorDriverNum': 0, 'ChannelNum': 0}
motorConfigDict01 = {'MotorDriverNum': 0, 'ChannelNum': 1}
motorConfigDict10 = {'MotorDriverNum': 1, 'ChannelNum': 0}
motorConfigDict11 = {'MotorDriverNum': 1, 'ChannelNum': 1}

motorConfigDictList_00_01_10_11 = [motorConfigDict00, motorConfigDict01, motorConfigDict10, motorConfigDict11]
motorConfigDictList01 = motorConfigDictList_00_01_10_11

motorConfigDictListDict = {'FourMotorsList' : motorConfigDictList01,
                }
'''

motorConfigDictDict = \
    {
        '0': {'MotorDriverNum': 0, 'ChannelNum': 0},
        '1': {'MotorDriverNum': 0, 'ChannelNum': 1},
        '2': {'MotorDriverNum': 1, 'ChannelNum': 0},
        '3': {'MotorDriverNum': 1, 'ChannelNum': 1},        
    }



# Comment
# 1. There are four DC motors, each denoted/represented by a Motor Config Dictionary.
# 2. A motor config dict has two elementa:
#      (a) MotorDriverNum which the the number of one of the two TB6612FNG motor drivers.
#      (b) Channel Number, denoting each of the two channel of the motor driver.
# 3. motorConfigDictList01 = motorConfigDictList_00_01_10_11 = the list of all four motor confict dictionaries.
# 4. motorConfigDictListDict is the Dict of motorConfigDictLists (only one such dict list for now)

motorDriverGpPinNumDict = { \
    '0': {'StdByPinNum'  : stdByPinNum0,             
          '0' : {'In1PinNum'      : aIn1PinNum0,  
                 'In2PinNum'      : aIn2PinNum0,  
                 'PwmPinNum'      : aPwmPinNum0,
                 'PwmFreq'        : defaultPwmFreq,
                 'DutyCycle'      : defaultDutyCycle,
                 'IntPinNum'      : intPinNum0,
                 'IntPinCallBack' : intCallBack0,                 
                },
          '1' : {'In1PinNum'      : bIn1PinNum0,  
                 'In2PinNum'      : bIn2PinNum0,  
                 'PwmPinNum'      : bPwmPinNum0,
                 'PwmFreq'        : defaultPwmFreq,
                 'DutyCycle'      : defaultDutyCycle,
                 'IntPinNum'      : intPinNum1,
                 'IntPinCallBack' : intCallBack1,                  
                },  
          },                   
    '1': {'StdByPinNum'  : stdByPinNum1,             
          '0' : {'In1PinNum'      : aIn1PinNum1,  
                 'In2PinNum'      : aIn2PinNum1,  
                 'PwmPinNum'      : aPwmPinNum1,
                 'PwmFreq'        : defaultPwmFreq,
                 'DutyCycle'      : defaultDutyCycle,
                 'IntPinNum'      : intPinNum2,
                 'IntPinCallBack' : intCallBack2,                  
                },
          '1' : {'In1PinNum'      : bIn1PinNum1,  
                 'In2PinNum'      : bIn2PinNum1,  
                 'PwmPinNum'      : bPwmPinNum1,
                 'PwmFreq'        : defaultPwmFreq,
                 'DutyCycle'      : defaultDutyCycle,
                 'IntPinNum'      : intPinNum3,
                 'IntPinCallBack' : intCallBack3                  
                },  
          }, 
    }

# Comment
# 1. motorDriverGpPinNumDict specifies
#    (a) the GP pin numbers for the two TB6612FNG motor drivers ecah with two channels.
#    (b) the default values such as PWM frequency, duty cycles

def setupMotorOld(motorConfigDict):
    motorDriverNum = motorConfigDict['MotorDriverNum']
    channelNum     = motorConfigDict['ChannelNum']
    
    stdByPinNum    = motorDriverGpPinNumDict[str(motorDriverNum)]['StdByPinNum']
    in1PinNum      = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['In1PinNum']
    in2PinNum      = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['In2PinNum']
    
    pwmPinNum      = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['PwmPinNum']
    pwmFreq        = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['PwmFreq']    
    dutyCycle      = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['DutyCycle']     
    
    intPinNum      = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['IntPinNum']
    intPinCallBack = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['IntPinCallBack']

    # *** Motor Driver Control Pin Setup ***    
    
    stdByPin    = Pin(stdByPinNum, Pin.OUT)
    in1Pin      = Pin(in1PinNum, Pin.OUT)    
    in2Pin      = Pin(in2PinNum, Pin.OUT)
    intPin      = Pin(intPinNum, Pin.IN, Pin.PULL_DOWN)
  
    stdByPin.high()
    in1Pin.low()
    in2Pin.high()

    # *** PWM Pin Setup ***      
    
    pwmPin      = PWM(Pin(pwmPinNum))
    pwmPin.freq(pwmFreq)
    u16DutyCycle = int((dutyCycle / 100) * 65536)  
    pwmPin.duty_u16(u16DutyCycle)
    
    # *** Interrupt Pin Setup ***
    
    intPin.irq(intPinCallBack, Pin.IRQ_FALLING)
    
    # *** Motor Control Dict ***
    
    motorControlDict = {'StdByPin': stdByPin,
                        'In1Pin'  : in1Pin,
                        'In2Pin'  : in2Pin,
                        'PwmPin'  : pwmPin,
                        'IntPin'  : intPin,
                       }
    return motorControlDict

def setupMotor(motorNum):
    motorConfigDict = motorConfigDictDict[str(motorNum)]
    motorDriverNum  = motorConfigDict['MotorDriverNum']
    channelNum      = motorConfigDict['ChannelNum']
    
    stdByPinNum     = motorDriverGpPinNumDict[str(motorDriverNum)]['StdByPinNum']
    in1PinNum       = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['In1PinNum']
    in2PinNum       = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['In2PinNum']
    
    pwmPinNum       = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['PwmPinNum']
    pwmFreq         = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['PwmFreq']    
    dutyCycle       = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['DutyCycle']     
    
    intPinNum       = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['IntPinNum']
    intPinCallBack  = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['IntPinCallBack']

    # *** Motor Driver Control Pin Setup ***    
    
    stdByPin    = Pin(stdByPinNum, Pin.OUT)
    in1Pin      = Pin(in1PinNum, Pin.OUT)    
    in2Pin      = Pin(in2PinNum, Pin.OUT)
    intPin      = Pin(intPinNum, Pin.IN, Pin.PULL_DOWN)
  
    stdByPin.high()
    in1Pin.low()
    in2Pin.high()

    # *** PWM Pin Setup ***      
    
    pwmPin      = PWM(Pin(pwmPinNum))
    pwmPin.freq(pwmFreq)
    u16DutyCycle = int((dutyCycle / 100) * 65536)  
    pwmPin.duty_u16(u16DutyCycle)
    
    # *** Interrupt Pin Setup ***
    
    intPin.irq(intPinCallBack, Pin.IRQ_FALLING)
    
    # *** Motor Control Dict ***
    
    motorControlDict = {'StdByPin': stdByPin,
                        'In1Pin'  : in1Pin,
                        'In2Pin'  : in2Pin,
                        'PwmPin'  : pwmPin,
                        'IntPin'  : intPin,
                       }
    return motorControlDict

# Comments
# 1. setupMotor(motorNum) perfroms the following things:
#    1.1 setup and intiralize control/pwm/interrupt pin objects from controlPinNum controlPin objects
#    1.2 setup interrupt call back functions
#    1.3 returns motorControlDict which is a dictionary of the motor's pin objects (stdBy, Input, Pwm, Interrupt)

def setupMotorList(motorNumList):
    motorControlDictList = [0] * len(motorNumList)        
    for motorNum in motorNumList:
        motorControlDict = setupMotor(motorNum)
        motorControlDictList[motorNum] = motorControlDict
    return motorControlDictList

def moveMotorDirection(motorControlDict, directionName):
    if directionName =='Forward':
        motorControlDict['In1Pin'].low()
        motorControlDict['In2Pin'].high()
    elif directionName == 'Backward':
        motorControlDict['In1Pin'].high()
        motorControlDict['In2Pin'].low()       
    return
    
def moveMotorSpeed(motorControlDict, speedName):
    pwmPin = motorControlDict['PwmPin']
    dutyCycle = dutyCycleDict[speedName]
    pwmPin.duty_u16(int((dutyCycle / 100) * 65536) )
    return

def moveMotorDirectionSpeed(motorControlDict, directionName, speedName):      
    moveMotorDirection(motorControlDict, directionName)
    moveMotorSpeed(motorControlDict, speedName)
    return

def moveMotorDirectionSpeedList(motorControlDictList, directionName, speedName):
    for motorControlDict in motorControlDictList:
        moveMotorDirectionSpeed(motorControlDict, directionName, speedName)
    return

def stopMotor(motorControlDict):  
    motorControlDict['In1Pin'].low()
    motorControlDict['In2Pin'].low()
    return

def stopMotorList(motorControlDictList):
    for motorControlDict in motorControlDictList:
        stopMotor(motorControlDict)
    return

# *** Test functions ***

def testSetupMoveMotorDirectionSpeedList(motorNumList, directionName, speedName, secondsName):
    print('Begin testSetupMoveMotorList(), ...')  
    motorControlDictList = setupMotorList(motorNumList)
    moveMotorDirectionSpeedList(motorControlDictList, directionName, speedName) # move motor list driection and speed
    utime.sleep(2)
    print('After 2 seconds, ...')  
    repeatCountIntPinNumListIntPeriod(intPinNumList = [0, 1, 2, 3], countPeriod = 0.1, pauseTime = 0.1, repeatTimes = 10)    
    utime.sleep(1)       
    stopMotorList(motorControlDictList)
    print('End   testSetupMoveMotorList(), ...')    
    return

# *** Sample test functions calls ***
#testSetupMoveMotorDirectionSpeedList([0, 1, 2, 3], 'Forward',  'VerySlow', 'FourSeconds')
#testSetupMoveMotorDirectionSpeedList([0, 1, 2, 3], 'Backward', 'VeryFast', 'FourSeconds')
#testSetupMoveMotorDirectionSpeedList([0, 1, 2, 3], 'Forward',  'Normal',   'TwoSeconds')
#testSetupMoveMotorDirectionSpeedList([0, 1, 2, 3], 'Forward',  'Normal',   'SixtySeconds')
#testSetupMoveMotorDirectionSpeedList([0, 1, 2, 3], 'Forward',  'Normal',   'ThreeMinutes')
#testSetupMoveMotorDirectionSpeedList([0, 1, 2, 3], 'Forward',  'VerySlow', 'TenSeconds')
#testSetupMoveMotorDirectionSpeedList([0, 1, 2, 3], 'Forward',  'Normal',   'FourSeconds')

# ========= ========= ========= ========= ========= ========= ========= ========= 
# ========= ========= ========= ========= ========= ========= ========= =========

'''
# *** BLDC Config/Fuctnions ***

dutyCycleDictBldc = {
    'VeryVerySlow' : 95,
    'VeryFast'     : 90,
    'Fast'         : 80,
    'Normal'       : 50,
    'Slow'         : 40,
    'VerySlow'     : 30,
    'VeryVerySlow' : 25,
    }

def changeBldcMotorSpeed(motorControlDict, speedName):
    pwmPin = motorControlDict['PwmPin']
    dutyCycle = dutyCycleDict[speedName]
    pwmPin.duty_u16(int((dutyCycle / 100) * 65536) )
    return

def setupBldcMotor(motorConfigDict):
    motorDriverNum = motorConfigDict['MotorDriverNum']
    channelNum     = motorConfigDict['ChannelNum']
    
    stdByPinNum    = motorDriverGpPinNumDict[str(motorDriverNum)]['StdByPinNum']
    in1PinNum      = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['In1PinNum']
    in2PinNum      = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['In2PinNum']
    
    pwmPinNum      = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['PwmPinNum']
    pwmFreq        = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['PwmFreq']    
    dutyCycle      = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['DutyCycle']     
    
    intPinNum      = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['IntPinNum']
    intPinCallBack = motorDriverGpPinNumDict[str(motorDriverNum)][str(channelNum)]['IntPinCallBack']

    # *** Motor Driver Control Pin Setup ***    
    
    stdByPin    = Pin(stdByPinNum, Pin.OUT)
    in1Pin      = Pin(in1PinNum, Pin.OUT)    
    in2Pin      = Pin(in2PinNum, Pin.OUT)
    intPin      = Pin(intPinNum, Pin.IN, Pin.PULL_DOWN)
  
    stdByPin.high()
    in1Pin.low()
    in2Pin.high()

    # *** PWM Pin Setup ***      
    
    pwmPin      = PWM(Pin(pwmPinNum))
    pwmPin.freq(pwmFreq)
    u16DutyCycle = int((dutyCycle / 100) * 65536)  
    pwmPin.duty_u16(u16DutyCycle)
    
    # *** Interrupt Pin Setup ***
    
    intPin.irq(intPinCallBack, Pin.IRQ_FALLING)
    
    # *** Motor Control Dict ***
    
    motorControlDictBldc = {'StdByPin': stdByPin,
                            'In1Pin'  : in1Pin,
                            'In2Pin'  : in2Pin,
                            'PwmPin'  : pwmPin,
                            'IntPin'  : intPin,
                           }
# Test functions 

def testBldcMotor00():
    print('  Begin testBldcMotor00(), ...')
    motorConfigDict = {'MotorDriverNum': 0, 'ChannelNum': 0}
    setupBldcMotor(motorConfigDict)
    
    hold('TwoSeconds')
    changeBldcMotorSpeed(motorConfigDict, 'VeryFast')
    hold('TwoSeconds')
    utime.sleep(2)
    changeBldcMotorDirection(motorConfigDict, 'CCW')    
    utime.sleep(2)
    changeBldcMotorDirection(motorConfigDict, 'CW') 
    changeBldcMotorSpeed(motorConfigDict, 'VerySlow')
    utime.sleep(2)
    
    print('  End   testSetupMotor00(), ...')
    return

# *** Sample test function call

#testBldcMotor00()

'''
# ========= ========= ========= ========= ========= ========= ========= ========= ========= =========
# ========= ========= ========= ========= ========= ========= ========= ========= ========= =========

''' Old main test sample outputs

*** Sample Output  tlfong01  2021oct11hkt1955 ***
>>> %Run -c $EDITOR_CONTENT
Begin testSetupMoveMotorList(), ...
After 2 seconds, ...

  countIntPinNumListIntPeriod()
    intPinNumList           = [0, 1, 2, 3]
    intGpPinNumList         = [4, 5, 6, 7]
    countPeriod (seconds)   = 0.1
    pauseTime (seconds)     = 0.1
    repeat count times      = 10

    countList = [296, 219, 291, 205] , min  205 , max  296 , dif  91 , avg  252
    countList = [286, 215, 295, 208] , min  208 , max  295 , dif  87 , avg  251
    countList = [288, 217, 300, 213] , min  213 , max  300 , dif  87 , avg  254
    countList = [301, 223, 298, 207] , min  207 , max  301 , dif  94 , avg  257
    countList = [271, 223, 308, 207] , min  207 , max  308 , dif  101 , avg  252
    countList = [287, 223, 305, 203] , min  203 , max  305 , dif  102 , avg  254
    countList = [277, 233, 306, 226] , min  226 , max  306 , dif  80 , avg  260
    countList = [282, 240, 299, 222] , min  222 , max  299 , dif  77 , avg  260
    countList = [294, 225, 307, 209] , min  209 , max  307 , dif  98 , avg  258
    countList = [299, 223, 303, 229] , min  223 , max  303 , dif  80 , avg  263
End   testSetupMoveMotorList(), ...
>>> 
'''

# *** Main Test ***

# ========= ========= ========= ========= ========= ========= ========= ========= 
# ========= ========= ========= ========= ========= ========= ========= =========

# *** Main ***

print('Begin setupMotor(), ...  tlfong01 2021nov1701')
testSetupMoveMotorDirectionSpeedList([0, 1, 2, 3], 'Forward',  'Normal', 'TwoSeconds')
print('End   setupMotor(), ...')

# *** End ***

''' Sample output  tlfong01  2021nov17hkt2033
>>> %Run -c $EDITOR_CONTENT
Begin setupMotor(), ...  tlfong01 2021nov1701
Begin testSetupMoveMotorList(), ...
After 2 seconds, ...

  countIntPinNumListIntPeriod()
    intPinNumList           = [0, 1, 2, 3]
    intGpPinNumList         = [12, 13, 14, 15]
    countPeriod (seconds)   = 0.1
    pauseTime (seconds)     = 0.1
    repeat count times      = 10

    countList = [0, 0, 0, 0] , min  0 , max  0 , dif  0 , avg  0
    countList = [0, 0, 0, 0] , min  0 , max  0 , dif  0 , avg  0
    countList = [0, 0, 0, 0] , min  0 , max  0 , dif  0 , avg  0
    countList = [0, 0, 0, 0] , min  0 , max  0 , dif  0 , avg  0
    countList = [0, 0, 0, 0] , min  0 , max  0 , dif  0 , avg  0
    countList = [0, 0, 0, 0] , min  0 , max  0 , dif  0 , avg  0
    countList = [0, 0, 0, 0] , min  0 , max  0 , dif  0 , avg  0
    countList = [0, 0, 0, 0] , min  0 , max  0 , dif  0 , avg  0
    countList = [0, 0, 0, 0] , min  0 , max  0 , dif  0 , avg  0
    countList = [0, 0, 0, 0] , min  0 , max  0 , dif  0 , avg  0
End   testSetupMoveMotorList(), ...
End   setupMotor(), ...
>>>
'''


HC12 References

HC-02 bluetooth serial port uart 3.3v TTL Datasheet

http://www.hc01.com/downloads/HC-02%20english%20datasheet.pdf


hc02_2021nov17011024×453 86.6 KB

hc02_2021nov17031024×356 71.2 KB


Edge Impulse and TinyML References

Build TinyML Models Using Your Mobile Phone TINYML – Jan Jongboom 2020apr11
edgeimpulse.com – 10 Apr 20

Build TinyML Models Using Your Mobile Phone

We already have a very capable device with multiple high-quality sensors in our pockets, and it’s the perfect device to build your first TinyML model.

Machine Learning Using Your Mobile Phone with Edge Impulse – 2020apr03

Machine Learning Using Your Mobile Phone with Edge Impulse

What Is Edge Impulse and tinyML? – 2020nov20

What Is Edge Impulse and tinyML?

Top 5 Projects on Raspberry Pi Pico – Abhishek Jadhav 2021nov16
electromaker.io

Top 5 Raspberry Pi Pico Projects

In this article, we will be looking at the top 5 projects on Raspberry Pi Pico.

Pico Motor Driver
Kitronik Ltd

Kitronik Motor Driver Board for Raspberry Pi Pico

Make the Raspberry Pi Pico the core of your new buggy project with the Kitronik Motor Driver Board for RPi Pico. It allows the RPi Pico to drive two motors simultaneously with forward, reverse & stop control, making it ideal for designs such as…

Price: GBP 9.00


Kitronix Zoom Tech Talks – Motor Driver/Robotics Board For Raspberry Pi Pico – 2021may14

Tech Talks – Motor Driver/Robotics Board For Raspberry Pi Pico


Now I am looking into TinyML. I have almost made up my mind to try it on my Pico 4WD.

Why TinyML Is Such A Big Deal – Bryon Moyer 2021sep02
Semiconductor Engineering – 2 Sep 21

Why TinyML Is Such A Big Deal

Surprisingly, not everything requires lots of compute power to make important decisions.

Est. reading time: 17 minutes

About tinyML
tinyml.org

Home | tinyML Foundation

TinyML Summit. The topic is advances in ultra-low power Machine Learning technologies and applications.

tinyML Vision Challenge – Winners October 08, 2021
tinyml.org

tinyML Vision Challenge – Winners | tinyML Foundation

TinyML Summit. The topic is advances in ultra-low power Machine Learning technologies and applications.


The Ultimate pi-top Holiday Gift Guide

https://www.pi-top.com/diypromo?hsCtaTracking=6c196cb8-ea4c-4eab-8683-edcff62b4c19|41e68e3b-99a6-4bdf-b312-84d3d2ad56f3


Pico Smart 4WD Part 2

My part 1 project blog is getting too long for the forum’s editor to handle, so the response time is now unbearingly long. So I need to end this TLDR part 1 and start Part 2.

Update 2021nov23hkt1219 – I opened the project’s Part 2 as a new topic but found the forum’s editor is also very long. So I am using offline Penzu editing to save time and space.

/ to continue in Part 2, …ReplyShareBookmarkFlagReply

Watching

You will receive notifications because you created this topic.

Suggested Topics

Categories: Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.