Forum: Analoge Elektronik und Schaltungstechnik PWM Dimmer - unregelmäßiges Aufflackern


von Bastler143 (Gast)



Lesenswert?

Hallo!

Ich versuche einen 4-Kanal PWM Dimmer für 12V Halogenlampen zu bauen, 
der einen automatischen Lichtablauf steuern soll.
Es soll periodisch "sanft" zwischen 2 verschiedenen Lampen umgeschaltet 
werden (eine faded-out, die nächste faded-ein) mit einer kleinen Pause 
dazwischen.
Folgende Parameter möchte ich dabei mit Potis einstellen: Maximale 
Helligkeit, Geschwindigkeit des Faden/Dimmen, Pause dazwischen.

Beschreibung des Problems:
-> Während des Dimmens blitzt die jeweilige Led kurz hell auf - das 
passiert in unregelmäßigen Zeitabständen
-> Im Anhang befindet sich ein Video davon, damit alle wissen, wovon ich 
spreche.

Beschreibung der Hardware (Auswahl der Bauteile aufgrund von dem was ich 
gerade zu Hause hatte):
-> AtMega8 (4,7µF direkt an den Versorgungspins)
-> 4x BUZ11 MosFETs
-> 2x TC4424 als Treiber für die MosFETs
-> 3x Trimpoti (10k)
-> 7805 zur Versorgung des Atmegas (100µF zur Stabilisierung auf 
Eingangsseite, 47µF auf Ausgangsseite)
-> Aufgebaut ist das ganze auf Lochrasterplatine mit 0,5mm² Kupferdraht 
auf der Rückseite
-> Zum Testen verwende ich als Leuchtmittel rote LEDs mit passendem 
Vorwiderstand, da mir die Halogenlampen auf dauer zu hell sind beim 
programmieren.

Beschreibung der Software:
-> Programmiert in C mit AtmelStudio
-> Die 3 Potis werden periodisch nacheinander eingelesen (conversion für 
den nächsten kanal wird im ADC-Interrupt gestartet)
-> Gedimmt wird mittels Zählvariable die im Timer-Overflow-Interrupt 
erhöht wird
-> Gedimmt wird durch Vergleich der Vorgabewerte für die Helligkeit mit 
der Zählvariable und entsprechendem Schalten der Ausgänge in der ISR.
-> Maximalhelligkeit wird über den Maximalwert der Zählvariable 
bestimmt.

Um das Problem zu beheben habe ich bisher folgendes erfolgslos 
ausprobiert, bzw ist noch folgendes zu sagen:
-> ADC deaktivieren und die Werte fix vorgeben (Vermutung war, dass der 
ADC Interrupt irgendwie den Timer-Interrupt verhindert und so ab und zu 
das Schalten eines Ausganges verhindert wird)
-> Verschiedene Spannungsquellen (Stabilisiertes Netzgerät, Eigenbau 
Netzgerät, Labornetzgerät), aber immer das selbe Problem
-> Der Atmega resettet nicht, das merke ich daran, da ich beim 
Einschalten eine spezielle Blinksequenz habe um das zu erkennen.
-> Es liegt nicht daran, dass der MosFET bzw dessen Treiber manchmal 
einfach nicht schaltet. Das habe ich überprüft indem ich eine Led am 
Ausgangspin des Atmegas gehängt habe - diese blitzt auch manchmal auf.

Ich hoffe, dass ihr mir Hinweise geben könnt, wo ich das Problem noch 
suchen kann!!!
Danke und liebe Grüße aus Österreich!

P.S.: Weiters finden sich am Board folgende Bauteile:
-> ein 75176er, weil ich den Dimmer später auch per DMX ansteuern will
-> zwei Jumper: zum Laufrichtung umschalten und zum einschalten vom 
DMX-Mode
-> eine LED die den Zustand des ersten Kanals anzeigt.

P.P.S.: letztens sind mir meine TC4424 plötzlich kaputt gegangen. Nach 
dem Austausch funktioniert wieder alles. Kann mir vielleicht auch wer 
verraten, ob ich im Leistungsteil noch zusätzliche Bauteile benötige 
(Leider bin ich bei Leistungselektronik nicht so gut drauf)?

: Verschoben durch Admin
von Bastler143 (Gast)


Lesenswert?

Hallo!

Ich habe nun eine Lösung gefunden, aber das Problem noch nicht wikrlich 
identifiziert!?

Meine Lösung ist, dass ich im Timer-Overflow-Interrupt die 
Zählervariable nicht auf Gleichheit mit dem gewünschten Helligkeitswert 
prüfe, sondern auf "Größer Gleich"...

Also nicht:
1
if(timer_counter == output_pwm_analog_value_1) {
2
    output_pwm_set_digital_1(0);
3
}
sondern
1
if(timer_counter >= output_pwm_analog_value_1) {
2
    output_pwm_set_digital_1(0);
3
}
.

