joan2937 / pigpio

pigpio is a C library for the Raspberry which allows control of the General Purpose Input Outputs (GPIO).
The Unlicense
1.45k stars 407 forks source link

Unclean PWM at certain frequencies. #592

Open nfstoney opened 10 months ago

nfstoney commented 10 months ago

Hello folks,

Below I'll tell you about strange behavior of the PWM on a PI.

HW: Raspberry Pi CM4108000 OS: Bullseye, Linux raspberrypi 5.10.92-v7l+ #1514 SMP Mon Jan 17 17:38:03 GMT 2022 armv7l GNU/Linux pigpio: v79

When the generated PWM signal is precisely analyzed by the following code, an unclean PWM signal is created. Pulses are missing and suspicious spikes are present. Which is also worth mentioning. Depending on the CM4 module, the critical frequency at which the signal becomes unusable is at a different point.. --> See attached PDF NF231206PS_pwm_error.pdf

`

include

include

include

define GPIO_PIN 19 // GPIO-Pin, der für den PWM verwendet wird

int main(int argc, char *argv[]) { int frequency = 16000; // Standardfrequenz 16 kHz float dutyCycle = 50.0; // Standardduty cycle 50%

if (argc >= 3) {
    frequency = atoi(argv[1]); // Frequenz von Befehlszeilenargument erhalten
    dutyCycle = atof(argv[2]); // Duty Cycle von Befehlszeilenargument erhalten
}

if (gpioInitialise() < 0) {
    fprintf(stderr, "Fehler beim Initialisieren von pigpio\n");
    return 1;
}

if (gpioSetMode(GPIO_PIN, PI_OUTPUT) != 0) {
    fprintf(stderr, "Fehler beim Einstellen des Pin-Modus\n");
    gpioTerminate();
    return 1;
}

// PWM initialisieren
if (gpioHardwarePWM(GPIO_PIN, frequency, (unsigned int)(dutyCycle * 10000)) != 0) {
    fprintf(stderr, "Fehler beim Einstellen des PWM\n");
    gpioTerminate();
    return 1;
}

printf("PWM gestartet mit Frequenz: %d Hz und Duty Cycle: %.2f%%\n", frequency, dutyCycle);

// Warte, bis eine Eingabe erfolgt, um das Programm zu beenden
printf("Drücke Enter, um das Programm zu beenden...");
getchar();

// PWM beenden
gpioHardwarePWM(GPIO_PIN, 0, 0);

gpioTerminate(); // GPIO aufräumen
return 0;

} `

If I start the PWM via file access like in the script below, then I get a beautiful PWM as it should be. config.sys --> dtoverlay=pwm,pin=19,func=2 echo 1 > /sys/class/pwm/pwmchip0/export echo 41700 > /sys/class/pwm/pwmchip0/pwm1/period echo 20000 > /sys/class/pwm/pwmchip0/pwm1/duty_cycle echo 1 > /sys/class/pwm/pwmchip0/pwm1/enable

Can someone recreate this and make improvements?

Kind regards Patrick

TULA1000 commented 8 months ago

I have the same problem. PWM0 on gpio 12 works fine when using sysfs (/sys/class/pwm/pwmchip0/). But when i try to use gpioHardwarePWM with frequencies 880, 10000, 20000... and dutycycle 50% signal becomes wrong. After testing on diffrents CM4 we have it appears that this happens on CM4 2 GB ram (b03140) BUT gpioHardwarePWM works fine on CM4 4 GB (c03140). I don't know why an amount of ram affects this(there are no other diffrences between CM4(there is only one revision of CM4) as far as i know).