mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Geschickte Programmierung für Phasenanschnitt


Autor: Alex Bürgel (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

das Thema Phasenanschnitt (50Hz Netzspannung) wurde schon etliche male 
behandelt. Eine passende Software dafür konnte ich jedoch leider nicht 
finden.

Mein Problem: Ich habe einen Phasenanschnittsdimmer mit ATMega8 gebaut. 
An den OC1A-Pin ist ein TRIAC angeschlossen, über einen Jumper kann ich 
entweder am ICP-Pin oder am INT0-Pin ein Rechtecksignal einlesen, 
welches bei jedem Nulldurchgang seinen Zustand umkehrt.

Nun meine Frage: Wie kann einen möglichst effizienten Code generieren, 
der mir den TRIAC nach einer eingestellten "Dimm-Verzögerung" (z.B. 8ms) 
einschaltet und kurze Zeit später, jedoch auf jeden Fall bei t < 10ms, 
wieder ausschaltet? Das Ganze eben möglichst ohne 3 Interrupts dafür zu 
benutzen o.ä..

Leider blicke ich bei den ganzen "Phase Corrected Frequency Corrected 
PWM Modes" etc. im Datenblatt nicht ganz durch bzw. sehe noch nicht, wie 
ich diese Funktionen geschickt einsetzen kann...

Wäre für Tipps sehr dankbar!
Schöne Grüße,
Alex

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als Trigger muss man erst mal ein gefiltertes Netz verwenden. Ohne 
rabiaten Filter, der die Harmonischen rigoros wegmacht ist nichts. Dann 
einen Timer laufenlassen. Immer jeweils vom Trigger her. Und 
gleichzeitig die Periode pruefen, ist sie nicht relativ genau 20ms, dann 
macht man zur Sicherheit nichts. Einen durchgehenden Timer wuerd ich 
nicht verwenden, der laeuft dem Netz ueber eine gewisse Zeit davon und 
es knallt.
Das Problem mit der Filterung ist, dass man das Netz selbst veraendert.

Autor: Alex Bürgel (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A...aha Soooo. schrieb:
> Dann
> einen Timer laufenlassen. Immer jeweils vom Trigger her.

Genau, ich wollte auch bei jedem Wechsel des Trigger-Signals (es 
wechselt, wie gesagt, bei jedem Nulldurchgang) den Timer "resetten".

>Und gleichzeitig die Periode pruefen, ist sie nicht relativ genau 20ms, dann
>macht man zur Sicherheit nichts.

Richtig, das hatte ich mir auch überlegt.

Nun dennoch die Frage, wie man dazu geschickt die Timer-Funktionen des 
AVRs nutzen kann ohne alles in Software und mit Interrupts zu erledigen. 
Kann man nicht vieles davon in Hardware realisieren (mit den ganzen 
Timer-Spezialmodi)?

Gruß,
Alex

P.S.:
>und es knallt.
Was denn und warum? Stimmt im schlimmsten Fall nicht einfach der 
"Dimm-Wert" nicht?

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PWM ist hier nicht ganz angebracht. Es ist ja dein AC-Netz, das die 
Zeitvorgaben liefert, und nicht du, der du z.B. eine Grundfrequenz für 
PWM festlegst.

Eine Überlegung: Was macht dein Prozessor denn noch? Nur 
Phasenanschnitt? Rechne dann doch einmal aus, wie sehr der sich 
langweilen wird zwischen den Nulldurchgängen.
Ansonsten kann man sowas für zwei Kanäle prima mit den beiden 
Auffangregistern (Compare) eines Timers machen. ist zwar immer noch mit 
Spatzen auf Kanonen geschossen, macht aber nichts :-)

Autor: Markus Müller (mmvisual)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll den geschnitten werden?
Ohmsche oder Induktive Last?

Autor: Alex Bürgel (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus Müller schrieb:
> Was soll den geschnitten werden?
> Ohmsche oder Induktive Last?

In erster Linie Ohm'sche Last. Ich glaubte jedoch (bis zu deiner Frage), 
dass induktives Dimmen genauso funktioniert... :-)

>Was macht dein Prozessor denn noch?
Es ist noch ein lokales User-Interface (1 LED, ein Drehencoder, ein 
Button) dran und eine ZigBee Schnittstelle (per UART) für "ein Bisschen" 
Kommunikation mit anderen Geräten. Ist aber nicht so "zeitkritisch".

>Ansonsten kann man sowas für zwei Kanäle prima mit den beiden
>Auffangregistern (Compare)
Es ist nur 1 Kanal. Aber erläutere mir bitte mal genauer, wie du das 
meinst...

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun, parametrier einen Timer in der Art, sodass er innerhalb einer 
Halbwelle gerade nicht überläuft. Er soll am Ende der Halbwelle den 
Wert X erreichen.

Mit einem Auffangregister setzt du diesen Wert X TOP ein, das wäre dann 
einer von den CTC-Modi. Dadurch wird der Timer am Ende der Halbwelle 
wieder zurückgesetzt.

Dann leg eine Tabelle mit Vergleichswerten an. '0' wäre volle Leistung, 
X wäre gar keine Leistung, dazwischen dann z.B. noch linearisieren.

Legst du nun einen dieser Vergleichswerte in ein zweites Auffangregister 
(das erste sorgt ja bereits fürs Rücksetzen des Timers), so hast du 
deinen Zündzeitpunkt.

Autor: Horst Hahn (horha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich weiß ja nicht, was Du damit willst.
Dein Timer wird doch eine Rahmenzeit von 10 ms == 180° haben, um jede 
Halbwelle anzuschneiden.Damit schaltet der Timer immer bei 10 ms ab.
Der Trigger ist der Nulldurchgang der Netzspannung.

Alex Bürgel schrieb:
> "Phase Corrected Frequency Corrected PWM Modes"

Phase corrected PWM würde bei einem Phasenwinkel von 0,2° bei 89,9° eine 
Signal auf High setzen und bei 90,1° wieder zurück auf Low.
Also hättest Du als kleinsten Zündwinkel 90° == 50%.
Ergo könntest Du auch nur von 50..100% dimmen.
Das ist sicher nicht das gewünschte Verhalten.

Autor: Markus Müller (mmvisual)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei Induktiver Dimmung braucht man zwei Messungen:
- Spannung / Nulldurchgang
- Stromfluss durch den Verbraucher

Beides über Optokoppler mit dem Oszi betrachtet gibt eine interessante 
Erkenntniss.

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alex Bürgel schrieb:
> Nun meine Frage: Wie kann einen möglichst effizienten Code generieren,

Ich habe für eine Thyristorgleichrichtung von meinem Labornetzteil das 
ganze in einen Timer-Interrupt gelegt, der alle 51us aufgerufen wird. 
(Ich hatte keine anderen Ressourcen im PIC16F876 mehr frei). Dort wird 
dann die Entprellung des Eingangssignals, messen der 
Periodendauer-Hälften und die Ausgabe an die Thyristoren durchgeführt.
Die Berechnung der Anschnittwerte erfolgt separat im Hauptprogramm.
Das ganze braucht etwa 13% der Rechenzeit, 46 Assembler-Befehle und 
erlaubt einen Phasenanschnitt mit knapp 0,5% Auflösung und Jitter.

Gruß Anja

Autor: Alex Bürgel (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich weiß ja nicht, was Du damit willst.

Es soll ein Dimmer für Glühlampen und 230V-Halogenlampen bis 500W sein 
(wobei mir zunächst 60W reichen). Ferner dachte ich eigentlich auch 
Niedervolthalogenlampen mit Ringkerntrafo damit dimmen zu können.

Bevor mir hier irgendetwas explodiert: Was sollte ich denn beim Dimmen 
eines Ringkerntrafos erwarten? Meiner Erwartung nach steigt der Strom 
beim Einschalten irgendwann innerhalb einer Halbwelle halt "langsam" an, 
die Spannung ist natürlich sofort die aktuelle Sinusspannung. 
Ausschalten tut sich der TRIAC doch von alleine wenn U ~ 0V und I ~ 0A 
ist. Es gibt im übrigen auch einen Snubber mit 100nF/33Ohm über dem 
TRIAC.


Das mit dem CTC kann ich mir noch nicht so recht vorstellen, muss mir 
das nochmal anhand des Datenblatts durch den Kopf gehen lassen...

Gruß,
Alex

Autor: Alex Bürgel (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>das ganze in einen Timer-Interrupt gelegt, der alle 51us aufgerufen wird.

Ja klar, so kann man es machen... ich hatte nur gehofft anstatt alle 
xxµs einen Interrupt zu generieren einfach diverse Hardware-Funktionen 
nutzen zu können. So verfügt der "Input-Capture" ja z.B. über einen 
"Noise Canceller" und der Output Compare hat 12 Betriebsmodi (oder so). 
Da sollte es doch eine Kombination geben, mit der man so was 
alltägliches mit nur 1 Interrupt lösen kann und dennoch 
Störungsresistent etc. ist...

Autor: Ralph Fischer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Alex,

ich hatte im Sommer mal angefangen, einen Dimmer in Bascom zu schreiben, 
der etwa so läuft, wie Du es Dir vorstellst. Gedacht ist das Ding für 
Glühlampenlast bis 3 kW und Einknopfbedienung (Taster).

Ist alles noch ziemlich provisorisch, geht aber im wesentlichen schon. 
Es läuft alles automatisch im Timer1 eines Attiny:
'*******************************************************************************
'  Dimmer for ohmic loads with Attiny24 for one button operation
'*******************************************************************************
'
'  Ralph Fischer 2010


$regfile = "ATtiny24.dat"
$crystal = 1000000                      '8 MHz with divider enabled
'$baud = 38400

$hwstack = 32
$swstack = 32
$framesize = 24


Config Porta.0 = Output
Triac Alias Porta.0

Config Pina.1 = Input
Porta.1 = 1
Key Alias Pina.1

Config Porta.2 = Output                 'just for debugging
Led Alias Porta.2


Config Int0 = Falling
On Int0 Int0_isr
Enable Int0

Dim Key As Bit
Dim Onoff_flag As Bit
Dim Dim_flag As Bit
Dim Dim_direction As Bit                '1 = incr. brightness, 0 = decr. brightness
Dim Key_count_flag As Bit
Dim Count_0 As Byte                     'for timing of the key
Dim Bright_min As Word
Dim Bright_max As Word


Declare Sub Key_count
Declare Sub Dimm
Declare Sub On_off



Ocr1b = 7000                            'start triac at x [µs] after zero cross; 0 = full power, 10,000 = off
Ocr1a = Ocr1b + 50                      'end of triac start pulse
Config Timer1 = Timer , Prescale = 1 , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1

On Oc1b Set_triac
On Oc1a Reset_triac
Enable Oc1b
Enable Oc1a

Enable Pcint0
On Pcint0 Isr_pcint0
Pcmsk0 = &B00000010                     'PA.0 is key interrupt

Config Timer0 = Timer , Prescale = 1024
On Timer0 Timer0_isr
Enable Timer0


Enable Interrupts

Bright_min = 7000                       'note: this is the value for _minimum_ brighness
Bright_max = 2000                       'note: this is the value for _maximum_ brighness
                                        ' (values are the time gap between zero crossing and triac ignition)







'****Main****
Do

Led = onoff_flag
If Dim_flag = 1 Then
     Gosub Dimm
End If

If Key_count_flag = 1 Then
     Gosub Key_count
End If

Loop
'****/Main****

End

Isr_pcint0:
Waitms 20
If Key = 0 Then Set Key_count_flag
Return

Int0_isr:
Timer1 = 0
Start Timer1
Return

Timer0_isr:
     'Toggle Led
     Incr Count_0
Return

Set_triac:
Set Triac
Return

Reset_triac:
Reset Triac
Stop Timer1
Return

Sub On_off:
'Reset Triac
      Toggle onoff_flag
      If onoff_flag = 1 Then
         Enable Int0
         Else
         Disable Int0
         Gosub Reset_triac
      End If
End Sub

Sub Key_count:
     Reset Key_count_flag
     Count_0 = 0
     While Key = 0
     'Incr Count_0
     If Count_0 > 8 Then
          Set Dim_flag
          Count_0 = 0
          Exit Sub
     End If
     Wend
     If Count_0 < 5 Then Gosub On_off
End Sub

Sub Dimm:
Reset Dim_flag
Count_0 = 0
Toggle Dim_direction
     While Key = 0
          If Dim_direction = 0 Then
          Incr Ocr1b
               If Ocr1b > Bright_min Then
               Ocr1b = Bright_min
               End If
          Elseif Dim_direction = 1 Then
          Decr Ocr1b
               If Ocr1b < Bright_max Then
               Ocr1b = Bright_max
               End If
          End If
          Ocr1a = Ocr1b + 50
          Waitms 1
     Wend
End Sub 

Vielleicht nutzt es.

Ralph

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A...aha Soooo. schrieb:
> Als Trigger muss man erst mal ein gefiltertes Netz verwenden. Ohne
> rabiaten Filter, der die Harmonischen rigoros wegmacht ist nichts.

Hmm, komisch, mein 12-Kanal Dimmer funktioniert seit Jahren 
ausgezeichnet, auch ohne rabiaten Netzfilter. Die Kunst ist die 
Erkennung aller Nulldurchgänge, und zwar möglichst nahe an der Nullinie. 
Das habe ich mit einem Optokoppler mit Wechselspannungseingang gelöst. 
Dann gibt man dem Timer noch ein bisserl Reserve, so dass maximal 95% 
Leistung eingestellt werden können und dann ist alles super. Der 
Controller muss die Nulldurchgänge natürlich sauber erkennen, weshalb 
man hinter dem Optokoppler am besten einen Analog-Komparator-Eingang 
anstelle eines normalen Portpins nimmt. Diesen stellt man dann so ein, 
dass die Nullinie im Sinus einen schmalen Puls im Controller auslöst. Da 
der Analog-Komparator einen Interrupt auslösen kann, kann man die CPU 
zusätzlich entlasten. Als Leistungsstufe habe ich SSRs mit Snubbern 
hergenommen. Es hat sich herausgestellt, dass es sinnvoll ist, die SSRs 
den gesamten Leuchtzyklus nach dem Zünden eingeschaltet zu lassen, da es 
bei langen Lampenleitungen und zu kurzen Zündpulsen zu Flackern in 
kleinen Dimmstufen gekommen ist.

Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Knut !

Vielen Dank für Deinen hilfreichen Tipp mit dem Analog-Comparator !
( Ich quäle mich schon lange und das Gute lag so nah ;-))


Kannst Du mir bitte verraten, welches SSR Du benutzt ?

Danke + Gruß
Olaf

Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach so, vergessen zu schreiben, wie ich es mache:

Ich nehme den Timer0 und teile ihn durch 1024.
Bei 16 MHz habe ich dann nach 10 ms einen Zählerstand von 157.

Das Capture Register muss dann also auf 157 minus irgendetwas gesetzt 
werden. In der Capture-Interrupt-Funktion dann EINSCHALTEN und in der
AnalogCompare/INTx Interrupt-Funktion dann AUSSCHALTEN
(benutze MOSFET´s)

Just my 2 cents

Olaf

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.