Leider wird dadurch die Durchschnittliche Laufzeit von der ISR stark 
erhöht, was zu einer stark verringerten Maximalgeschwindigkeit des 
Dimm-Vorganges führt. Aber auch dafür konnte ich eine Lösung finden: 
Nämlich, dass ich zuerst prüfe, ob der Ausgang überhaupt noch ON ist...
Das sieht dann so aus:
1
if(output_pwm_digital_state_1 && timer_counter >= output_pwm_analog_value_1) {
2
    output_pwm_set_digital_1(0);
3
}

Das führt zwar jetzt zu einem annehmbaren Fade, aber mir ist noch nicht 
klar, warum das überhaupt notwendig ist!?

Kann mir noch irgendwer erklären, warum anscheinend die Gleichheit der 
beiden Variablen nicht in jedem Durchlauf eintritt, und es daher zu 
einem Flackern kommt?

Danke!

P.S.: Wenn ich für dieses Projekt schon einen Thread eröffnet habe, wärs 
auch ganz nett, wenn mir wer sagen könnte, ob ich am Leistungsteil 
(TC4424 und BUZ11) noch irgendwelche weiteren Bauteile benötige???

von Markus (Gast)


Lesenswert?

Warum ist das hochzählen in einem Else...

von Bastler143 (Gast)


Lesenswert?

Markus schrieb:
> Warum ist das hochzählen in einem Else...

Weil sonst der "erste" Durchlauf mit dem Wert 1 anstatt 0 geschieht.

1. Alternative: im if-Zweig den Zählerwert auf -1 setzen.
2. Alternative: das if mit ">" (anstatt ">=") am Beginn der ISR.

Hmmm - wenn ich drüber nachdenke, gefällt mir die 2. Alternative 
eigentlich am Besten - damit spare ich gegenüber meiner jetztigen 
Variante auch einen Sprungbefehl im übersetzten Code... Oder?

Danke für den Hinweis, ich werde die Änderung umsetzen - aber das hat 
leider nichts mit meinen Fragen zu tun...

mfg

von Michael (Gast)


Lesenswert?

Bastler143 schrieb:
> -> AtMega8 (4,7µF direkt an den Versorgungspins)
Wenn das ein 0815-C ist, wird der kaum dafür geeignet sein.
100nF o.ä. wären eher geeignet, um kurzzeitige Lastspitzen aufzufangen.

> -> 7805 zur Versorgung des Atmegas (100µF zur Stabilisierung auf
> Eingangsseite, 47µF auf Ausgangsseite)
Der 7805 ist ein Regler und als solcher i.A. nicht besonders glücklich 
über große kapazitive Lasten. Was sagt das Datenblatt des Herstellers?

Dein 12V-Gnd sind mit µC-Gnd verbunden?

Dein Code geht so nicht mal durch den Compiler. Wie soll man da etwas 
testen, ohne groß mit Basteln anzufangen.

von c-hater (Gast)


Lesenswert?

Bastler143 schrieb:

> Ich habe nun eine Lösung gefunden, aber das Problem noch nicht wikrlich
> identifiziert!?

Das Problem ist einfach, daß die Analogwerte nicht konstant sind, 
sondern immer geringfügig "wackeln", insbesondere ein Wackeln im letzten 
Digit ist praktisch unvermeidbar. Dadurch kann es zu folgendem 
(beispielhaften) Ablauf kommen:

ADC-ISR:
Analogwert=50

Timer-ISR:
Zähler+=1 (neuer Zählerstand=47)
Prüfung auf Abschaltbedingung negativ->LED bleibt an

Timer-ISR:
Zähler+=1 (neuer Zählerstand=48)
Prüfung auf Abschaltbedingung negativ->LED bleibt an

Timer-ISR:
Zähler+=1 (neuer Zählerstand=49)
Prüfung auf Abschaltbedingung negativ->LED bleibt an

ADC-ISR:
Analogwert=49 (wackeln im letzten Digit)

Timer-ISR:
Zähler+=1 (neuer Zählerstand=50)
Prüfung auf Abschaltbedingung negativ->LED bleibt an

Und nun bleibt die LED bis zum Ende des Zyklus an, weil nie mehr die 
Abschaltbedingung eintritt. ->Lampe blitzt hell auf.

> Leider wird dadurch die Durchschnittliche Laufzeit von der ISR stark
> erhöht

Deklariere mal die output_pwm_set_digital_x-Routinen als 
Inline-Funktionen, dann sollte sich dieses Problem deutlich entschärfen.

...

Die schönere Lösung wäre allerdings, die Ursache zu bekämpfen. Und das 
erreicht man dadurch, daß man dafür sorgt, daß sich während eines 
PWM-Zyklus die zum Vergleich benutzten ADC-Werte nicht mehr ändern 
können. Dazu benutzt man das gute alte double buffering.

