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 6 hours 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 5 hours 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 5 hours ago
-
@RAS, I skimmed you Rpi4B PCA9685 PWM log file again. I was a bit confused. I noticed that you said PWM frequency to 1.6 kHz. I forgot if I see the root frequency to around 50Hz for servos. Perhaps I forgot the details. I also found your setting the PCA6895 registers directory. I usually call the registers by name, to avoid any typos and easy troubleshooting. Perhaps I might show you my PCA9685 programming. BTW, I do use the scope to check out the 500uS to 2000uS pulses. Do you also use a scope or analyzer just to make sure? – tlfong01 5 hours ago
-
@RAS, I checked my PCA9685 config function and found that I indeed base frequency. Perhaps I abstracted to often and forgot the original procedure. BTW I could no longer paste any more long code to my answer because I am hitting the Rpi Stack Exchange’s 30k word limit. So I am listing my program as a Penzu entry: (1) penzu.com/p/3a36a526. You will find that in my program I call everything by name, to prevent typos, easy troubleshooting, and newbie understanding . – tlfong01 4 hours ago
Question
Problem in porting Rpi3B+ python GPIO PWM servo programs to Rpi4B
Answer
Your Rpi3B+ log file shows DMA channels are use to PWM control servo. But the Rpi4B log file shows PCA9685 PWM GPIO is replacing DMA PWM. You need to show your program list to confirm this.
If PCA9685 is your project decision, I would recommend to refer to MagPi84 Circuit Python servo tutorial and use AdaFruit’s open hardware/software PCA9685 PWM Controller HAT, and quad servo HAT, and their python servo libraries.
My servo project here is inspired by them. Please see Reference (2) for more details.
References
(1) Rpi4B PCA9685 PWM Controller driving 4 TowerPro MG996R Servos – tlfong01
(2) PCAS9685 PWM Controller Installation Notes – tlfong01
(3) 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

