Uncategorized

Making a Rpi Pico Based Smart Vehicle – Part 2

Making a Rpi Pico Based Smart Vehicle – Part 2

Projects

Nov 2021

1 / 7

Nov 2021

8h ago

tlfong01

Nov ’21

Introduction

This is Part 2 of the Project with the same title.


smart_pico_4wd_2021nov19021654×858 341 KB


Summary of Part 1

Part 1 microPython program now has 4 python modules:

  1. Pico system Uart
  2. HC12 RF xmit/recv
  3. TB6612FNG 4WD motor driving
  4. Pico system interrupt

# *** pico_4wd_v90.py - tlfong01, 2021nov19hkt1719 ***

# 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  = 11 #2
bPwmPinNum1  = 10 #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  = 27 #14
aIn2PinNum1  = 28 #15
bIn1PinNum1  = 22 #16
bIn2PinNum1  = 26 #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.

defaultDirection = 'Forward'
defaultSpeed     = 'VertHighSpeed'
defaultPwmFreq   = 1000
defaultDutyCycle = 90

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

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 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.low()

    # *** 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,
                       }
    
    motorStatusDict = {'Direction'   : defaultDirection,
                       'Speed'       : defaultSpeed,
                       'PwmFrequency': defaultPwmFreq,
                       'DutyCycle'   : defaultDutyCycle,
                      }                       

    motorDict = {'MotorConfictDict' : motorConfigDict,
                 'MotorControlDict' : motorControlDict,
                 'MotorStatusDict'  : motorStatusDict
                }    

    return motorDict

# 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 setupMotorDirection(motorControlDict, directionName):
    if directionName =='Forward':
        motorControlDict['In1Pin'].low()
        motorControlDict['In2Pin'].high()
    elif directionName == 'Backward':
        motorControlDict['In1Pin'].high()
        motorControlDict['In2Pin'].low()       
    return
    
