Hallo zusammen, habe mir die 3-Kanal Dimmer Steuerung von http://www.unmuth.de/technik/projekte.htm, etwas erweitert auf 8 Kanäle, nachgebaut. Allerdings mit einem Atmega32. Soweit sogut, Hardware steht. Ein einfaches Testprogramm für einen Kanal läuft auch prima. Sprich: Interupt bei Nulldurchgang rising und dann einen Timer Interuppt aufziehen, der nach Ablauf den Triac zündet. Jetzt stehe ich vor dem Problem, bei einem Nulldurchgang mehrere Triacs zeitversetzt zünden zu lassen. Habe mir die Doku von unmuth mehrmals durchgelesen, komme aber auf keinen vernünftigen Ansatz. Vielleicht kann mir hier jemand einen Tip zu Realisierung geben. Btw. ich arbeite mit Bascom, erwarte aber jetzt keine fertige Routine :) Ein Ansatz oder eine Idee würde mir schon helfen. Gruß Frank
du brauchst doch nur die zündwinkel aufsteigend ordnen und dann jeweils mit nem timer jeden triac nacheinander zünden
Da der AVR sich sowieso langweilt, reicht es auch, alle Zündzeitpunkte zu jedem Zündwinkel zu vergleichen.
Also nach dem Nulldurchgang einen Interrupt Timer starten für den ersten Triac und nach dem zünden wieder einen Interrupt Timer für den zweiten usw. ?
Nach dem Nulldurchgang einen Timer starten, der bis zum nächsten Nulldurchgang 255 Interrupts auslöst. Macht dann 50Hz 2 255 = 25500 Interrupts pro Sekunde; bei 16MHz Systemtakt hätte jeder Interrupt dabei knapp 630 Takte zur Verfügung. Ich glaube, das reicht...
Ok, glaube das ich es verstanden habe. Nulldurchgang startet einen Timer. Bei jedem overflow wird ein 8bit Zähler incrementiert. Anhand des Zählers mache ich dann einfach if Abfragen und zünde dann zum vorgegebenen Wert. Klingt logisch :) Besten Dank für eure Hilfe
Sodele, den ganzen Tag gebastelt..aber leider funktioniert es nicht so wie es soll. Das Problem ist nun, dass der Dimmvorgang immer bei A=80 beendet ist. Sprich die Lampe ist aus. Von A=1 bis A=30 ist es gleich hell und ab da wird in großen Stufenschritten herunter gedimmt. Eine Änderung im "Load timer0" bringt seltsamerweise überhaupt keine Änderung im Ablauf. Kann es sein dass die IF Abfragen in der "Dimmer_isr" zuviel Zeit beanspruchen? Oder wo könnte sonst das Problem liegen? [code] $regfile = "m32def.dat" $crystal = 16000000 $swstack = 32 Mcusr = &H80 Mcusr = &H80 ' inits Config Lcd = 16 * 2 Config Lcdpin = Pin , Db4 = Porta.2 , Db5 = Porta.3 , Db6 = Porta.4 , Db7 = Porta.5 , E = Porta.7 , Rs = Porta.6 Cursor Off Licht Alias Portd.7 Brunnen Alias Portd.6 Null_detect Alias Portd.2 Kanal1 Alias Portc.0 Kanal2 Alias Portc.1 Kanal3 Alias Portc.2 Kanal4 Alias Portc.3 Kanal5 Alias Portc.4 Kanal6 Alias Portc.5 Kanal7 Alias Portc.6 Kanal8 Alias Portc.7 Taste_dimmer_dunkler Alias Porta.0 Taste_dimmer_heller Alias Portd.5 Taste_dimmer_programm Alias Portd.4 Taste_dimmer_toggle Alias Portd.3 Taste_brunnen_toggle Alias Portd.1 Taste_licht_toggle Alias Portd.0 Config Null_detect = Input Config Licht = Output Config Brunnen = Output Config Portc = Output Config Taste_dimmer_dunkler = Input Config Taste_dimmer_heller = Input Config Taste_dimmer_programm = Input Config Taste_dimmer_toggle = Input Config Taste_brunnen_toggle = Input Config Taste_licht_toggle = Input 'Null_detect = 1 Config Int0 = Rising On Int0 Null_durchgang Enable Int0 Config Timer0 = Timer , Prescale = 8 On Timer0 Dimmer_isr Enable Timer0 Enable Interrupts Dim A As Byte Dim I As Byte Dim Zuendwinkel_triac1 As Byte Dim Zuendwinkel_triac2 As Byte Dim Zuendwinkel_triac3 As Byte Dim Zuendwinkel_triac4 As Byte Dim Zuendwinkel_triac5 As Byte Dim Zuendwinkel_triac6 As Byte Dim Zuendwinkel_triac7 As Byte Dim Zuendwinkel_triac8 As Byte Dim Zuendtimer As Byte Zuendtimer = 174 ' 250 Interrupts innerhalb einer Halbwelle / 10ms/250= alle 40us ein INT Load Timer0 , Zuendtimer Stop Timer0 ' Hauptprogramm Do For A = 1 To 250 Cls Zuendwinkel_triac1 = A Lcd "Dimmstufe :" Lowerline Lcd A Waitms 500 Incr A Next A Loop ' subroutinen Null_durchgang: Portc = 0 Start Timer0 I = 0 Return Dimmer_isr: If I = Zuendwinkel_triac1 Then Kanal1 = 1 Elseif I = Zuendwinkel_triac2 Then Kanal2 = 1 Elseif I = Zuendwinkel_triac3 Then Kanal3 = 1 Elseif I = Zuendwinkel_triac4 Then Kanal4 = 1 Elseif I = Zuendwinkel_triac5 Then Kanal5 = 1 Elseif I = Zuendwinkel_triac6 Then Kanal6 = 1 Elseif I = Zuendwinkel_triac7 Then Kanal7 = 1 Elseif I = Zuendwinkel_triac8 Then Kanal8 = 1 End If Incr I If I = 250 Then Stop Timer0 End If Return [/code}
Hallo zusammen, ich hatte vor ein paar Jahren mal etwas dazu geschrieben. Vielleicht hilft es ja etwas - auch wenn der Code in C geschrieben ist: http://www.hoelscher-hi.de/hendrik/light/ressources.htm Die AN016 dürfte passen - die Sourcen sind daneben, wenn Du auf die CD klickst. Viel Erfolg, Hendrik
Danke für deinen Tip. Habe deinen C Code so gut es geht analysiert. Habe aber trotzdem noch ein paar Fragen: - Während der ISR (INT1_vect) wird der INT1 selbst beendet, warum? - ist es korrekt, dass bei jedem INT in der ISR (TIMER1_COMPA_vect, wo der Dimmcount niedriger ist als Dimmerfield, der Triac gezündet wird? Worthcase = 254mal (besser gesagt: der Gateport ständig 1 wäre) bei einer Halbwelle? Warum genügt nicht einfach ein "=" statt "<=" ? - Wenn ein Interrupt von Timer1 ausgelöst wird, wird doch eigentlich TCNT1 auch zurück gesetzt auf 0 oder? Demenstprechend würde ja der nächste Winkel auf den alten aufaddiert werden (zeittechnisch gesehen). Oder wird nur ein neuer OCR1A geladen und TCNT1 läuft nach wie vor weiter bis 65536?
Ich habe damals die Nullpunkterkennung auf den ICP gelegt, den Timer auf 0 gesetzt und dann immer wieder den Sollwert (bei mir 8 Bit DMX) mit dem aktuellenn Timerstand verglichen. Beispiel: im Input Captuer Register steht eine 10000, der Triac soll bei 50% zünden. Also Triac zünden, wenn der Timer >= 5000 ist. Und das kann im Hauptprogramm erfolgen, ob der Triac wenige µs später zündet, interessiert niemanden. Michael
@Frank: Der ext. Int. wird gesperrt, damit bei einem Prellen des Eingangs (Netzstörung) die Compare-ISR nicht dauernd neu gestartet wird. Erst kurz vor dem nächsten erwarteten zc wird er wieder scharf gemacht. @Michael: Wenn das Hauptprogramm viel zu tun hat, macht sich die Verzögerung schon bemerkbar. Wahrscheinlich sind Multiphasendimmer mit Deinem Ansatz aber ein geringerer Aufawand als mit meiner Version (bei der dann ein Sortieralgorithmus im Hintergrund werkelt). VG, Hendrik
Hallo nochmal, habe versucht Hennes C Code in Bascom umzusetzen. Leider vergeblich. Offensichtlich ist C "direkter" zu programmieren. Bascom kennt offensicht noch nicht einmal eine do-while Schleife :( Wie dem auch sei, ich bin am verzweifeln. Michaels Lösung kann ich nicht anwenden, da das Hauptprogramm noch wachsen wird, nachdem die Steuerung der Triacs funktioniert. Noch jemand da der helfen kann? Gruß Frank
Frank S. schrieb: > Offensichtlich ist C "direkter" zu programmieren. Ja > Bascom kennt offensicht noch nicht einmal eine do-while Schleife Doch, sucher doch mal nach while in der Hilfe.
Selbst wenn ich die while Geschichte zum laufen bekomme, sind es immer noch viele andere Dinge die einfach direkter eingestellt werden müssten. Hat sonst noch niemand einen 8 Kanal Dimmer mit Bascom programmiert?
pcdimmer lief glaube ich einmal auf Bascom und wurde erst später (aus den von Dir beschriebenen Gründen) auf c umgestellt. Meine Empfehlung ist, sich mit c zu beschäftigen anstatt sich weiter mit einem Basic zu quälen, das für zeitkritische Anwendungen nie konzipiert worden ist. sorry, hendrik
Wenn Die c überhaupt nicht zusagt, wäre auch noch Assembler möglich ;-)
Hi Frank, hast Du das Projekt mittlerweile erfolgreich zu ende gehführt? Gruss Olli
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.