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.