I have this RPi3 that I am running a bunch codes on it. It is communicating with a server and also I have python supervisor running on it. Now I am trying to set up the same system on RPi4. For some reason RPi4 is not doing the functionality that I am looking for. Can someone look at the log files and let me know what is it that I am missing in RPi4. I here paste the log files from both PIs.
PI3 log file:
Port 5: 0100 power
Sent power on request
New status for hub 1-1 [0424:9514, USB 2.00, 5 ports]
Port 2: 0100 power
Port 3: 0100 power
Port 4: 0100 power
Port 5: 0100 power
Synchronizing state for rsyslog.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d rsyslog defaults
Executing /usr/sbin/update-rc.d rsyslog enable
Board model: 2
GPIO configuration: P1 (40 pins)
Using hardware: PWM
Using DMA channel: 14
Idle timeout: Disabled
Number of servos: 8
Servo cycle time: 20000us
Pulse increment step size: 10us
Minimum width value: 50 (500us)
Maximum width value: 250 (2500us)
Output levels: Normal
Using P1 pins: 7,11,12,13,15,16,18,22
Servo mapping:
0 on P1-7 GPIO-4
1 on P1-11 GPIO-17
2 on P1-12 GPIO-18
3 on P1-13 GPIO-27
4 on P1-15 GPIO-22
5 on P1-16 GPIO-23
6 on P1-18 GPIO-24
7 on P1-22 GPIO-25
2019-09-05 23:30:55,812 Starting device runner. On version 1.16.15.
2019-09-05 23:30:55,815 Exited state off
2019-09-05 23:30:55,817 Entered state
PI4 log file:
Sent power on request
New status for hub 2 [1d6b:0003 Linux 4.19.57-v7l+ xhci-hcd xHCI Host Controller 0000:01:00.0, USB 3.00, 4 ports]
Port 2: 02a0 power 5gbps Rx.Detect
Port 3: 02a0 power 5gbps Rx.Detect
Port 4: 02a0 power 5gbps Rx.Detect
Current status for hub 1 [1d6b:0002 Linux 4.19.57-v7l+ xhci-hcd xHCI Host Controller 0000:01:00.0, USB 2.00, 1 ports]
Sent power on request
New status for hub 1 [1d6b:0002 Linux 4.19.57-v7l+ xhci-hcd xHCI Host Controller 0000:01:00.0, USB 2.00, 1 ports]
Synchronizing state of rsyslog.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable rsyslog
2019-09-05 14:53:18,748 Reseting PCA9685 MODE1 (without SLEEP) and MODE2
2019-09-05 14:53:18,749 Wrote 0x00 to register 0xFA
2019-09-05 14:53:18,750 Wrote 0x00 to register 0xFB
2019-09-05 14:53:18,751 Wrote 0x00 to register 0xFC
2019-09-05 14:53:18,751 Wrote 0x00 to register 0xFD
2019-09-05 14:53:18,752 Wrote 0x04 to register 0x01
2019-09-05 14:53:18,753 Wrote 0x01 to register 0x00
2019-09-05 14:53:18,759 Read 0x01 from register 0x00
2019-09-05 14:53:18,760 Wrote 0x01 to register 0x00
2019-09-05 14:53:18,765 Setting PWM frequency to 1600 Hz
2019-09-05 14:53:18,766 Estimated pre-scale: 2
2019-09-05 14:53:18,766 Final pre-scale: 3
2019-09-05 14:53:18,767 Read 0x01 from register 0x00
2019-09-05 14:53:18,768 Wrote 0x11 to register 0x00
2019-09-05 14:53:18,768 Wrote 0x03 to register 0xFE
2019-09-05 14:53:18,769 Wrote 0x01 to register 0x00
2019-09-05 14:53:18,775 Wrote 0x81 to register 0x00
Board model: 2
GPIO configuration: P1 (40 pins)
Using hardware: PWM
Using DMA channel: 14
Idle timeout: Disabled
Number of servos: 8
Servo cycle time: 20000us
Pulse increment step size: 10us
Minimum width value: 50 (500us)
Maximum width value: 250 (2500us)
Output levels: Normal
Using P1 pins: 7,11,12,13,15,16,18,22
Servo mapping:
0 on P1-7 GPIO-4
1 on P1-11 GPIO-17
2 on P1-12 GPIO-18
3 on P1-13 GPIO-27
4 on P1-15 GPIO-22
5 on P1-16 GPIO-23
6 on P1-18 GPIO-24
7 on P1-22 GPIO-25
2019-09-05 14:53:18,933 Starting device runner. On version 1.16.15.
2019-09-05 14:53:28,947 Exited state off
2019-09-05 14:53:28,949 Entered state ready
2019-09-05 14:53:28,950 moving to top
-
What log files? What “bunch codes”? What doesn’t work? What OS? – Milliways 54 mins ago
-
@RAS, Brainstorming questions: (1) Why do you power your 8 servos from USB2/3 hub? I remember when I tried the Rpi4V USB3 hub, some Rpi3B+ USB device drivers no long work. So I sadly went back to USB2 hub. (2) Your octo GPIO DMA driver might not port from Rpi3 to 4. That is one of the reasons I gave up using Rpi PWM pins and use PCA9685 with 16 GPIO/PWM pins. The good thing about PCA9685 is that you can set a time lag (eg 1% of 50Hz period) so when start/stop all servos together, actually each of them start with a time lag, prevent power dip and also back EMF, EMI etc. – tlfong01 16 mins ago
-
@RAS, I noticed that you use 8 Rpi GPIO pins in Rpi3B+ but also switched to PCA9685 in Rpi4B. If that is so, of course you would expect a lot of teething or tech transfer problems. BTW, my PCA9685 functions also abstract to use higher level parameters such as: servo name (4 Rpi4B x 4 I2C bus x 2 PCA9685 x 16 PWM channels = 4 x 4 x 2 x 16 = “my-stupid-brain-calculator-overflow-so-many” servos, all “called by name”) , bus name (4 I2C buses each Rpi4B), pulse width (500 ~ 2000uS), postion (extreme left, right, mid, etc), position steps (like a stepping motor! :)), for a 64+ servo robot arm, … – tlfong01 4 mins ago Edit
Question
Problem in porting Rpi3B+ python GPIO PWM servo programs to Rpi4B
Answer
/ to continue, …
References
Rpi4B PCA9685 PWM Controller driving 4 TowerPro MG996R Servos – tlfong01
PCAS9685 PWM Controller Installation Notes – tlfong01
Rpi3B+ GPIO PWM Servo Testing Notes – tlfong01
Appendices
(1) Rpi4B PCA9685 and 4 TowerPro MG996Rs
(2) tlfong01’s PWM Servo Program Listing
**# fservo61py tlfong01 2019aug26hkt1446
# ********************************************************************************
# ********************************************************************************
# *** Import ***
from time import sleep
import fprint53 as fprint
import ftime53 as ftime
import fi2c53 as fi2c
import fpwm61 as fpwm
# ********************************************************************************
# ********************************************************************************
# *** Config ***
# *** Servo Type Dict ***
servoTypeDict0 = {
'ServoModel' : 'TowerPro MG96R',
'ServoFunction' : 'Ultrasound Sensor Right',
'PwmFrequencyName' : '50Hz',
'PwmDutyCycleName' : '50%',
'PwmDutyCycleNum' : 50,
}
# *** Servo Device Dict ***
servoDevDict0 = {
'ServoName' : 'Annie',
'ServoTypeDict' : servoTypeDict0,
'ServoNum' : 0,
'PwmDevNum' : 0,
'PwmChnNum' : 0,
'InitPwmPulseWidthNum' : 1500,
'ServoStartDeg' : 0,
'ServoFinishDeg' : 90,
}
servoDevDict1 = {
'ServoName' : 'Betty',
'ServoTypeDict' : servoTypeDict0,
'ServoNum' : 1,
'PwmDevNum' : 0,
'PwmChnNum' : 1,
'InitPwmPulseWidthNum' : 1500,
'ServoStartDeg' : 0,
'ServoFinishDeg' : 90,
}
servoDevDict2 = {
'ServoName' : 'Connie',
'ServoTypeDict' : servoTypeDict0,
'ServoNum' : 2,
'PwmDevNum' : 1,
'PwmChnNum' : 0,
'InitPwmPulseWidthNum' : 1500,
'ServoStartDeg' : 0,
'ServoFinishDeg' : 90,
}
servoDevDict3 = {
'ServoName' : 'Daisy',
'ServoTypeDict' : servoTypeDict0,
'ServoNum' : 3,
'PwmDevNum' : 1,
'PwmChnNum' : 1,
'InitPwmPulseWidthNum' : 1500,
'ServoStartDeg' : 0,
'ServoFinishDeg' : 90,
}
# *** Servo Name Dict ***
servoNameDict = {
'Annie' : servoDevDict0,
'Betty' : servoDevDict1,
'Connie' : servoDevDict2,
'Daisy' : servoDevDict3,
}
# *** Servo Control Byte Dict ***
servoControlByteDict = {
'24Hz' : 0xff,
'50Hz' : 0x7f, # 50Hz = 20 mS period
'200Hz' : 0x1e,
'400Hz' : 0x0f,
'800Hz' : 0x07,
'1526Hz' : 0x03,
'0%' : 0x00010fff,
'5%' : 0x00010f33,
'10%' : 0x00010e66,
'20%' : 0x00010ccc,
'50%' : 0x000107ff,
'75%' : 0x000103ff,
'80%' : 0x00010333,
'90%' : 0x00010199,
'55%' : 0x000100cc,
'DutyCycle20%Delay10%' : 0x019904cc,
'500uS' : 0x00010f99, # 0.5 mS (50Hz)
'1000uS' : 0x00010f33, # 1.0 mS
'1500uS' : 0x00010ecd, # 1.5 mS
'2000uS' : 0x00010e66, # 2.0 mS (50Hz = 1000/50 = 20mS, (1 - 2/20) * 4096 = e66
'Degree0' : 0x00010f33,
'Degree90' : 0x00010ecd,
'Degree180' : 0x00010e66,
}
servoChangePositionDict = {
'1000To2000' : [1000, 2000],
'2000To1000' : [2000, 1000],
'1000To1500' : [1000, 1500],
'1500To1000' : [1500, 1000],
}
servoFixPositionDict = {
'1000' : 1000,
'1500' : 1500,
'2000' : 2000,
}
# *** Servo Functions ***
# *** PWM Functions ***
def setServoNamePwmFrequencyName(servoName):
fprint.printBeginExecFunction()
servoDevDict = servoNameDict[servoName]
pwmDevNum = servoDevDict['PwmDevNum']
pwmFrequencyName = servoDevDict['ServoTypeDict']['PwmFrequencyName']
fpwm.setFrequencyName(pwmDevNum, pwmFrequencyName)
fprint.printEndExecFunction()
return
def setServoNamePwmPulseWidthNum(servoName, pwmPulseWidthNum):
fprint.printBeginExecFunction()
servoDevDict = servoNameDict[servoName]
pwmDevNum = servoDevDict['PwmDevNum']
pwmChnNum = servoDevDict['PwmChnNum']
print('pwmChnNum =', pwmChnNum)
fourByteNum = fpwm.convertPwmPulseWidthNumToFourByteNum(pwmPulseWidthNum)
print('fourBytesNum =', hex(fourByteNum))
fpwm.setDutyCycleFourByteNum(pwmDevNum, pwmChnNum, fourByteNum)
fprint.printEndExecFunction()
return
# *** Move Servo ***
def moveServoName(servoName, pulseWidthNum):
fprint.printBeginExecFunction()
setServoNamePwmPulseWidthNum(servoName, pulseWidthNum)
fprint.printEndExecFunction()
return
# *** Test Functions ***
def initServoName(servoName):
fprint.printBeginExecFunction()
setServoNamePwmFrequencyName(servoName)
servoDevDict = servoNameDict[servoName]
initPwmPulseWidthNum = servoDevDict['InitPwmPulseWidthNum']
setServoNamePwmPulseWidthNum(servoName, initPwmPulseWidthNum)
fprint.printEndExecFunction()
return
def initServoNameList(servoNameList):
fprint.printBeginExecFunction()
for servoName in servoNameList:
initServoName(servoName)
fprint.printEndExecFunction()
return
def moveToPulseWidthNum(servoName, pulseWidthNum):
servoDevDict = servoNameDict[servoName]
setServoNamePwmPulseWidthNum(servoName, pulseWidthNum)
return
def repeatSwingServo(servoName, beginPulseWidthNum, endPulseWidthNum, pauseSeconds, repeatCount):
for count in range(repeatCount):
moveToPulseWidthNum(servoName, beginPulseWidthNum)
sleep(pauseSeconds)
moveToPulseWidthNum(servoName, endPulseWidthNum)
sleep(pauseSeconds)
return
def moveServo(servoName, beginPulseWidthNum, endPulseWidthNum):
moveToPulseWidthNum(servoName, beginPulseWidthNum)
moveToPulseWidthNum(servoName, endPulseWidthNum)
return
def moveServoBySteps(servoName, beginPulseWidthNum, endPulseWidthNum, stepPulseWidthNum, stepPauseSeconds):
moveToPulseWidthNum(servoName, beginPulseWidthNum)
tempPulseWidthNum = beginPulseWidthNum + stepPulseWidthNum
while (tempPulseWidthNum < endPulseWidthNum):
moveToPulseWidthNum(servoName, tempPulseWidthNum)
sleep(stepPauseSeconds)
tempPulseWidthNum = tempPulseWidthNum + stepPulseWidthNum
moveToPulseWidthNum(servoName, endPulseWidthNum)
return
def swingServo(servoName, beginPulseWidthNum, endPulseWidthNum, pauseSeconds):
moveServo(servoName, beginPulseWidthNum, endPulseWidthNum)
sleep(pauseSeconds)
moveServo(servoName, endPulseWidthNum, beginPulseWidthNum)
sleep(pauseSeconds)
return
def repeatSwingServo(servoName, beginPulseWidthNum, endPulseWidthNum, pauseSeconds, repeatCount):
for count in range(repeatCount):
swingServo(servoName, beginPulseWidthNum, endPulseWidthNum, pauseSeconds)
return
# ********************************************************************************
# ********************************************************************************
# *** Main Tests ***
def mainTests():
#fpwm.testBlinkOneLed0()
#fpwm.testBlinkAllLedsConcurrently()
#fpwm.setFrequencyName(devNum = 0, frequencyName = '50Hz')
#fpwm.setDutyCycleName(devNum = 0, ledNum = 0, dutyCycleName = '50%')
#fpwm.setFrequencyName(devNum = 0, frequencyName = '50Hz')
#fpwm.setDutyCycleName(devNum = 0, ledNum = 0, dutyCycleName = '20%')
#fpwm.setFrequencyName(devNum = 0, frequencyName = '800Hz')
#fpwm.setDutyCycleNum (devNum = 0, ledNum = 0, dutyCycleNum = 20)
#initServoName('Annie')
#initServoNameList(['Annie', 'Betty', 'Cindy', 'Daisy'])
#repeatSwingServoName('Annie', 500, 5000)
initServoName('Annie')
initServoName('Betty')
initServoName('Connie')
initServoName('Daisy')
sleep(2)
repeatSwingServo('Annie', 1000, 2000, 1, 2)
sleep(1)
repeatSwingServo('Betty', 1000, 2000, 1, 2)
sleep(1)
repeatSwingServo('Connie', 1000, 2000, 1, 2)
sleep(1)
repeatSwingServo('Daisy', 1000, 2000, 1, 2)
sleep(1)
#moveServoBySteps('Annie', 1000, 2000, 5, 0.1)
#moveServoBySteps('Connie', 1000, 2000, 5, 0.1)
# ********************************************************************************
# ********************************************************************************
# *** Init/Main Functions ***
# *** Init Function ***
def init():
pass
return
#*** Main Function ***
def main():
init()
mainTests()
return
# ********************************************************************************
# ********************************************************************************
# *** Main ***
if __name__ == '__main__':
main()
# *** End of Program ***
# ********************************************************************************
# **********************************************************************************
(3) tlfong01’s Rpi4B Quad I2C Bus Testing Program Listing
# fi2c62.py tlfong01 2019aug28hkt1433
from time import sleep
import smbus
import fprint53 as fprint
import ftime53 as ftime
# I2c Bus Setup Notes
# pi@raspberrypi:~ $ date Wed 28 Aug 2019 03:26:24 PM HKT
# pi@raspberrypi:~ $ uname -a
# Linux raspberrypi 4.19.58-v7l+ #1245 SMP Fri Jul 12 17:31:45 BST 2019 armv7l GNU/Linux
# pi@raspberrypi:~ $ sudo nano /boot/config.txt
# dtoverlay=i2c1,pins_2_3 (board pins 3, 5)
# dtoverlay=i2c3,pins_4_5 (board pins 7, 29)
# dtoverlay=i2c4,pins_6_7 (board pins 31, 26)
# dtoverlay=i2c5,pins_12_13 (board pins 32, 33)
# dtoverlay=i2c6,pins_22_23 (board pins 15, 16)
# pi@raspberrypi:~ $ ls /dev/i2c*
# /dev/i2c-1 /dev/i2c-3 /dev/i2c-4 /dev/i2c-5 /dev/i2c-6
# ********************************************************************************
# ********************************************************************************
# *** I2c Bus Config ***
i2cBus1 = smbus.SMBus(1)
i2cBus3 = smbus.SMBus(3)
i2cBus4 = smbus.SMBus(4)
i2cBus5 = smbus.SMBus(5)
i2cBusDict = {'I2cBus1': i2cBus1,
'I2cBus3': i2cBus3,
'I2cBus4': i2cBus4,
'I2cBus5': i2cBus5,
}
# *** Pca9685 I2c Slave Device Congif ***
pca9685DevAddrDict = {
'Dev0': 0x40,
'Dev1': 0x41,
'Dev2': 0x42,
'Dev3': 0x43,
'Dev4': 0x44,
'Dev5': 0x45,
'Dev6': 0x46,
'Dev7': 0x47,
}
pca9685RegAddrDict = { 'Mode1': 0x00,
'Mode2': 0x01,
}
pca9685DataByteDict = {
'Mode1Reset': 0x11,
}
# ********************************************************************************
# ********************************************************************************
# *** Read Write Print Device/Register Functions ***
def writeDevTwoBytes(i2cBus, devAddr, writeByte1, writeByte2):
i2cBus.write_byte_data(devAddr, writeByte1, writeByte2)
return
def writeRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName, writeByte):
devAddr = devAddrDict[devName]
regAddr = regAddrDict[regName]
writeDevTwoBytes(i2cBus, devAddr, regAddr, writeByte)
return
def readDevOneByte(i2cBus, devAddr, readByteAddr):
readByte = i2cBus.read_byte_data(devAddr, readByteAddr)
return readByte
def readRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName):
devAddr = devAddrDict[devName]
regAddr = regAddrDict[regName]
readByte = i2cBus.read_byte_data(devAddr, regAddr)
return readByte
def printRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName):
readByte = readRegOneByte(i2cBusName, devAddrDict, devName, regAddrDict, regName)
print(printTitle, hex(readByte))
return
# *** Main Test Function ***
def testWriteReadPca9685Bus1Dev0RegMode1():
fprint.printBeginExecFunction()
i2cBusName = 'I2cBus1'
devName = 'Dev0'
regName = 'Mode1'
#i2cBus = fi2c.i2cBusDict[i2cBusName]
i2cBus = i2cBusDict[i2cBusName]
devAddrDict = pca9685DevAddrDict
regAddrDict = pca9685RegAddrDict
writeByte = 0x77
writeRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName, writeByte)
readByte = readRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName)
if readByte == writeByte:
resultsString = 'Good'
else:
resultsString = 'Bad'
devAddr = devAddrDict[devName]
fprint.printTitleOneByteNum('PCA9685 I2C Address', fprint.indentFormat640, devAddr)
fprint.printTitleOneByteNum('PCA9685 MODE1 Register Written', fprint.indentFormat640, writeByte)
fprint.printTitleOneByteNum('PCA9685 MODE1 Register Read', fprint.indentFormat640, readByte)
fprint.printTitleString('Write/Read Results', fprint.indentFormat640, resultsString)
fprint.printEndExecFunction()
return
def testPingPca9685Bus1Dev0RegMode1():
fprint.printBeginExecFunction()
i2cBusName = 'I2cBus1'
devName = 'Dev0'
regName = 'Mode1'
#i2cBus = fi2c.i2cBusDict[i2cBusName]
i2cBus = i2cBusDict[i2cBusName]
devAddrDict = pca9685DevAddrDict
regAddrDict = pca9685RegAddrDict
devAddr = devAddrDict[devName]
readByte = readRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName)
compareByte = pca9685DataByteDict['Mode1Reset']
if readByte == compareByte:
resultsString = 'Good'
else:
resultsString = 'Bad'
fprint.printTitleString('PCA9685 I2C Address', fprint.indentFormat640, hex(devAddr))
fprint.printTitleString('PCA9685 MODE1 Register Written', fprint.indentFormat640, hex(compareByte))
fprint.printTitleString('PCA9685 MODE1 Register Read', fprint.indentFormat640, hex(readByte))
fprint.printTitleString('Ping Results', fprint.indentFormat640, resultsString)
fprint.printEndExecFunction()
return
# ********************************************************************************
# ********************************************************************************
# *** Main Tests ***
def mainTests():
#ftime.testPrintDateTime()
testPingPca9685Bus1Dev0RegMode1()
testWriteReadPca9685Bus1Dev0RegMode1()
return
# ********************************************************************************
# ********************************************************************************
# *** Init/Main Functions ***
# *** Init Function ***
def init():
pass
return
#*** Main Function ***
def main():
init()
mainTests()
return
# ********************************************************************************
# ********************************************************************************
# *** Main ***
if __name__ == '__main__':
main()
# *** End of Program ***
# ********************************************************************************
# ********************************************************************************
Categories: Uncategorized