def setupMotorSpeed(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 moveMotorForward(motorControlDict):  
    motorControlDict['In1Pin'].high()
    motorControlDict['In2Pin'].low()
    return

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

# *** Test setup/stop/move motor functions ***

def testSetupMotor(motorNum):
    print('Begin testSetupMotor(), ', 'motorNum =', motorNum)
    motorControlDict = setupMotor(motorNum)['MotorControlDict']
    stopMotor(motorControlDict)
    print('End   testSetupMotor().')
    return

def testSetupMotorList(motorNumList):
    for motorNum in motorNumList:
        testSetupMotor(motorNum)
    return

def testSetupMoveMotor(motorNum, directionName, speedName, holdSecondsName):
    print('Begiun testSetupMoveMotor(), ', 'motorNum =', motorNum)
    motorDict = setupMotor(motorNum)
    motorControlDict = motorDict['MotorControlDict']
    stopMotor(motorControlDict)
    setupMotorDirection(motorControlDict, directionName)
    setupMotorSpeed(motorControlDict, speedName)    
    hold(holdSecondsName)
    stopMotor(motorControlDict)
    print('End   testSetupMoveMotor().')    
    return

def testSetupMoveMotorList(motorNumList, directionName, speedName, holdSecondsName):
    print('Begiun testSetupMoveMotorNumList(), ...')
    for motorNum in motorNumList:
        motorDict = setupMotor(motorNum)
        motorControlDict = motorDict['MotorControlDict']
        stopMotor(motorControlDict)
        setupMotorDirection(motorControlDict, directionName)
        setupMotorSpeed(motorControlDict, speedName)    
        hold(holdSecondsName)
        stopMotor(motorControlDict)
    print('End   testSetupMoveMotorNumList().')    
    return

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

'''
# *** 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 ***

#testSetupMotor(motorNum = 0)
#testSetupMotorList(motorNumList = [0, 1, 2, 3])

#testSetupMoveMotor(motorNum = 0, directionName = 'Forward', speedName = 'VeryFast', holdSecondsName = 'TwoSeconds')
#testSetupMoveMotor(motorNum = 1, directionName = 'Forward', speedName = 'VeryFast', holdSecondsName = 'TwoSeconds')
#testSetupMoveMotor(motorNum = 2, directionName = 'Forward', speedName = 'VeryFast', holdSecondsName = 'TwoSeconds')
#testSetupMoveMotor(motorNum = 3, directionName = 'Forward', speedName = 'VeryFast', holdSecondsName = 'TwoSeconds')

testSetupMoveMotorList([0, 1, 2, 3], 'Forward', 'VeryFast', 'TwoSeconds')

# *** End ***

'''
>>> %Run -c $EDITOR_CONTENT
Begiun testSetupMoveMotorNumList(), ...
End   testSetupMoveMotorNumList().
>>>
'''

''' 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(), ...
>>>
'''


/ to continue, …Reply

  • createdNov ’21
  • last reply8h
  • 6replies
  • 357views
  • 1user
  • 3links
  • 7

tlfong01

Nov ’21

Now Testing Driving 4 wheels and RF transmission at the same time.

testSetupMoveMotorListSequential([frontLeftWheel, frontRightWheel, rearLeftWheel, rearRightWheel], 'Forward', 'VeryFast', 'TwoSeconds')
testSetupMoveMotorListConcurrent([frontLeftWheel, frontRightWheel, rearLeftWheel, rearRightWheel], 'Backward', 'VerySlow', 'FourSeconds')


pico 4wd test 2021nov2001


# *** pico_4wd_v95.py - tlfong01, 2021nov20hkt1516 ***

from machine import Pin, PWM, UART
import utime

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

# *** UART GP pin assignment and setup/configuration ***

uart0 = UART(0, baudrate = 9600, tx=Pin(0), rx=Pin(1))
uart1 = UART(1, baudrate = 9600, tx=Pin(8), rx=Pin(9))

uartPortDict = \
    {
     '0': uart0,
     '1': uart1,
    }

# HC12 GP pin assignment and setup/configuration ***

hc12SetupPinNum0 = 2
hc12SetupPinNum1 = 3

hc12SetupPin0 = Pin(hc12SetupPinNum0, Pin.OUT) 
hc12SetupPin1 = Pin(hc12SetupPinNum1, Pin.OUT)

hc12SetupPinDict = \
    {
        '0': hc12SetupPin0,
        '1': hc12SetupPin1,
    }

hc12ConfigParameterDict = \
    {
        'CheckAtReply'           : 'AT',
        'CheckAllConfigSetting'  : 'AT+RX',
        'SetChannel#1'           : 'AT+C001',
        'SetChannel#2'           : 'AT+C002',        
    }

hc12TextMsgDict = \
    {
        'HelloWorld'             : 'Hello World',
        'HelloPico0'             : 'Hello Pico #0',
        'HelloPico1'             : 'Hello Pico #1',
        'MoveForward'            : 'Move Forward',
        'MoveBackward'           : 'Move Backward',
        'Stop'                   : 'Stop'
    }

# *** Uart Functions ***

def uartWrite(uartPortNum, writeBytes):
    uartPort = uartPortDict[str(uartPortNum)]
    uartPort.write(writeBytes)
    return 

def uartRead(uartPortNum):
    uartPort = uartPortDict[str(uartPortNum)]
    uartAny = uartPort.any()
    print('    uartAny   =', uartAny)
    readBytes = uartPort.read()
    return readBytes

# *** test uart loopback functions ***

def testUartLoopBack(uartPortNum, writeBytes):
    print('    Begin testUartLoopBack(), ...')
    print('      uartPortNum        =', uartPortNum)       
    
    uartWrite(uartPortNum, writeBytes)
    print('        writeBytes       =', writeBytes)    
     
    utime.sleep(0.5)
    
    readBytes = uartRead(uartPortNum)     
    print('        readBytes        =', readBytes)
    
    print('    End   testUartLoopBack().')
    return

# *** UARTTest Functions ***

#testUartLoopBack(uartPortNum = 0, writeBytes = 'uart0 Hello World')
#testUartLoopBack(uartPortNum = 1, writeBytes = 'uart1 Hello World')

# *** Sample output ***
'''
>>> %Run -c $EDITOR_CONTENT
    Begin testUartLoopBack(), ...
      uartPortNum        = 0
        writeBytes       = uart0 Hello World
    uartAny   = 17
        readBytes        = b'uart0 Hello World'
    End   testUartLoopBack().
    Begin testUartLoopBack(), ...
      uartPortNum        = 1
        writeBytes       = uart1 Hello World
    uartAny   = 17
        readBytes        = b'uart1 Hello World'
    End   testUartLoopBack().
>>>
'''

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

hc12UartPortNumDict = \
           {
             '0': 0,
             '1': 1,
           }            

# *** HC12 Functions ***

def setHc12ConfigMode(hc12Num):
    uartPortNum = hc12UartPortNumDict[str(hc12Num)]
    hc12SetupPin = hc12SetupPinDict[str(uartPortNum)]
    hc12SetupPin.low()
    return

def setHc12CommMode(hc12Num):
    uartPortNum = hc12UartPortNumDict[str(hc12Num)]    
    hc12SetupPin = hc12SetupPinDict[str(uartPortNum)]
    hc12SetupPin.high()
    return

# *** HC12 Test Functions ***

def testHc12Config(hc12Num, writeBytes):
    print('Begin testHc12Config(), ...')
    uartPortNum = hc12UartPortNumDict[str(hc12Num)]
    setHc12ConfigMode(uartPortNum)
    utime.sleep(0.1)  
    testUartLoopBack(uartPortNum, writeBytes)
    print('End   testHc12Config(), ...')     
    return

# *** Sample Tests ***
#testHc12Config(hc12Num = 0, writeBytes = 'AT')
#testHc12Config(hc12Num = 1, writeBytes = 'AT')

''' *** Sample output ***
>>> %Run -c $EDITOR_CONTENT
Begin testHc12Config(), ...
    Begin testUartLoopBack(), ...
      uartPortNum        = 0
        writeBytes       = AT
    uartAny   = 4
        readBytes        = b'OK\r\n'
    End   testUartLoopBack().
End   testHc12Config(), ...
Begin testHc12Config(), ...
    Begin testUartLoopBack(), ...
      uartPortNum        = 1
        writeBytes       = AT
    uartAny   = 4
        readBytes        = b'OK\r\n'
    End   testUartLoopBack().
End   testHc12Config(), ...
>>> 
'''

def testHc12Communication(xmitUartPortNum, recvUartPortNum, testXmitMsg):
    print('Begin testHc12Communication(), ...')

    # *** Set both HC12 communication mode, ...')
    print('  Begin set both HC12s communication mode, ...')
    setHc12CommMode(xmitUartPortNum)
    setHc12CommMode(recvUartPortNum)
    print('  End   set both HC12s communication mode.')
    
    print('  Begin transmit message, ...')
    print('    xmitBytes =', testXmitMsg)
    uartWrite(xmitUartPortNum, testXmitMsg)    
    print('  End transmit message.')        
    
    # *** uart1 recv test message ***
    print('  Begin receive message, ...')
    utime.sleep(0.1)    
    recvBytes = uartRead(recvUartPortNum)
    print('    recvBytes =', recvBytes)
    print('  End   receive msaages.')
    print('End   testHc12Communication(), ...')     
    return

# *** Sample Tests ***

#testHc12Communication(xmitUartPortNum = 0, recvUartPortNum = 1, \
#    testXmitMsg = 'Pico #1 at COM 11, uart0 transmitting, ...')

''' *** Sample Output ***
>>> %Run -c $EDITOR_CONTENT
Begin testHc12Communication(), ...
  Begin set both HC12s communication mode, ...
  End   set both HC12s communication mode.
  Begin transmit message, ...
    xmitBytes = Pico #1 at COM 11, uart0 transmitting, ...
  End transmit message.
  Begin receive message, ...
    uartAny   = 42
    recvBytes = b'Pico #1 at COM 11, uart0 transmitting, ...'
  End   receive msaages.
End   testHc12Communication(), ...
>>>
'''

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

# *** 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  = 11 #2
bPwmPinNum1  = 10 #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  = 27 #14
aIn2PinNum1  = 28 #15
bIn1PinNum1  = 22 #16
bIn2PinNum1  = 26 #17

# *** Interrupt Pin Dicts ***

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

intPinNumList = [intPinNum0, intPinNum1, 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

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

# *** 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,
    }

# *** 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

# *** 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

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

defaultDirection = 'Forward'
defaultSpeed     = 'VertHighSpeed'
defaultPwmFreq   = 1000
defaultDutyCycle = 90

frontLeftWheel  = 0
frontRightWheel = 1
rearLeftWheel   = 2
rearRightWheel  = 3

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

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

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                  
                },  
          }, 
    }

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.low()

    # *** 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,
                        'MotorNum' : motorNum,
                       }
    
    motorStatusDict = {'Direction'   : defaultDirection,
                       'Speed'       : defaultSpeed,
                       'PwmFrequency': defaultPwmFreq,
                       'DutyCycle'   : defaultDutyCycle,
                      }                       

    motorDict = {'MotorConfictDict' : motorConfigDict,
                 'MotorControlDict' : motorControlDict,
                 'MotorStatusDict'  : motorStatusDict
                }    

    return motorDict

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

def setupMotorDirection(motorControlDict, directionName):
    if directionName =='Forward':
        if (motorControlDict['MotorNum'] % 2) == 0:
           motorControlDict['In1Pin'].low()
           motorControlDict['In2Pin'].high()
        else:
           motorControlDict['In1Pin'].high()
           motorControlDict['In2Pin'].low()      
        
    elif directionName =='Backward':
        if (motorControlDict['MotorNum'] % 2) == 0:
           motorControlDict['In1Pin'].high()
           motorControlDict['In2Pin'].low()
        else:
           motorControlDict['In1Pin'].low()
           motorControlDict['In2Pin'].high()                 
    return
    
def setupMotorSpeed(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 moveMotorForward(motorControlDict):  
    motorControlDict['In1Pin'].high()
    motorControlDict['In2Pin'].low()
    return

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

# *** Test setup/stop/move motor functions ***

def testSetupMotor(motorNum):
    print('Begin testSetupMotor(), ', 'motorNum =', motorNum)
    motorControlDict = setupMotor(motorNum)['MotorControlDict']
    stopMotor(motorControlDict)
    print('End   testSetupMotor().')
    return

def testSetupMotorList(motorNumList):
    for motorNum in motorNumList:
        testSetupMotor(motorNum)
    return

def testSetupMoveMotor(motorNum, directionName, speedName, holdSecondsName):
    print('Begiun testSetupMoveMotor(), ', 'motorNum =', motorNum)
    motorDict = setupMotor(motorNum)
    motorControlDict = motorDict['MotorControlDict']
    stopMotor(motorControlDict)
    setupMotorDirection(motorControlDict, directionName)
    setupMotorSpeed(motorControlDict, speedName)    
    hold(holdSecondsName)
    stopMotor(motorControlDict)
    print('End   testSetupMoveMotor().')    
    return

def testSetupMoveMotorListSequential(motorNumList, directionName, speedName, holdSecondsName):
    print('Begiun testSetupMoveMotorNumListSequential(), ...')
    for motorNum in motorNumList:
        motorDict = setupMotor(motorNum)
        motorControlDict = motorDict['MotorControlDict']
        stopMotor(motorControlDict)
        setupMotorDirection(motorControlDict, directionName)
        setupMotorSpeed(motorControlDict, speedName)    
        hold(holdSecondsName)
        stopMotor(motorControlDict)
    print('End   testSetupMoveMotorNumListSequential().')    
    return

def testSetupMoveMotorListConcurrent(motorNumList, directionName, speedName, holdSecondsName):
    print('Begin testSetupMoveMotorNumListConcurrent(), ...')
    for motorNum in motorNumList:
        motorDict = setupMotor(motorNum)
        motorControlDict = motorDict['MotorControlDict']
        stopMotor(motorControlDict)
        setupMotorDirection(motorControlDict, directionName)
        setupMotorSpeed(motorControlDict, speedName)       
    hold(holdSecondsName)
    for motorNum in motorNumList:
        motorDict = setupMotor(motorNum)
        motorControlDict = motorDict['MotorControlDict']
        stopMotor(motorControlDict)      
    print('End   testSetupMoveMotorNumListConcurrent().')    
    return

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

# *** Main ***

#testSetupMotor(motorNum = 0)
#testSetupMotorList(motorNumList = [0, 1, 2, 3])

#testSetupMoveMotor(motorNum = 0, directionName = 'Forward', speedName = 'VeryFast', holdSecondsName = 'TwoSeconds')
#testSetupMoveMotor(motorNum = 1, directionName = 'Forward', speedName = 'VeryFast', holdSecondsName = 'TwoSeconds')
#testSetupMoveMotor(motorNum = 2, directionName = 'Forward', speedName = 'VeryFast', holdSecondsName = 'TwoSeconds')
#testSetupMoveMotor(motorNum = 3, directionName = 'Forward', speedName = 'VeryFast', holdSecondsName = 'TwoSeconds')

# *** Testing TB6612FNG Driving 4 Wheels ***
testSetupMoveMotorListSequential([frontLeftWheel, frontRightWheel, rearLeftWheel, rearRightWheel], 'Forward', 'VeryFast', 'TwoSeconds')
testSetupMoveMotorListConcurrent([frontLeftWheel, frontRightWheel, rearLeftWheel, rearRightWheel], 'Backward', 'VerySlow', 'FourSeconds')

# *** Testing HC12 Config and Transive/Receive ***
#testHc12Config(hc12Num = 0, writeBytes = 'AT')
#testHc12Config(hc12Num = 1, writeBytes = 'AT')
testHc12Communication(xmitUartPortNum = 0, recvUartPortNum = 1, testXmitMsg = 'xyz msg')

# *** End ***

''' Sample output  tlfong01  2021nov20hkt1531
>>> %Run -c $EDITOR_CONTENT
Begiun testSetupMoveMotorNumListSequential(), ...
End   testSetupMoveMotorNumListSequential().
Begin testSetupMoveMotorNumListConcurrent(), ...
End   testSetupMoveMotorNumListConcurrent().
Begin testHc12Communication(), ...
  Begin set both HC12s communication mode, ...
  End   set both HC12s communication mode.
  Begin transmit message, ...
    xmitBytes = xyz msg
  End transmit message.
  Begin receive message, ...
    uartAny   = 7
    recvBytes = b'xyz msg'
  End   receive msaages.
End   testHc12Communication(), ...
>>> 
'''


Now I am watching how the ESP32 hobbyists are making Robots

The 10 Best ESP32 Robotics Projects – Cherie Tan, Muo 2021nov21
MUO – 20 Nov 21

The 10 Best ESP32 Robotics Projects

Here are some of the impressive robots made with an ESP32.

Learn Python Programming on Raspberry Pi With These Commands and Data Structures – Cherie Tan, Muo 2021sep19
MUO – 19 Sep 21

Learn Python Programming on Raspberry Pi With These Commands and Data Structures

Want to learn programming on your Raspberry Pi? You’ll need to know these Python commands and data structures to get started.


Integrating modules uart, hc12, interrupt, tb6612fng

Now I have integrated the above 4 python modules and tested all functions more or less OK.The penzu journal below has the full program listing and sample output.

pico_4wd_v115 program listing
Penzu

Penzu

Free personal journal and online diary.

/ to continue, …Reply

tlfong01

30 

Nov ’21

Master and slave pico 4WD 433MHz Transceiving Mirror Moving Experiment v0.1

Now that I have tested all the Smart Pico 4WD OK, I am going to do the following experiment:

  1. Using two pico 4WD, one as master, another as slave.
  2. Master 4WD moves any pattern, and sends the motor/wheel move commands, as a text string, such as “FrontLeftWheelMoveForwardFullSpeed”, through a HC12 UART RF 433MHz channel to the slave 4WD.
  3. The slave 4WD, when receiving the move wheel command, move the wheeling according, and send back the Wheel/Motor speed (from motor rotary encoder signals) back to the master 4WD.
  4. So, as an example, if the master 4WD moves in a straight line, then a square, then a circle, the the slave 4WD moves the same pattern, at the same speed.
  5. The slave 4WD, if it wants, can record/remember the move commands as a command text file, and later moves the same pattern, as many times as possible, and at same or different speed as the master 4WD.

pico_4wd_v122.py

pico_4wd_v125.py


Open-source, 3D printed, low cost vehicle, controlled over the internet programmed in Python


newone_car_2021nov24011019×285 154 KB


Open-source, 3D printed, low cost transport and reconnaissance vehicle controlled over the internet, programmed in Python

https://www.open-ats.eu/

Element14 Rpi Pico Info

https://community.element14.com/products/raspberry-pi/w/documents/5191/raspberry-pi-pico


Kitronix Pico Buggy

image600×600 75 KB


Kitronik Autonomous Robotics Platform for Pico [New] – £34Kitronik Ltd 1

Electronic education & hobby project kits, tools & resources 1

Kitronik specialise in electronic project kits. We also stock the microbit and a range of accessories, plywood, e-textiles, Perspex, clocks and much more.

Kitronik Autonomous Robotics Platform for Pico`

This morning I read that Kitronix is now an official Rpi reseller and they are selling an autonomous Pico robot car. I hope pi-top will catch up soon.

The Kitronik Autonomous Robotics Platform Pico, a fun and hands-on introduction to Robotics with the Raspberry Pi Pico.

*The Kitronik Autonomous Robotics Platform for Raspberry Pi Pico is a fun and hands-on introduction to buggy robotics. *

*The easy to follow booklet provided with the kit guides you through all of the steps required for you to take control of your robot. *

The Robotics Platform has been designed to grow with you and provided additional servo and ultrasonic sensor connectors for more advanced projects. This buggy requires a Raspberry Pi Pico with pin headers attached, yo…


pi-top [4] Complete Raspberry Pi 4 Computer Kit – $250

pi-top [4] Complete Raspberry Pi 4 Computer Kit – $250

Overview

You and your children can design, code and make anything you imagine with the pi-top [4] Complete Raspberry Pi 4 computer kit.

It includes everything you need to program a Raspberry Pi inside of its rugged case.

Whatever you wish to build an alarm or a sensor, or learning about problem solving and code writing, this computer kit is a must-have.


Pico 4WD v128 Program Listing

#setupMoveCarHold('FrontLeftWheel',  'Forward', 'Normal', '2 seconds')
#setupMoveCarHold('FrontRightWheel', 'Forward', 'Normal', '2 seconds')

#setupMoveCarHold('RearLeftWheel',   'Forward', 'Normal', '2 seconds')
#setupMoveCarHold('RearRightWheel',  'Forward', 'Normal', '2 seconds')

#setupMoveCarHold('FrontWheels',     'Forward', 'Normal', '2 seconds')
#setupMoveCarHold('RearWheels',      'Forward', 'Normal', '2 seconds')
#setupMoveCarHold('AllFourWheels',   'Forward', 'Normal', '2 seconds')

setupTurnCarHold('FrontWheels',      'Forward',    'Normal', '2 seconds')
setupTurnCarHold('RearWheels',       'Backward',   'Normal', '2 seconds')

Pico 4WD v128 Program Listing


Pico 4WD Moving in a straight line, in a sqaure, in a circle functions tested OK

Now the following functions are tested OK.

setupMoveCarHold('FrontLeftWheel',  'Forward', 'Normal', '2 seconds')
setupMoveCarHold('FrontRightWheel', 'Forward', 'Normal', '2 seconds')

setupMoveCarHold('RearLeftWheel',   'Forward', 'Normal', '2 seconds')
setupMoveCarHold('RearRightWheel',  'Forward', 'Normal', '2 seconds')

setupMoveCarHold('FrontWheels',     'Forward', 'Normal', '2 seconds')
setupMoveCarHold('RearWheels',      'Forward', 'Normal', '2 seconds')
setupMoveCarHold('AllFourWheels',   'Forward', 'Normal', '2 seconds')

setupTurnCarHold('FrontWheels',      'TurnLeft',   'Normal', '2 seconds')
setupTurnCarHold('FrontWheels',      'TurnRight',  'Normal', '2 seconds')
setupTurnCarHold('RearWheels',       'TurnLeft',   'Normal', '2 seconds')
setupTurnCarHold('RearWheels',       'TurnRight',  'Normal', '2 seconds')

So I have proven the concept that it is easy to move the 4WD in any pattern I wish: straight line, square, circle, hexagon etc.

And of course it should be also easy to communicate between a group of pico 4WDs each with HC12 433MHz tranceivers to talk to each other and perform orchestraed group movements with or without a Rpi4B master/conductor

pico_4wd_v130.py


Yet another self driving car

This remote-controlled car drives itself


4WD Moving in a square functions tested OK

4WD Moving in a square program listing

def carMoveSquareV01():
    print('Begin carMoveSquareV01(), ...')
    setupMoveCarHold('AllFourWheels', 'Forward',  'Normal', '2 seconds')
    setupTurnCarHold('FrontWheels',   'TurnLeft', 'VerySlow',   '1 second')    
    setupMoveCarHold('AllFourWheels', 'Forward',  'Normal', '2 seconds')
    setupTurnCarHold('FrontWheels',   'TurnLeft', 'VerySlow',   '1 second')
    setupMoveCarHold('AllFourWheels', 'Forward',  'Normal', '2 seconds')
    print('End   carMoveSquareV01().')
    return


Pico GP pins running out problem

I am running out of GP pins for the 4WD project. One workaround is to use IO expenderes such as MCP2307/MCP23s17, or PCF8574. I am thinking of trying out PCF8574 first.

PCF8574 Remote 8-Bit I/O Expander for I2C Bus – TI
ti.com

pcf8574.pdf

2.83 MB


pcf8574_summary_2021nov2801931×662 191 KB


PCF8574 IO pins for TB6612FNG signals

tb6612fng_pinout_2021nov2801

Now I am reading an old Pico micropython program using PCF8574 to control a DC motor controller MX15 I need to modify this program for TB6612FNG.


 *** iox_pcf8571_v34 tlfong01 2021mar01hkt1616
# Thonny 3.3.3 MicroPython (Raspberry Pi Pico)
# Chinese Windows 10
# References - https://github.com/raspberrypi/pico-micropython-examples

#import machine
from machine import Pin, Timer
import time

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

# Contents
#   Part A - I2C Bus Config/Setup/Test
#   Part B - PCF8571 8-Bit I/O Extender Config/Setup/Test
#   

# *** I2C ***

# *** I2C Bus Dictionary

i2cBusDict = {
    '0' : { 'BusNum'     : 0,
            'NickName'   : 'Amy',
            'SdaPinNum'  : 0,
            'SclPinNum'  : 1,
            'Frequency'  : '100 kHz',
          },
    '1' : { 'BusNum'     : 1,
            'NickName'   : 'Betty',
            'SdaPinNum'  : 2,
            'SclPinNum'  : 3,
            'Frequency'  : '400 kHz',
          },          
    }                  

frequencyDict = {
    '100 kHz' :  100000,
    '400 kHz' :  400000,
    '1 MHz'   : 1000000,
    }

# *** Print/Debug Functions ***

def printIntListInHex(intList):
    for integer in intList:
        print(hex(integer), ' ', end = '')
    #print('')        
    return

def padString(string, paddedStringLength):
    leftOver = paddedStringLength - len(string)
    string = string + (' ' * leftOver)
    return string    

# *** I2C Functions ***

def setupI2cBus(i2cBusNum):
    sdaPinNum = i2cBusDict[str(i2cBusNum)]['SdaPinNum'] 
    sclPinNum = i2cBusDict[str(i2cBusNum)]['SclPinNum']
    sdaPin    = machine.Pin(sdaPinNum)    
    sclPin    = machine.Pin(sclPinNum)
    frequency = frequencyDict[i2cBusDict[str(i2cBusNum)]['Frequency']]     
    i2cBus = machine.I2C(i2cBusNum, sda = sdaPin, scl = sclPin, freq = frequency)
    return i2cBus

def setupI2cBusList(i2cBusNumList):
    i2cBusList = []
    for i2cBusNum in i2cBusNumList:        
       i2cBus = setupI2cBus(i2cBusNum)
       i2cBusList.append(i2cBus)   
    return i2cBusList

# *** Test Functions ***

def testSetupI2cBusList():
    print('Begin testSetupI2cBusList(), ...')
    i2cBustList = setupI2cBusList([0, 1])
    print('End   testSetupI2cBusList().\n')
    return i2cBustList

def testSetupScanI2cBusList():
    print('Begin testSetupScanI2cBusList(), ...')    
    i2cBusList = setupI2cBusList([0, 1])    
    for i2cBus in i2cBusList:
        index = i2cBusList.index(i2cBus)
        print('  I2C Bus Num =', index, ' ', end = '')
        ljustNickName = padString(i2cBusDict[str(i2cBusList.index(i2cBus))]['NickName'], 8)
        print('NickName =', ljustNickName, end ='')       
        print('Frequency =', i2cBusDict[str(i2cBusList.index(i2cBus))]['Frequency'], ' ', end ='')
        print('sdaPin =', i2cBusDict[str(i2cBusList.index(i2cBus))]['SdaPinNum'], ' ', end ='')
        print('sclPin =', i2cBusDict[str(i2cBusList.index(i2cBus))]['SclPinNum'], ' ', end ='')         
        printI2cDeviceList(i2cBus)
    print('End   testSetupI2cBusList().\n')        
    return 

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

# *** PCF8574 8-bit IO Extender ***

# *** IoX Config ***

i2cDevDict = {
    '0' : { 'I2cDevNum'     : 0,
            'I2cBusNum'     : 0,
            'I2cDevAddr'    : 0x23,
            'DevName'       : 'PCF8574 #1',
            'DevNickName'   : 'Connie'
          },
    '1' : { 'I2cDevNum'     : 1,
            'I2cBusNum'     : 1,
            'I2cDevAddr'    : 0x24,
            'DevName'       : 'PCF8574 #2',
            'DevNickName'   : 'Daisy'
          },
    '2' : { 'I2cDevNum'     : 2,
            'I2cBusNum'     : 0,
            'I2cDevAddr'    : 0x27,
            'DevName'       : 'LCD2004 #1',
            'DevNickName'   : 'Emily'
          },
    '3' : { 'I2cDevNum'     : 3,
            'I2cBusNum'     : 1,
            'I2cDevAddr'    : 0x22,
            'DevName'       : 'LCD1602 #1',
            'DevNickName'   : 'Fanny'
          },     
    }

def printI2cDevDict():
    dictLength = len(i2cDevDict)
    i2cDevNumList = [i2cDevNum for i2cDevNum in range(dictLength)]
    
    for i2cDevNum in i2cDevNumList:
        print('      i2cDevNum =', i2cDevNum, ' ', end = '')
        
        ljustDeviceName = padString(i2cDevDict[str(i2cDevNum)]['DevName'], 8)
        print(' DeviceName =', ljustDeviceName, end ='')        
        
        ljustNickName = padString(i2cDevDict[str(i2cDevNum)]['DevNickName'], 8)
        print('  NickName =', ljustNickName, end ='')
        
        print('  I2cBusNum =', i2cDevDict[str(i2cDevNum)]['I2cBusNum'],end ='')
        print('  I2cDevAddr =', hex(i2cDevDict[str(i2cDevNum)]['I2cDevAddr']),end ='')         
        
        print('')
    print('')        
    return

def printI2cDevInfo(i2cDevNum):
    print('      i2cDevNum =', i2cDevNum, ' ', end = '')
        
    ljustDeviceName = padString(i2cDevDict[str(i2cDevNum)]['DevName'], 8)
    print(' DeviceName =', ljustDeviceName, end ='')        
        
    ljustNickName = padString(i2cDevDict[str(i2cDevNum)]['DevNickName'], 8)
    print('  NickName =', ljustNickName, end ='')
        
    print('  I2cBusNum =', i2cDevDict[str(i2cDevNum)]['I2cBusNum'],end ='')
    print('  I2cDevAddr =', hex(i2cDevDict[str(i2cDevNum)]['I2cDevAddr']),end ='')         
        
    print('')
    return

# *** IoX Functions ***

def scanAndPrintI2cBusList(i2cBusList):
    for i2cBus in i2cBusList:
        index = i2cBusList.index(i2cBus)        
        print('      I2C Bus Num =', index, ' ', end = '')
        i2cDeviceList = i2cBus.scan()
        print('I2cDeviceList = ', end = '')
        printIntListInHex(i2cDeviceList)
        print('')
    return

# *** Iox Test Functions ***

def testIoxDevices():
    printIoxDevices()
    return

def printI2cBusListConfig(i2cBusList):
    #print('\n        I2C Bus List Config, ... ')
    for i2cBus in i2cBusList:
        index = i2cBusList.index(i2cBus)        
        print('      I2C Bus Num =', index, ' ', end = '')
        ljustNickName = padString(i2cBusDict[str(i2cBusList.index(i2cBus))]['NickName'], 8)
        print('Bus nick name =', ljustNickName, end ='')       
        print('Frequency =', i2cBusDict[str(i2cBusList.index(i2cBus))]['Frequency'], ' ', end ='')
        print('sdaPin =', i2cBusDict[str(i2cBusList.index(i2cBus))]['SdaPinNum'], ' ', end ='')
        print('sclPin =', i2cBusDict[str(i2cBusList.index(i2cBus))]['SclPinNum'], ' ', end ='')
        print('')
    return

def printIoxDevicesOnI2cBusList(i2cBusList): 
    for i2cBus in i2cBusList:
        index = i2cBusList.index(i2cBus)        
        print('      I2C Bus Num =', index, ' ', end = '')        
        printI2cDeviceList(i2cBus)
    return

# *** Basic Tests ***

def pcf8574BasicTest01():
    print('>>>>>>>>>> Begin testPcf8574(), ... >>>>>>>>>>\n')  

    print('  *** Set up I2C bus list [i2cBus0, i2cBus1] ***\n')
    i2cBusList = setupI2cBusList([0, 1])
    
    print('  *** I2C Bus List Config ***')     
    printI2cBusListConfig(i2cBusList)
    print('')     
    
    print('  *** I2c Device Dict ***')    
    printI2cDevDict()
    
    print('  *** Scan and print I2C devices I2C bus list [i2cBus0, i2cBus1] ***')
    scanAndPrintI2cBusList(i2cBusList)

    print('\n>>>>>>>>>> End   testPcf8574(). >>>>>>>>>>\n')    
    return

# *** Write/Read I2C Device ***

# *** Write Functions ***

def writeI2cBusDevAddrOneByte(i2cBus, i2cDevAddr, writeByte):
    i2cBus.writeto(i2cDevAddr, bytes([writeByte]))
    return

def writeI2cDevNumOneByte(i2cBusList, i2cDevNum, writeByte):
    i2cBusNum  = i2cDevDict[str(i2cDevNum)]['I2cBusNum']
    i2cBus     = i2cBusList[i2cBusNum]
    i2cDevAddr = i2cDevDict[str(i2cDevNum)]['I2cDevAddr']
    writeI2cBusDevAddrOneByte(i2cBus, i2cDevAddr, writeByte)
    return

def blinkI2cDevNumByte1Byte2(i2cBusList, i2cDevNum, byte1, byte2, byteTime1, \
                             byteTime2, totalCount):
    i2cBusNum  = i2cDevDict[str(i2cDevNum)]['I2cBusNum']
    i2cBus     = i2cBusList[i2cBusNum]
    i2cDevAddr = i2cDevDict[str(i2cDevNum)]['I2cDevAddr']
    
    for count in range(totalCount):
        writeI2cBusDevAddrOneByte(i2cBus, i2cDevAddr, byte1)
        time.sleep(byteTime1)
        writeI2cBusDevAddrOneByte(i2cBus, i2cDevAddr, byte2)
        time.sleep(byteTime2)
    writeI2cBusDevAddrOneByte(i2cBus, i2cDevAddr, 0x00)
    #writeI2cBusDevAddrOneByte(i2cBus, i2cDevAddr, 0xff)      
    return

def scanI2cDevNumOneByte(i2cBusList, i2cDevNum, scanByte, scanTime, totalCount):
    i2cBusNum  = i2cDevDict[str(i2cDevNum)]['I2cBusNum']
    i2cBus     = i2cBusList[i2cBusNum]
    i2cDevAddr = i2cDevDict[str(i2cDevNum)]['I2cDevAddr']
    
    maskByte = 0x01
    for byteCount in range(totalCount):
        for bitCount in range(8):
            newMaskByte = maskByte << bitCount
            newByte = scanByte & newMaskByte
            writeI2cBusDevAddrOneByte(i2cBus, i2cDevAddr, newByte)
            time.sleep(scanTime)
    writeI2cBusDevAddrOneByte(i2cBus, i2cDevAddr, 0x00)    
    return

# *** Read Functions ***

''' tested not OK 

def readI2cBusDevAddrOneByte(i2cBus, i2cDevAddr):
    readByte = i2cBus.readfrom(i2cDevAddr, 4) 
    return readByte

def readPrintI2cBusDevAddrOneByte(i2cBus, i2cDevAddr):
    readByte = readI2cBusDevAddrOneByte(i2cBus, i2cDevAddr)
    print('Read byte =', readByte)
    return

def readI2cDevNumOneByte(i2cBusList, i2cDevNum):
    i2cBusNum  = i2cDevDict[str(i2cDevNum)]['I2cBusNum']
    i2cBus     = i2cBusList[i2cBusNum]
    i2cDevAddr = i2cDevDict[str(i2cDevNum)]['I2cDevAddr']
    readPrintI2cBusDevAddrOneByte(i2cBus, i2cDevAddr)
    return
'''

# *** Write/Read Tests ***

def pcf8574WriteBlinkTest01():
    print('>>>>>>>>>> Begin   pcf8574WriteTest01(), ... >>>>>>>>>>\n')     
    
    print('  *** Set up I2C bus list [i2cBus0, i2cBus1] ***\n')
    i2cBusList = setupI2cBusList([0, 1])    
    
    print('  *** Scan and print I2C devices I2C bus list [i2cBus0, i2cBus1] ***')
    scanAndPrintI2cBusList(i2cBusList)
        
    #print('\n *** Read pcf8574 input pins - to test later ***')
    #i2cDevNum = 0    
    #readI2cDevNumOneByte(i2cBusList, i2cDevNum)
        #i2cBus = i2cBusList[0]
    #i2cDevAddr = 0x23
    #readByteArray = []
    #readByteArray = i2cBus.readfrom(i2cDevAddr, 1)
    #i2cBus.writeto_mem(76, 6, b'456')
    #i2cBus.readfrom_mem(76, 6, 4)

    print('\n  *** Toggle/Blink pcf8574 output pins/LEDs ***') 
   
    #print('dp 01')  
    i2cBusList[0].writeto(0x27, bytes([0x55]))
    i2cBusList[0].writeto(0x23, bytes([0x55]))
    i2cBusList[1].writeto(0x22, bytes([0x55]))      
    i2cBusList[1].writeto(0x24, bytes([0x55]))
    
    #print('dp 02')
    writeI2cBusDevAddrOneByte(i2cBusList[0], 0x23, 0xff)    
    writeI2cBusDevAddrOneByte(i2cBusList[1], 0x24, 0xff)
    time.sleep(1)
    writeI2cBusDevAddrOneByte(i2cBusList[0], 0x23, 0x00)    
    writeI2cBusDevAddrOneByte(i2cBusList[1], 0x24, 0x00)
    
    #print('dp03') 
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum = 0, writeByte = 0x55)
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum = 1, writeByte = 0xaa)
    
    #print('dp04 blink')
    byte1 = 0x55
    byte2 = 0xaa
    byte1Time = 0.5
    byte2Time = 0.5
    totalCount = 2
    
    i2cDevNum = 0    
    blinkI2cDevNumByte1Byte2(i2cBusList, i2cDevNum, byte1, byte2, byte1Time, \
                             byte2Time, totalCount)
    i2cDevNum = 1 
    blinkI2cDevNumByte1Byte2(i2cBusList, i2cDevNum, byte1, byte2, byte1Time, \
                             byte2Time, totalCount)

    print('\n>>>>>>>>>> End   pcf8574WriteTest01().>>>>>>>>>>') 
    return

def pcf8574WriteBitTest01():
    print('\n>>>>>>>>>> Begin pcf8574WriteBitTest01(). >>>>>>>>>>')
    
    print('  *** Set up I2C bus list [i2cBus0, i2cBus1] ***\n')
    i2cBusList = setupI2cBusList([0, 1])    
    
    print('  *** I2c Device Dict ***')    
    printI2cDevDict()
    
    print('  *** Scan and print I2C devices I2C bus list [i2cBus0, i2cBus1] ***')
    scanAndPrintI2cBusList(i2cBusList)
    
    print('\n  *** Wrtie to i2cDevNum0, i2cDevNum1 ***')
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum = 0, writeByte = 0x55)
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum = 1, writeByte = 0xaa)
    time.sleep(0.5)
    
    print('\n  *** scan bit i2cDevNum0 ***')
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum = 0, writeByte = 0x00)
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum = 1, writeByte = 0x00)
    time.sleep(0.5)

    i2cDevNum = 0   
    #oldByte = 0x00
    newByte = 0x01
    maskByte = 0x00
    
    for i in range(8):
        #maskByte = newByte
        #newByte = newByte << 1
        writeI2cDevNumOneByteOrMaskByte(i2cBusList, i2cDevNum, newByte, maskByte)
        
        #newByte = newByte | oldByte
        #writeByte = newByte
        #writeI2cDevNumOneByte(i2cBusList, i2cDevNum, writeByte)
        time.sleep(0.5)
        maskByte = newByte | maskByte
        newByte = newByte << 1        
        
    print('\n>>>>>>>>>> End   pcf8574WriteBitTest01(). >>>>>>>>>>') 
    return

def writeI2cDevNumOneByteOrMaskByte(i2cBusList, i2cDevNum, writeByte, maskByte):
    writeByte = writeByte | maskByte
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum, writeByte)
    return

def writeI2cDevNumOneByte(i2cBusList, i2cDevNum, writeByte):
    i2cBusNum  = i2cDevDict[str(i2cDevNum)]['I2cBusNum']
    i2cBus     = i2cBusList[i2cBusNum]
    i2cDevAddr = i2cDevDict[str(i2cDevNum)]['I2cDevAddr']
    writeI2cBusDevAddrOneByte(i2cBus, i2cDevAddr, writeByte)
    return

def writeI2cDevNumOneByteOrMaskByte(i2cBusList, i2cDevNum, writeByte, maskByte):
    writeByte = writeByte | maskByte
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum, writeByte)
    return

#def setBitHigh(i2cBusList, i2cDevNum, writeByte, bitPosition):

# *** Motor Driver MX1908 Functions ***

i2cMotorDict = {
    '0' : {'I2cDevNum'    : 0,
           'MotorName'    : 'Gigi',
           'Action'       : {'MoveForward'  : 0b01,
                             'MoveBackward' : 0b10,
                             'Stop'         : 0b00,
                            }
          },
    '1' : {'I2cDevNum'    : 1,
           'MotorName'    : 'Helen',
           'Action'       : {'MoveForward'  : 0b01,
                             'MoveBackward' : 0b10,
                             'Stop'         : 0b00,
                            }           
          },
    }

i2cDevNameDict = {
    'Gigi'  : {'I2cDevNum'  : 0,
               'DeviceName' : 'Motor'},
    'Helen' : {'I2cDevNum'  : 1,
               'DeviceName' : 'Motor'},   
    }

def writeI2cMotorOneByte(i2cBusList, motorName, actionName):
    i2cDevNum = i2cDevNameDict[motorName]['I2cDevNum']
    writeByte = i2cMotorDict[str(i2cDevNum)]['Action'][actionName]
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum, writeByte)
    print('dp1', 'i2cDevNum =', i2cDevNum, 'actionName =', actionName, 'writeByte =', hex(writeByte))
    return

def pcf8574MotorTest01():
    print('\n>>>>>>>>>> Begin pcf8574MotorTest01(). >>>>>>>>>>')
    
    print('  *** Set up I2C bus list [i2cBus0, i2cBus1] ***\n')
    i2cBusList = setupI2cBusList([0, 1])    
    
    print('  *** I2c Device Dict ***')    
    printI2cDevDict()
    
    print('  *** Scan and print I2C devices I2C bus list [i2cBus0, i2cBus1] ***')
    scanAndPrintI2cBusList(i2cBusList)
    
    print('\n  *** Write Motor Test ***')
    #writeI2cMotorOneByte(i2cBusList, 'Gigi', 'MoveForward')
    
    i2cDevNum = 0
    motorByte = 0b10
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum, motorByte)
    time.sleep(2)
    
    motorByte = 0b01
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum, motorByte)    
    time.sleep(2)
    
    motorByte = 0b00
    writeI2cDevNumOneByte(i2cBusList, i2cDevNum, motorByte)    
    time.sleep(2) 
    
    print('\n>>>>>>>>>> End   pcf8574MotorTest01(). >>>>>>>>>>')    
    return

# *** Main ***

# *** test PCF8457 IOX Devices ***

#pcf8574BasicTest01()
#pcf8574WriteBlinkTest01()
#pcf8574WriteBitTest01()
pcf8574MotorTest01()

# *** End ***

'''
import utime
from machine import Pin

motor1a = Pin(10, Pin.OUT)
motor1b = Pin(11, Pin.OUT)

def forward():
   motor1a.high()
   motor1b.low()

def backward():
   motor1a.low()
   motor1b.high()

def stop():
   motor1a.low()
   motor1b.low()

def test():
    print('  Begin test()')
    forward()
    utime.sleep(1)
    backward()
    utime.sleep(1)
    stop()
    print('  End   test()')

for i in range(1):
    print('Test ', i)
    test()

'''


How do we develop AI education in schools? A panel discussion – Maria Richter, Rpi Foundation monthly AI education seminar series 2021nov30Blogdot.tv – 30 Nov 21

How do we develop AI education in schools? A panel discussion

AI is a broad and rapidly developing field of technology. Our goal is to make sure all young people have the skills, knowledge, and confidence to use and create AI systems. So what should AI


The future of AI education in UK schools — panel | Computing education research


Pico I2C Evaluation Board v0.1


pico_test_2021dec04011024×924 327 KB


Drive a Raspberry Pi Car Using Hand Gestures With OpenCV – Ash Hill 2021dec04
Tom’s Hardware – 3 Dec 21

Drive a Raspberry Pi Car Using Hand Gestures With OpenCV

Control a Pi with the wave of your hand.

This new Raspberry Pi-powered cluster computer is cheaper than a basic desktop – Mayank Sharma 2021dec05
TechRadar – 4 Dec 21

This new Raspberry Pi-powered cluster computer is cheaper than a basic desktop

Turing Pi 2 slated to go on sale early next year

Learn about electronics, coding, IoT and more as you build fun projects for just $20 – ZDNet
ZDNet

Learn about electronics, coding, IoT and more as you build fun projects for…

You don’t need to know anything except how to use a computer to acquire all kinds of new tech skills as you build the most interesting projects, like GPS tracking, smart home remote dashboards and much more.

You don’t need to know anything except how to use a computer to acquire all kinds of new tech skills as you build the most interesting projects, like GPS tracking, smart home remote dashboards and much more.


Pico UART, SPI, I2C Evaluation Board Pinout v0.1 2021dec05hkt1314


pico_pinout_2021dec05021024×480 109 KB


pico_test_2021dec05011555×1663 760 KB


Dual PCF8574 Module Board Testing Notes

PCF8574 Module – 8-bit I/O Expander for I2C Bus – Nettigo

PCF8574A Remote 8-bit I/O expander for I2C-bus with interrupt – NXP
nxp.com

PCF8574_PCF8574A.pdf

794.81 KB


dual_pcf8574_board_2021dec05021024×656 263 KB


PCF8574 IOX Test Function v01

PCF8574 IOX Test Function v01


PCF8574 Wiring V0.2

pcf8574_2021dec06011024×652 215 KB


Everyday Robot has eyes and arms. I am so jealous, …

Alphabet’s Everyday Robots – IEEE Spectrum 2021nov23
IEEE Spectrum – 23 Nov 21

Alphabet’s Everyday Robots: Years Later, Is Their Day Still Someday?

Last week, Google or Alphabet or X or whatever you want to call it announced that its Everyday Robots team has grown enough and made enough progress that it’s time for it to become its own thing: You guessed it, “Everyday Robots.” Click through to…

Introducing Everyday Robots – Everyday Robots 2021nov01

Introducing Everyday Robots


PCF8574 Iox Driving TB6612FNG Python Program

pcf8574_test_v53_2021dec0801.py


The Elektor Lab Team is interesting

The Elektor Lab Team
Elektor

The Elektor Lab Team: Our Approach, Preferred Tools, and More

The Elektor Lab team of in-house engineers develops, refines, and tests electronic projects and products. Get to know us!


picorobot67.py


Pico MicroPython program Driving 4WD Through PCF8514 Iox and TB6612FNG Motor Driver

picorobot79.py


Pico Wireless Pack – Piromorni £12

Me jealously read the following this morning:

Pico Wireless Pack – Piromorni £12
shop.pimoroni.com

Pico Wireless Pack – Pimoroni

Give your Raspberry Pi Pico project the capacity to chat with 2.4GHz Wi-Fi networks plus a handy microSD card slot!


Then this morning I read the following:

Develop boards remotely, in real time with new hardware-as-a-service – Nitin Dahad 2021dec13


The forum editor is getting very slow. So I am writing a new reply to see the response time will improve.

/ To continue, …Reply

20 DAYS LATER

1 MONTH LATER

1 MONTH LATER

1 MONTH LATER

tlfong01

8h

Raspberry Pi Pico Detects Accidents and Sends for Help
By Ash Hill published 1 day ago
Tom’s Hardware – 24 Mar 22

Raspberry Pi Pico Detects Accidents and Sends for Help

A practical Pi project with plenty to learn from.


5 Amazing Warehouse Robots You Must See – 1,101,734 views Feb 23, 2021

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.