Softwarepwm vs Hardwarepwm (Code in Python)

  • Hallo zusammen,

    aus gegebenen Anlass habe ich mich gestern etwas mit PWM beschäftigt, und muss gleich vorne Weg sagen, dass ich vom Ergebnis der Softwarepwm enttäuscht bin. Die Codes wurden in dem Versuch sehr einfach gehalten. Die Auslastung der CPU betrug nicht höher 5%


    Softwarepwm:

    Python
    1. import gpiozero
    2. import signal
    3. pwmpin = gpiozero.PWMOutputDevice(18, frequency=25000, initial_value=0.5)
    4. signal.pause()


    Hardwarepwm:

    Python
    1. import pigpio
    2. import signal
    3. pin = pigpio.pi()
    4. pwmpin = pin.hardware_PWM(gpio=18, PWMfreq=25000, PWMduty=500000)
    5. signal.pause()


    Ziel waren in beiden Fällen 25kHz. Was die Softwarepwm hier erstellt ist mir schleierhaft.


    Wer die Möglichkeit dazu hat...erzielt ihr so ein schlechtes Ergebnis mit Softwarepwm?


    Versuch durchgeführt mit Raspberry Pi 3 (Raspbian Stretch)

  • Hi Hofei ,

    hast Du Software-PWM mal mit pigpio probiert? Laut meiner Erfahrungen aus der Vergangenheit sollte das sauberer laufen.


    Du hast bei Software-PWM das Problem der Latenz-Zeiten durch den scheduler. Und die können ganz schön heftig sein. Auf dieses Problem haben wir hier immer hingewiesen, wenn es um Abtast-Raten oder Servo-Steuerungen ging.


    Die Seite von EMLID -> https://emlid.com/raspberry-pi-real-time-kernel/ ist da recht informativ zu dem Thema.


    cu,

    -ds-

  • 25 KHz entspricht 50000 Schaltvorgängen (ein oder aus) pro Sekunde - das sind 20 µs pro Schaltvorgang.

    Der Pi hat im Normalfall durch das Betriebssystem bis zu 400 µs Reaktionszeit.

    Hier findest du realisierbare Programmtaktzeiten - die Signalausgänge wurden mit einem Oszi gemessen und kommen offenbar auch am Ausgang an. Wenn das Betriebssystem aber vorrangige Aufgaben ausführt, wird das schon mal unterbrochen werden (siehe Anmerkung am Ende der Seite).


    Hardware PWM kann der Pi ja nicht. Wenn du dem Problem ausweichen willst, häng einen µC dran, der die Hardware PWM übernimmt. Damit entlastest du auch deinen Prozessor.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Was ich in Beitrag #1 vielleicht besser hätte erwähnen sollen, mir ist bekannt und auch bewusst dass Hardware PWM bessere Ergebnisse liefern als Software PWM.

    Ich hätte bei Software PWM eher mit verzehrten und unregelmäßigen Takten gerrechnet, aber einfach ein gleichmäßig ungefähr sauberer Takt von ca 6kHz war ich doch überrascht.


    Andere Taktfrequenzen habe ich gestern der Zeit geschuldet nicht getestet.


    hast Du Software-PWM mal mit pigpio probiert?

    Leider nein, werde ich aber nachholen!


    Auf dieses Problem haben wir hier immer hingewiesen, wenn es um Abtast-Raten oder Servo-Steuerungen ging.

    Ja ich hätte wirlich in Beitrag 1 erwähnen sollen, dass mir bekannt ist dass SoftwarePWM beim Pi schlechte Ergebnisse liefert, aber das wie find ich eben überraschend.


    Hardware PWM kann der Pi ja nicht.

    Auch hier ist Hardware PWM möglich (GPIO 18), welches auch einwandfrei beim Test funktioniert hat.

    12 PWM channel 0 All models but A and B<br>13 PWM channel 1 All models but A and B<br>18 PWM channel 0 All models<br>19 PWM channel 1 All models but A and B

    Danke an euch beiden für die Links und die weiterführenden Informationen

  • Ups, stimmt. War nur so, dass die Sstandard-GPIO-Lib das nicht unterstützt. Und es gibt auch nur einen Port - wenn du mehr brauchst...

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Ich meine die RPiGPIO - die wird ja in den meisten Anfängertutorials verwendet.

    So weit ich weiß ist PiGPIO standardmäßig installiert, wiringpi dagegen nicht.

    Korrigiere mich, falls ich mich da irre.


    Ich weiß, es gibt noch ca. hunderttausend andere Libraries... Erbsenzähler.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Ich hätte bei Software PWM eher mit verzehrten und unregelmäßigen Takten gerrechnet, aber einfach ein gleichmäßig ungefähr sauberer Takt von ca 6kHz war ich doch überrascht.

    Hofei : Du triffst den Nagel auf en Kopf. Der Scheduler und dessen Latenzen hauen Dir sporadisch größere Pausen (entweder mit Ein- oder mit Auszeiten) in Dein Signal rein (was man aber in Deinem Signal nicht erkennen kann), die langsame Frequenz erklärt sich darüber aber nicht. Du wirst sehr oft sogar lange Passagen finden, wo das Signal das tut, was es soll. Allerdings kann ich mir sehr gut vorstellen, warum der Soft-PWM auf die 6kHz "gedrosselt" ist.


    Wenn ein Core zu viel CPU-Zeit zieht, dann wird er zwangs-preemptet. Das passiert auch Threads der RT-scheduling Policy und ist der Standard bei den Raspbian Desktop-Kerneln. Wenn man also als Bibliotheksprogrammierer Rechenzeit aktiv per While-Schleife verheizt, um aktiv auf den nächsten Takt zu warten, dann rennt man in diese Falle. Um dem zu entgehen, muß man kooperativ Rechenzeit per usleep() oder nanosleep() freigeben. Diese Sleeps wachen aber mit signifikantem Jitter auf. D.h. man kann nicht 2µs Schlafen, sondern z.B. 50µs oder noch mehr. Somit ergibt sich eine Grenze der praktisch erreichbaren Frequenz, will man nicht andererseits in die Schedulerfalle laufen.

    Will ich beispielsweise 140µs schlafen, so mache ich ein usleep(140-50), wache vielleicht nach 97µs auf und verheize dann die restlichen 43µs aktive per while-Schleife, um mit meinem PWM-Signal nach außen schön äquidistant zu wirken. Das wäre jedenfalls eine Erklärung auf "unterer" Ebene.

    Lies mal die Kapitel "Problemfall 1/2 - Der Linux Scheduler", da habe ich die hier dargestellten Hintergründe mal vermessen.