Man erzeugt also einen zweiten Satz Variablen. Die ADC-ISR schreibt 
ausschließlich in den ersten Variablensatz. Die Timer-ISR holt die 
Vergleichswerte für die PWM hingegen ausschließlich aus dem zweiten 
Variablensatz. Alles, was nun noch fehlt, ist ein Umkopieren der Werte 
aus dem ersten in den zweiten Variablensatz im richtigen Moment, nämlich 
beim Start des PWM-Zyklus, also genau dort, wo du alle Ausgänge 
einschaltest.

->Problem an der Wurzel gelöst.

von Bastler143 (Gast)


Lesenswert?

Hallo!


Michael schrieb:
> Wenn das ein 0815-C ist, wird der kaum dafür geeignet sein.

OK - Werde ich ändern - mach ich immer so und hatte noch nie Probleme!

Michael schrieb:
>Der 7805 ist ein Regler und als solcher i.A. nicht besonders glücklich
>über große kapazitive Lasten. Was sagt das Datenblatt des Herstellers?

Datenblatt sagt, dass man beim Eingang und beim Ausgang einen C 
hinhängen soll - jedoch werden dort kleinere Werte vorgeschlagen... 
Werde bei der nächsten Platine Bauteilwerte im Bereich der Vorschläge im 
Datenblatt wählen.

Michael schrieb:
> Dein 12V-Gnd sind mit µC-Gnd verbunden?

Ja.

c-hater schrieb:
>Das Problem ist einfach, daß die Analogwerte nicht konstant sind,
>sondern immer geringfügig "wackeln", insbesondere ein Wackeln im letzten
>Digit ist praktisch unvermeidbar.

Danke für den Hinweis und deine Ausführliche Erklärung, aber wenn du dir 
den Code etwas genauer ansiehst, merkst du eventuell (code is ja nicht 
vollständig), dass ich 2 der 3 eingelesenen Analogwerte nicht als 
PWM-Tastwerte (Helligkeitswerte) benutze, sondern als delay um die 
Ablaufgeschwindigkeit zu steuern. Der dritte Analogwert dienst zwar als 
max. Zählerwert, bei dem der Zähler wieder zurückgesetzt wird, dort ist 
aber genau das, was du als "double buffering" Bezeichnest, umgesetzt. 
Also ich lese den ADC-Wert nur am Beginn eines PWM-Zyklus (beim 
Zählerstand=0) in eine zweite Variable ein, die ich als Vergleichswert 
in der timer ISR benutze. Also ist meines Verständnisses nach das 
Flackern nicht aufgrund vom Rauschen des ADC.

Mein Problem ist also noch immer nicht gefunden....
Es darf weiter spekuliert werden!

Danke an alle die sich die Mühe gemacht haben und meine Uploads zum 
Thread betrachtet haben!

mfg

von Stefan (Gast)


Lesenswert?

Das sieht mir nach dem typischen Fade-out Flackern bei einer einfachen 
PWM aus.

Problem (8-Bit PWM, Match bei 10):
1. Zyklus beginnt -> LED ein
2. Zähler erreicht 10 -> LED aus
3. Zähler läuft über -> neuer Zyklus beginnt

So, wenn jetzt aber der Zähler z.B. 8 erreicht hat und nun
der Match Wert per SW auf z.B. 5 verringert wird, leuchtet die
LED während des gesamten Zyklus da mit "==" kein Match auftritt. Mit dem 
">=" umgehst du das Problem.

Einige HW PWM lösen das indem sie einen neuen Match Wert erst zu Beginn 
eines neuen Zyklus übernehmen. Während des aktuellen Zyklus wird der 
alte Wert verwendet.

von c-hater (Gast)


Lesenswert?

Bastler143 schrieb:

> Danke für den Hinweis und deine Ausführliche Erklärung, aber wenn du dir
> den Code etwas genauer ansiehst, merkst du eventuell (code is ja nicht
> vollständig)

Woran man mal wieder sehen kann, wie wichtig es ist, daß der 
vollständige Code gepostet wird.

> Mein Problem ist also noch immer nicht gefunden....
> Es darf weiter spekuliert werden!

Hättest du den vollständigen Code gepostet, bräuchte man nicht zu 
spekulieren.

von Bastler143 (Gast)


Lesenswert?

Hallo!

Stefan schrieb:
> Das sieht mir nach dem typischen Fade-out Flackern bei einer einfachen
> PWM aus.

Danke - es scheint als wäre damit die Ursache geklärt.
Als Lösung werde ich das Dubble Buffering anwenden, wie es c-hater 
beschrieben hat.

mfg

P.S.: Es war alles, was man zur Auffindung des Problems benötigte im 
Codeauszug vorhanden.

P.P.S.: Leistungselektronik: passt das so? Oder brauche ich noch Diode, 
Widerstand oder C irgendwo dazu um meinen Treiber vor einem erneutem 
Tode zu schützen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.