Seltsames Problem mit Software-PWM

  • So, jetzt hab' ich da auch mal ein Problem - ein sehr merkwürdiges mit ner Software-PWM...


    hab' das jetzt mal nicht bei "Anfänger" geschreiben, weil: 1. Ich bin kein "wirklicher Anfänger" mehr, was µC betrifft, 2. es handelt sich nicht um ein Anfänger-Problem wie "Timer läuft nicht", "Was sind Fuse-Bits" o.ä., sondern um ein echt komisches Phänomen, 3. ich würde gerne auf Anfänger-Kommentare á la "schau' mal bei Microcontroller.net" etc. verzichten...


    Zur Sache: ich habe, um meine Dimmerkurve mal zu überprüfen, das Ganze (Beschreibung im anderen Thread) schnell umgebaut: noch ne grüne LED statt der roten hin, diese fadet ohne, die andere mit Dimmerkurve - zum Vergleich.


    Da ist mir dann aufgefallen: im unteren Bereich flackert das Ganze gewaltig - komisch! - dachte mir zuerst, vielleicht ist das bei dem Rainbow-Fader nur nicht aufgefallen, weil da ja immer eine LED zusätzlich voll an war...


    Habe dann mal (weil ich mir irgendwie dachte, vielleicht sieht man die 244 HZ PWM-Frequenz bei ganz kleinen Helligkeiten ja doch noch?!?!) die erste LED auf nen kleinen Wert (2) festgesetzt. Folgendes Ergebnis: das Ganze flackert nicht mehr, nur wenn die fadende LED ganz "unten ist", "stolpert" sie irgendwie, und die andere (die auf einen festen Wert gesetzt ist, das Register wird für nix anderes benutzt) flackert mal kurz...


    Da ich dachte, dass das was mit der Dimmerkurve zu tun haben könnte, hab' ich die rausgeschmissen, Programm immer weiter vereinfacht, ist jetzt nur noch ne PWM-Routine, ein Register fest auf "5", das andere fadet (ganz langsam, damit man's sieht) von 0 auf 9 und wieder zurück - siehe hier:


    [code:1]
    .include "m8515def.inc"


    ;-------------------------------------------------------------------------------
    ; Register etc. definieren
    ;-------------------------------------------------------------------------------


    .def temp0 = R16
    .def temp1 = R17
    .def temp2 = R18
    .def temp_ZL = R1
    .def temp_ZH = R2
    .def LED1 = R20
    .def LED2 = R21
    .def PWM_Count = R23


    ;-------------------------------------------------------------------------------
    ; Interrupt-Vektor-Tabelle Mega 8515
    ;-------------------------------------------------------------------------------


    .CSEG


    .org 0x0000


    rjmp Start ; Reset Handler
    reti ; External Interrupt Request 0
    reti ; External Interrupt Request 1
    reti ; Timer/Counter1 Capture Event
    reti ; Timer/Counter1 Compare Match A
    reti ; Timer/Counter1 Compare Match B
    reti ; Timer/Counter1 Overflow
    rjmp ISR_PWM ; Timer/Counter0 Overflow --> PWM-Routine
    reti ; Serial Transfer Complete
    reti ; Rx Complete
    reti ; Data Register Empty
    reti ; Tx Complete
    reti ; Analog Comparator
    reti ; External Interrupt Request 2
    reti ; Timer/Counter0 Compare Match
    reti ; EEPROM Ready
    reti ; Store Program memory Ready


    ;-------------------------------------------------------------------------------
    ; Stackpointer, Ports setzen
    ;-------------------------------------------------------------------------------


    Start:


    ldi temp0, LOW(RAMEND)
    out SPL, temp0
    ldi temp0, HIGH(RAMEND)
    out SPH, temp0


    ldi temp0, 0b00000001 ; CS00 setzen: Teiler 1
    out TCCR0, temp0


    ldi temp0, (1<<TOIE0) ; Interrupt bei Timer Overflow
    out TIMSK, temp0


    sei ; Interrupts aktivieren


    ldi temp0, 0xff
    out DDRA, temp0 ; PortA auf Ausgang (PWM-Ausgang)


    ;-------------------------------------------------------------------------------
    ; LED 2 Auf- und abfaden, LED1 bleibt bei "5"
    ;-------------------------------------------------------------------------------


    Fade_Loop:


    ldi LED1, 5
    ldi LED2, 0

    Fade_an:


    rcall warten
    inc LED2
    cpi LED2, 9
    brlo Fade_an


    Fade_aus:


    rcall warten
    dec LED2
    brne Fade_aus


    rjmp Fade_Loop


    ;-------------------------------------------------------------------------------
    ; ISR für Software-PWM
    ;-------------------------------------------------------------------------------


    ISR_PWM:

    push temp0
    in temp0, SREG
    push temp0

    ldi temp0, 0b00000011 ; Grundzustand 1 = LED an, 0 = LED aus

    inc PWM_Count ; PWM Zähler von 0 bis 255 durchzählen


    cp PWM_Count, LED1 ; Ist der Grenzwert für LED1 erreicht?
    brlo PWM_LED2 ; nein, weiter zu LED2
    andi temp0, 0b11111110 ; ja, LED1 aus


    PWM_LED2:

    cp PWM_Count, LED2 ; Ist der Grenzwert für LED2 erreicht?
    brlo PWM_Ausgabe ; nein, weiter zur Ausgabe
    andi temp0, 0b11111101 ; ja, LED2 aus

    PWM_Ausgabe: ; Neue Bitbelegung ausgeben


    out PORTA, temp0

    pop temp0
    out SREG, temp0 ; Statusregister + Temp0 wiederherstellen
    pop temp0

    reti


    ;-------------------------------------------------------------------------------
    ; Warteschleife
    ;-------------------------------------------------------------------------------


    warten: ; 3 verschachtelte Warteschleifen


    push temp2 ; Statusregister + Temp sichern
    push temp1
    push temp0
    in temp0, SREG
    push temp0


    ldi temp0, 255 ; 255 Wiederholungen


    loop0:


    ldi temp1, 255 ; 255 Wiederholungen


    loop1:


    ldi temp2, 60 ; 60 Wiederholungen


    loop2:


    dec temp2
    brne loop2


    dec temp1
    brne loop1


    dec temp0
    brne loop0


    pop temp0
    out SREG, temp0 ; Statusregister + Temp wiederherstellen
    pop temp0
    pop temp1
    pop temp2


    ret


    ;-------------------------------------------------------------------------------
    [/code:1]


    Unten auch noch ein animiertes Gif, auf dem man (leider nicht so toll) den Effekt sieht:


    Die linke LED ist fest auf "5" (von 255), die rechte fadet auf - wenn die rechte ebenfalls "5" erreicht hat, werden beide dunkler, bei "6" bleibt die rechte auf diesem Wert (oder wird evtl. eine Stufe heller, läßt sich nicht so genau erkennen, flackert jedenfalls mal kurz), die linke wird jedoch heller (also heller als davor), ab "7" geht's wieder normal weiter... (da ist dann das Gif zuende)


    Rückwärts das umgekehrte Spiel: bei "5" werden wieder beide dunkler, bei "4" die rechte jedoch wieder heller (obwohl sie ja abfadet), die linke auch wieder (aber dunkler als vorher), dann fadet die rechte bis Null...


    Also irgendwie so, als wenn die rechte kurz mal "hängenbleiben" würde, und die linke so "halb" mitfadet (obwohl an dem Register ja nix geändert wird)...


    also in der Art (links/rechts): 5/0 - 5/1 - 5/2 - 5/3 - 5/4 - 4/3 - 6/5 - 6/7 - 6/8 - ...


    Das mit 5 ist jetzt nur ein Beispiel - das geht mit jeder anderen Zahl zwischen 1 und 254 auch - immer, wenn beide LEDs die selbe Helligkeit haben, tritt dieses Phänomen auf...


    Und ich habe keine Ahnung, woran das liegen könnte - stehe irgendwie total auf der Leitung, evtl. sehe ich auch nur den Wald vor lauter Bäumen nicht?!?! Habe jetzt schon über drei Stunden da erfolglos rumprobiert...


    Dass es was mit der Hardware zu tun hat, schließe ich aus: der Effekt ist immer gleich, egal ob mit den Rebels über Mosfet und LM 317 (auf 200 mA) oder mit "kleinen" LEDs direkt am µC - sowohl gegen Gnd als auch gegen Vcc (da PWM-Polarität natürlich umgekehrt). µC hab' ich auch schon gewechselt, um da einen Schaden dran auszuschließen... Netzteil liefert 20 W, stabilisiert, fetter Siebelko (3.300 µF), µC hat ein eigenes NT mit 7805 etc.


    Fusebits sind auch richtig gesetzt, der µC läuft auch wirklich auf 16 MHz... Statusregister und sonstige verwendete werden in den Subroutinen immer brav gesichert...


    Ich habe keine Ahnung, was da vor sich geht....?

    Bilder

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

  • Hallo Pesi,


    schwierig zu sagen, was da genau vor sich geht.


    Sicher ist auf jeden Fall, dass Software-PWM generell zum Jittern neigt, insbesondere bei der von dir gewählten Implementation. Aber das sollte eigentlich nur bei Wertewechseln kurz zu Flackerern führen können, bei stabilen PWM-Werten sollte es nichts ausmachen nach Theorie. Trotzdem gebe ich dir einen Tipp für eine weitgehend jitter-minimierte Lösung. Du kannst ja mal ausprobieren, ob das etwas bringt: Die Register LED1 und LED2 sollten in der ISR nicht direkt für den Vergleich verwendet werden, sondern du solltest noch zwei Register (Kopien) dazu nehmen, LED1_pwm und LED2_pwm zum Beispiel. Die Werte der Register LED1 und LED2 kopierst du dann in der ISR jeweils nur beim Zählwert 0 in die entsprechenden ..._pwm Register und verwendest die ..._pwm Register für die Vergleiche. Dies verhindert, dass ein Wertewechsel mitten im PWM-Zyklus stattfinden und somit zu einer kurzen, invaliden Impulsdauer beim PWM-Wert-Update führen kann.


    Weiter könntest du zum Test versuchen, die LED-Ausgänge per SBI und CBI zu setzen resp. löschen, und zwar CBI jeweils direkt beim Vergleich. Damit würde nur einmal bzw. zweimal pro Zyklus auf Port A schreibend zugegriffen. Ich wüsste zwar jetzt auch nicht, warum ein durchgehendes Schreiben grösstenteils gleicher Werte in Port A (wie bei dir jetzt) etwas ausmachen sollte, aber machmal ist bei µCs eben viel Voodoo dabei :wink: . Mit dem CBI direkt beim Vergleich wäre auch die Gleichzeitigkeit des Toggles nicht mehr vorhanden, womit dann auch dies als Einflussmöglichkeit getestet werden könnte.


    Drittens kommen mir da noch Einflüsse parasitärer Kapazitäten und Induktivitäten (Zuleitungen, LED-Beinchen etc.) in den Sinn. Die minimale Pulsbreite bei einer 8-Bit-PWM von 244 Hz beträgt ja rund 16 µs. Wenn die Pulsbreite in dem Bereich (ca. +- 8 µs) schwanken/schwingen würde, könnte das Helligkeitsschwankungen im unteren Bereich (kleine PWM-Werte) erklären. Hast du dir die Pulse bei den versch. Werten mal mit einem Oszi direkt an der LED angesehen? Vielleicht kann man ja dabei was erkennen, wenn die Helligkeit verrückt spielt.


    Das sind so mal ein paar Dinge, die du anschauen könntest. Mehr fällt mir dazu im Moment leider auch nicht ein.


    Gruss
    Neni

  • Hi Neni, etwas verspätet vielen Dank für die ganzen Tipps!


    Habe die (fast, bis auf das Messen) alle mal ausprobiert... im Zuge dessen hat sich herausgestellt, dass es wohl doch ein Hardware-Problem ist.... :-%


    Das scheint wohl an meiner "Endstufe" (Schaltplan in diesem Rainbow-Fader-Thread) zu liegen...


    Dass die LEDs "direkt" am µC Dienstag Nacht auch geflackert haben, keine Ahnung, evtl. hat sich das irgendwie ausgewirkt, dass die Fet-Endstufe noch mit an Vcc gehangen ist, oder ich hab's mir aus lauter Müdigkeit und Ärger auch nur eingebildet... 8-[


    Woran das jetzt aber liegt, keine Ahnung - habe leider kein Oszi, um da was zu messen... evtl. findet da ein kapazitives Übersprechen statt, die Signale laufen über ca 15 cm parallel in einem Flachbandkabel von der µC- zur Endstufenplatine....


    Die FET-Eingänge sind halt auch sehr "empfindlich", da reicht es schon, mit dem Finger hinzulangen (also wenn sie offen sind), um den FET durchzuschalten... evtl. vergrößere ich auch mal die Gate-Widerstände... oder probier' nen anderen FET


    Oder es kommt irgendwie die LM317-KSQ in's schwingen... wurde hier auch schon mal angesprochen, dass die für PWM eigentlich nicht so ideal sei, da die *eigentlich* zu lang braucht, um den Strom nachzuregulieren... aber viele verwenden sie ja trotzdem, anscheinend ohne Probleme... aber ich bin da eh grad' an was anderem dran...


    Und das war wohl en Mißverständnis: der Effekt tritt nicht nur im unteren Helligkeitsbereich auf, sondern immer dann, wenn beide LEDs ungefähr gleich hell sind - irgendwie so, wie wenn die eine die andere "ein Stück weit mitziehen" würde...


    Achja, woher ich das weiß, dass es an der Hardware liegt: ich habe zwischenzeitlich ein kleines "Versuchscluster" gebaut, einfach 3 Stück 5-mm-LEDs in rot, grün, blau über BC 337 angesteuert. Da läuft auch die "alte" Software-PWM völlig ohne Flackern, Ruckeln, Jittern...


    Nur noch als Anmerkung wegen Software:


    Das mit dem Register kopieren macht bei mir keinen (zumindest sehe ich ihn nicht) Unterschied... dazu habe ich mir mal folgendes überlegt, was passiert, wenn der Wert während des PWM-Zyklus geändert wird:


    1. PWM_Count ist z.B. bei 128, LED ändert sich z.B. von 100 auf 50 (oder umgekehrt): Keine direkte Auswirkung, neuer Wert "gilt" ab nächstem PWM-Zyklus


    2. PWM_Count ist bei 128. LED ändert sich von 140 auf 200 (oder umgekehrt): Keine direkte Auswirkung, neuer Wert gilt jedoch schon für diesen PWM-Zyklus


    3. PWM_Count 128, LED ändert sich von 200 auf 100: die LED geht sofort (also bei 128) aus, also weder beim "alten" noch "neuen" Wert - der neue gilt ab dem nächsten Zyklus


    4. PWM_Count 128, LED ändert sich von 100 auf 200: da geht die LED, die ja schon aus war, bei meinem Algorithmus wieder an, bei 200 dann wieder aus, ist in diesem PWM-Zyklus also insg. 172 Durchgänge lang an...


    bei 3. und 4. ergibt sich also ein "Zwischenwert", bei 4. verbunden mit einer kurzzeitigen Verdopplung der PWM-Frequenz... aber das dürfte ja nicht so schlimm sein, ist ja nicht so, wie wenn die LED mal kurz komplett aus wäre oder voll aufleuchten würde...


    Wegen dem CBI: ich hab' das mal so ausprobiert, bei PWM-Zähler 0 die Pins einschalten, bei CompareMatch wieder aus - da reichen aber die paar Takte, die der Pin auch bei 0 an ist, dass die LED immer leicht glimmt - müsste man also noch ne Abfrage einbauen, dass der entsprechende Pin bei "0" erst gar nicht eingeschaltet wird, das wird mir dann schon zu aufwändig :wink:


    Ausserdem, wenn ich jetzt z.B. ne 9-Kanal-PWM habe, wird bei der CBI-Direkt-Methode bei gleichen Werten die 9. LED 27 Prozessortakte später als die erste ausgeschaltet; da 3 Takte bereits für ein leichtes Glimmen reichen, könnte das doch bei kleinen Werten durchaus einen wahrnehmbaren Helligkeitsunterschied geben....?


    Das jetzt nur mal als Gedankenanregung von mir - jetzt muss ich mal sehen, was ich mit meiner FET-Endstufe mache...

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

  • Hi,


    also ich habe derzeit das gleiche Problem. Funktioniert eigentlich alles einwandfrei, zumindest Softwaretechnisch.


    Hab folgendes Problem: hab nen atmega am ausgang nen irlz34n transistor und dann mittels lm317 einen konstantstrom für die LEDs (k2). Das ganze über DMX. Wenn ich mir jetzt die pwm im oszi anseh schaut alles einwandfrei aus.


    0-50%: LED leuchtet einwandfrei ohne zu flackern


    50-80%: LED flackert leicht


    80%-100% LED leuchtet wieder flackerfrei.


    Ich glaub das liegt an den LM317, bin mir aber nicht ganz sicher, denn wenn die Software falsch wäre würde die led ja eher im unteren Bereich flackern!!


    ODER????

  • JAAAAA!!!!


    8o


    hat doch tatsächlich jemand den Uralt-Trööt ausgegraben :D - OK, ich habe damals ja auch nix mehr dazu geschrieben....


    Bei mir war eher das Problem, dass Flackern auftrat wenn alle Kanäle den selben Wert hatten - ich benutze dieses Teil nicht mehr, habe auch nix mehr dran gemessen o.ä. (kein Oszi), vermute das Problem aber auch bei den LM 317 - die sind wohl nicht wirklich dafür ausgelegt, so schnell ein- und ausgeschaltet zu werden... und wenn dann noch mehrere zum selben Zeitpunkt, kann schon sein, dass die dann in's Schwingen kommen o.ä.


    ich benutze ja schon seit längerem Diese "Endstufe" (unteres Bild), da gibt's keine Flackerprobleme mehr..


    Weiterer Vorteil: den Fet hast Du ja eh' schon zum schalten, nur noch nen BC 549 und nen Widerstand dazu, billiger als ein LM 317, und hat auch weniger Dropout...

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!