8 Kanal Dimmer - Softwarefrage

OP #1491318
Lesenswert?

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
Gast #1491424
Lesenswert?

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...
OP #1492412
Lesenswert?

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}
OP #1492787
Lesenswert?

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?
#1492839
Lesenswert?

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
Gast #1493017
Lesenswert?

@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
OP #1495159
Lesenswert?

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
Gast #1495791
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren