Forum: Mikrocontroller und Digitale Elektronik 8 Kanal Dimmer - Softwarefrage


von Frank S. (blaueslicht)


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

von TestX .. (xaos)


Lesenswert?

du brauchst doch nur die zündwinkel aufsteigend ordnen und dann jeweils 
mit nem timer jeden triac nacheinander zünden

von Sven P. (Gast)


Lesenswert?

Da der AVR sich sowieso langweilt, reicht es auch, alle Zündzeitpunkte 
zu jedem Zündwinkel zu vergleichen.

von Frank S. (blaueslicht)


Lesenswert?

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. ?

von Sven P. (Gast)


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...

von Frank S. (blaueslicht)


Lesenswert?

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

von Frank S. (blaueslicht)


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}

von Henne (Gast)


Lesenswert?

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

von Frank S. (blaueslicht)


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?

von Michael W. (retikulum)


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

von Henne (Gast)


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

von Frank S. (blaueslicht)


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

von Alexander S. (esko) Benutzerseite


Lesenswert?

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.

von Frank S. (blaueslicht)


Lesenswert?

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?

von Henne (Gast)


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

von Henne (Gast)


Lesenswert?

Wenn Die c überhaupt nicht zusagt, wäre auch noch Assembler möglich ;-)

von Henne (Gast)


Lesenswert?

Die -> Dir

von o. westerweller (Gast)


Lesenswert?

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