Open DanMan32 opened 2 years ago
👍 this is useful. I never tested this with a scope, but now I really would like to track down this bug.
Hm, I'm not able to reproduce the issue. I'm using a Saleae digital analyzer. Setting the frequency=50hz and dc=10% on hardware PWM channel 1:
Similar results with PWM channel 0.
I'm using an RPi 3A. What are you using?
Same issue. DS7102V oscilloscope. A frequency of 30.0Hz at 10% duty cycle has an actual frequency of 32.1Hz. This is on the raspberry pi 4B, using channel 0
More data: In Out 30Hz 10% 32.10Hz 10Hz 10% 10.71Hz 20Hz 10% 21.41Hz 40Hz 10% 42.83Hz 50Hz 10% 53.55Hz 60Hz 10% 64.21Hz 70Hz 10% 74.96Hz 80Hz 10% 85.76Hz 90Hz 10% 96.34Hz 100Hz 10% 107.1Hz
At 10% all frequencies seem to be off by a factor of ~1.071
Huh, okay, so something is definetly up. My partner has a beefy scope, I'll get them to help repro this on our end.
Quick update with my findings. When I cat /sys/class/pwm/pwmchip0/pwm0 it returns the exact period of 35695236. However, when I clone the repository from github and try the same settings (30Hz at 10%) I get the correct value of 33333333. So this only arises when I try to use the pip package.
Edit: Ignore the above, this was only because I was wasn't applying the magic factor of 1.070857091 in the source rep from github.
Edit2: So by running
vcgencmd measure_clock pwm
I was able to get the pwm clock rate which turns out to be 107143064 aka 107.143064MHz which is suspiciously close to the magic factor. I think the clock is supposed to be running at 100MHz. So, essentially the RPi 4B pwm clock is running faster than expected so that is why the frequency doesn't match up. I also found this thread which seems to be related to the issues https://forums.raspberrypi.com/viewtopic.php?t=275199.
I don't really know how to fix this but I suppose that you could always fetch the actual clock frequency and apply a correction factor for the chipsets that need it. I am pretty sure that if you run the measure clock command on your device without issues, it will return something very close to 100MHz. Maybe there is a way to just adjust the clock frequency but I haven't looked into how that could be done.
Very useful, thanks @BasVDriel. Running vcgencmd measure_clock pwm
on an Rpi 3 gives 100000000. So I think the difference is due to Pi 4s vs Pi 3s.
I'll spend some time this week / next week fixing this.
What a great find! For those who need precision this sounds like the way to go and it shouldn't be too hard to implement, assuming the overhead of the lookup is minimal.
Yeah all good, I'd make a pull request if I had time to fix it. But, if someone has a fix ready I can test it on the scope to test the real world accuracy. I only have a Pi 4 though.
Follow-up: working on this issue this week
Hm, so I had a moment to test with with an RPi4, and I'm still not able to fully reproduce it with either hardware pin. Some examples of what I'm seeing:
Some more details:
vcgencmd measure_clock pwm
returns frequency(25)=99997560
or 100010744
cat /proc/device-tree/model
returns Raspberry Pi 4 Model B Rev 1.4
/boot/config.txt
: https://gist.github.com/CamDavidsonPilon/c578170ba6f092f0fd6b0ecfbc97b5a4I would appreciate it if other users could provide the same details!
Still looking into a solution - that forum thread linked above helps. I have a develop
branch on this repo that proposes a WIP fix. You can install this branch with:
pip3 install -U --force-reinstall https://github.com/pioreactor/rpi_hardware_pwm/archive/develop.zip
Using Rigol DS1054Z oscilloscope to measure the PWM output, I found to get 50.0hz, I had to set HardWarePWM to 46.7hz. Setting function to 50hz, which is what is expected for SG-90 servos (really 20mS period), I was getting an output of 53.6hz or 18.66mS.
Otherwise I found this really easy to use and much more stable than software PWM that comes with Python library RPi.GPIO. Too bad RPi only comes with 2 PWM channels, shared with the audio features of the RPi. I would have loved to use this for controlling RGB LED and get more stable results when using vPython.