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
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???
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
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.
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.
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
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.