Making a Rpi Pico Based Smart Vehicle – Part 2
1 / 7
Nov 2021

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:
- Pico system Uart
- HC12 RF xmit/recv
- TB6612FNG 4WD motor driving
- 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

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_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 2021nov21MUO – 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 2021sep19MUO – 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.

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:
- Using two pico 4WD, one as master, another as slave.
- 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.
- 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.
- 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.
- 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.
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
Element14 Rpi Pico Info
https://community.element14.com/products/raspberry-pi/w/documents/5191/raspberry-pi-pico
Kitronix Pico Buggy
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 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
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

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 2021dec04Tom’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 2021dec05TechRadar – 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 – ZDNetZDNet

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 Wiring V0.2
pcf8574_2021dec06011024×652 215 KB
Everyday Robot has eyes and arms. I am so jealous, …
Alphabet’s Everyday Robots – IEEE Spectrum 2021nov23IEEE 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

PCF8574 Iox Driving TB6612FNG Python Program
pcf8574_test_v53_2021dec0801.py
The Elektor Lab Team is interesting
The Elektor Lab TeamElektor

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!
Pico MicroPython program Driving 4WD Through PCF8514 Iox and TB6612FNG Motor Driver
Pico Wireless Pack – Piromorni £12
Me jealously read the following this morning:
Pico Wireless Pack – Piromorni £12shop.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

Raspberry Pi Pico Detects Accidents and Sends for Help
By Ash Hill published 1 day agoTom’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