PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Avr Dimmer 230V



Niggle
11.05.2016, 15:22
Hi Leute,
ich habe vor über meinen Atmega8 230 Volt zu dimmen. Die
Nulldurchgangserkennung wird mit einem Optokoppler (4N33) + Widerstand
direkt am Netz angeschlossen. Somit sollte ich am Ausgang ein
Rechtecksignal erhalten. Das erzeugte Signal geht dann in den AVR an den
Interrupt-Pin 1.
Hier wird ein Zähler zurückgesetzt. Der Timer löst nach 39µs aus, somit
wird dieser aufruf ca. 256 mal pro Halbwelle ausgelöst. Wenn der Timer
also ausgelöst wird, wird geguckt, ob der aktuelle Zählerstand dem vorgegeben
Wert entspricht.

Ist das hier von der Idee her richtig?
Oder ist das komplett der falsche Ansatz?


#define F_CPU 16000000
#include <avr/io.h>
#include <avr/interrupt.h>

uint8_t counter, val1, val2;

#define timerpreload_1 178

#define Tri1_OUT DDRD |= (1<<PD7);
#define Tri2_OUT DDRD |= (1<<PD6);


#define Tri1_ON PORTD |= (1<<PD7);
#define Tri1_OFF PORTD &= ~(1<<PD7);
#define Tri2_ON PORTD |= (1<<PD6);
#define Tri2_OFF PORTD &= ~(1<<PD6);


ISR(TIMER2_OVF_vect)
{
TCNT2 = timerpreload_1;
if (counter < 254)
{
counter++;
}
if(counter==val1)
{
Tri1_ON
}
else
{
Tri1_OFF
}
if(counter==val2)
{
Tri2_ON
}
else
{
Tri2_OFF
}



}

/
ISR (INT1_vect)
{
Tri1_OFF
Tri2_OFF
TCNT2 = timerpreload_1;
counter = 0;
if (val1 == 0)
{
Tri1_ON
}
if (val2 == 0)
{
Tri2_ON
}
}


int main(void)
{
//Timer für die Phasenanschnittberechnung ( alle 39usec )
TCNT2 = timerpreload_1;
TCCR2 |= (1<<CS21);
TIMSK |= (1<<TOIE2);
//Timer Ende
//INT1 ON PHASE SYNC
MCUCR |= (1<<ISC10); //Fallend / Steigend
GICR |= (1<<INT1); //Interrupt aktivieren
//Int1 Ende
sei();

while(1)
{

}
}

Somit sollte für val=255 die Lampe aus und für 0 an sein.

MfG Niclas

021aet04
11.05.2016, 22:56
Ich habe soetwas ähnliches auch vor kurzem gemacht. Ich habe einen attiny45 genommen. Es soll ein Sanftanlauf werden (Prototyp ist fertig). Ich habe es rein über Interrupts gelöst. Programm müsste ich am Rechner schauen, aber vom Prinzip funktioniert es so (bin mir aber nicht zu 100% sicher):


Int 0
(
Lade wert in OCR Register
Starte Timer
)
Int Timer
(
Stoppe Timer
Zünde triac (impuls)
)
Main
(
Prüfe Taster (wegen sanftanlauf)
Wenn gedrückt => ladewert Timer erhöhen damit Zündung früher
Sonst => ladewert Timer niedriger damit Zündung später
)


Hoffe der pseudocode ist verständlich.

MfG Hannes

nikolaus10
12.05.2016, 11:19
Hallo

Bin nicht ganz so firm drin.

Aber alle 39 uSec einen interrupt ?
Da bleibt nicht viel Zeit fuer anderes.

Vielleicht besser, nach Nulldurchgang Timer mit Helligkeitswert starten und im Millisec bereich ein Interupt ?



73

Niggle
12.05.2016, 13:30
Danke für die schnellen Antworten:

Ich würde am Ende gerne 4 Kanäle ansteuern können, weshalb die Methoden von euch beiden wahrscheinlich nicht funktionieren würde. Bin aber nicht sicher, vlt. habe ich was falsch verstanden ;).
Ich könnte von 256 Helligkeitsstufen auf 128 runtergehen. Dann hätte ich alle 78 µSec einen Interrupt.
Im Hintergrund soll 'nur' über I2C Daten empfangen werden

021aet04
12.05.2016, 19:31
In der PDF findest du den Plan und das Programm. Als Controller dient ein Attiny45 der mit dem internen Takt läuft (mit Teiler auf 1MHz). Ich benötige nur einen Ausgang, wenn du mehr benötigst, sollte sich das aber relativ leicht lösen lassen (vom Prinzip ähnlich der Ansteuerung von Modellbauservos). Am Plan fehlt noch der VDR, den ich jetzt verwende, wollte es ursprünglich mit einem RC-Glied machen (zusammen mit dem Motor an die Ausgangsklemme).
Das Foto ist mein Prototyp.

Die Nulldurchgangserkennung stammt nicht von mir, das habe ich aus einem Schaltungsbuch von Elektor.

Die Ansteuerung könnte noch verbessert werden (Schaltungstechnisch), wenn die Zündung zu früh ist zündet der Triac nicht richtig, dann gibt es teilweise nur eine Halbwelle (am Oszi kontrolliert). Deswegen gibt es in der Timer ISR die IF/Else Schleife (sollte vermieden werden, bei mir ist es aber egal). Wenn die Zündung zu früh ist zünde ich 30mal (for Schleife). Die Schleife mit den 3x NOP dient der Zündungsdauer (das der Triac sicher zündet).

MfG Hannes

wkrug
22.05.2016, 10:22
Um das Problem mit dem zu frühen Zündimpuls zu umgehen, könnte man den Triac nicht nur mit einem Impuls, sondern mit einer statischen Spannung zünden.
Diese Spannung wird dann im Nulldurchgang wieder abgeschaltet.
Das Problem mit nur einer ausgegebenen Halbwelle ist vor allem bei Transformatoren ein Problem.
Ich hab mal versucht PAR 36 Strahler ( mit integriertem Trafo ) so anzusteuern.
Das Ergebnis waren durchgebrannte Trafos.

Man könnte die Zündsequenz auch mit Comparematch Interrupts lösen, dadurch würde man eine feinere Auflösung erreichen, aber dann bräuchte man einen Controller der pro Ausgang einen Comparematch Interrupt hat.

Zusätzlich solltest Du bedenken, das die 50Hz durchaus auch eine Toleranz haben und es auch Netze mit 60Hz Netzfrequenz gibt.

021aet04
22.05.2016, 10:35
Das mit der Dauerzündung stimmt. Bei mir funktioniert das aber nicht, da ich einen relativ kleinen Pufferelko verwende. Da würde die Spannung zu stark absinken. Was ich noch versuchen kann den Strom vom Kondensator Netzteil zu erhöhen und einen anderen/mehrere Elkos nehmen. Habe jetzt noch einen anderen X2 Kondensator.

Das mit der Halbwelle habe ich eigentlich beim testen mit der Bohrmaschine bemerkt (bremste plötzlich ab) und dann habe ich mit dem Oszilloskop nachgeschaut.

PS: ich weiß nicht ob du dir die Dateien angesehen hast, aber ich messe jeden Nulldurchgang. Somit ist es egal ob die 50Hz etwas abweichen oder nicht (außer wenn ich sehr früh zünde).

MfG Hannes