Show Posts
Pages: 1 [2] 3 4 ... 20
16  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: May 19, 2014, 01:25:44 pm
Quote
Ohne Oszilloskop wird das nicht möglich sein.

Gut das ich mir vor kurzem ein ordentliches Oszilloskop bestellt habe. smiley

Kannst du mir beschreiben wo ich wie,was messen muss damit um diese Verzögerung zu ermitteln?

Quote
Du hast hier in der Tabelle in Sollwert() Werte für die Phasenanschnittzeit bis zu 20ms drin
.

Das habe ich vergessen im Code zu kommentieren. Ich hab den Prescaler so eingestellt das 1 Digit 0,5ms dauert.
Also kannst du alles in der Tabelle durch 2 rechnen um auf den eigentlichen Wert zu kommen
17  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: May 18, 2014, 01:09:49 pm
Quote
Das Thema haben wir schon mal diskutiert: du mußt alle möglichen Werte abfangen!

Stimmt daran lags.

Jetzt funktioniert das ganze schon annähernd gut. Bei 227V im Netz habe ich 50% verlangt, das Ergebnis waren 110V. Nah dran.

Nun möchte ich das ganze noch präziser machen. Dafür muss ich die Funktion U_Netzlesen() präziser machen, also mehr Werte nach oben und unten eintragen, richtig?

Den t wert habe ich auch schon um 500µs korrigiert. Könnte es nicht auch sein das man diesen Wert noch präziser machen kann?
Immerhin misst die Vorrichtung auf +-1V genau. Die Abweichung des Reglers beträgt jedoch 3-4V.
Kann ich irgenswie diesen Verzögerungswert bei mir genauer ermitteln?
18  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: May 17, 2014, 06:12:59 am
Quote
Du könntest eventuell noch in der Funktion U_Netzlesen() den gelesenen AD-Wert anzeigen:
Das hab ich ja gemacht, der Wert ist sowohl beim isolierten als auch beim gesamten sketch gleich.

Sobald ich jedoch den Gesamten sketch laufen lasse rechnet irgendetwas den AD wert falsch um:
Hier mal im gesamten sketch: (erste Zahl AD)
Quote
739   U_Netz: -14.41    Faktor_U: -15.27    Prozent: 50    Faktor_G: -763.30
741   U_Netz: -67.55    Faktor_U: -3.26    Prozent: 50    Faktor_G: -162.85
739   U_Netz: -14.41    Faktor_U: -15.27    Prozent: 50    Faktor_G: -763.30
742   U_Netz: -94.11    Faktor_U: -2.34    Prozent: 50    Faktor_G: -116.88
740   U_Netz: -40.98    Faktor_U: -5.37    Prozent: 50    Faktor_G: -268.43
740   U_Netz: -40.98    Faktor_U: -5.37    Prozent: 50    Faktor_G: -268.43
740   U_Netz: -40.98    Faktor_U: -5.37    Prozent: 50    Faktor_G: -268.43
740   U_Netz: -40.98    Faktor_U: -5.37    Prozent: 50    Faktor_G: -268.43
741   U_Netz: -67.55    Faktor_U: -3.26    Prozent: 50    Faktor_G: -162.85
739   U_Netz: -14.41    Faktor_U: -15.27    Prozent: 50    Faktor_G: -763.30

Und hier nur Funktion U_Netzlesen():
Quote
734
  Netzspannung: 225.93
732
  Netzspannung: 225.32
733
  Netzspannung: 225.62
736
  Netzspannung: 226.55
736
  Netzspannung: 226.55
733
  Netzspannung: 225.62
734
  Netzspannung: 225.93
734
  Netzspannung: 225.93

Mit max. 1V Abweichung vom realen Wert,ist der Wert zwar noch nicht so genau, jedoch wird er immerhin umgerechnet.

Was mache ich den anders als du smiley?
19  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: May 12, 2014, 01:14:40 pm
Quote
Wenn du darauf geachtet hast, dass Beide unabhängige Variablen verwenden, beeinflussen sie sich nicht.

Es sind ja 2 verschiedene Funktionen, worin jeweils die Variablen deklariert sind. Die müssten unabhängig sein, oder sehe ich das falsch?

Quote
am besten deguggen mit Serial.print(). Du lässt dir die kritischen Variablen ausgeben, dann kannst du sehen, was der Arduino so rechnet.

Das mach ich ja. Nun weiß ich aber nicht mehr welche Variable ich ausgeben soll. Der analoge Wert ist richtig, der in Volt umgerechnete jedoch nicht.

Hier der sketch:
Code:
#include <avr/io.h>
#include <avr/interrupt.h>

#define GATE 9    //Triac Pin
#define PULSE 20   //trigger pulse width (counts) 10µs
#define DETECT 2  //zero cross detect

int U_NetzPin = A10; // Netzspannungsmesser

int U_ref = 220; // bei 220V 3000W Leistung

void setup() {   
  pinMode(DETECT, INPUT);     //zero cross detect
  digitalWrite(DETECT, HIGH); //enable pull-up resistor
  pinMode(GATE, OUTPUT);      //triac gate control
  // set up Timer1
  OCR1A = 0;      //initialize the comparator
  TIMSK1 |= (1 << OCIE1A); // Comperator A Interrupt aktivieren
  TIMSK1 |= (1 << TOIE1); //Overflow Interrupt aktivieren
  TCCR1A = 0x00;    //timer control registers set for
  TCCR1B = 0x00;    //normal operation, timer disabled


  // bei zerocross Interrupt
  attachInterrupt(0,zeroCrossingInterrupt, RISING);   
    //IRQ0 is pin 2. Call zeroCrossingInterrupt
    //on rising signal

  Serial.begin(57600);   
}

void loop() { 
  Sollwert(50); // 50% der Leistung also 1,5kW

} //end loop


//d) eine Funktion, die den Phasenanschnitt ausführt.
//the interrupt function must take no parameters and return nothing
void zeroCrossingInterrupt(){ //zero cross detect   
  TCCR1B=0x02; //start timer prescaler 8
  TCNT1 = 0;   //reset timer - count from zero
}

ISR(TIMER1_COMPA_vect){ //comparator match
  digitalWrite(GATE,HIGH);  //Triac an machen
  TCNT1 = 65536-PULSE;      //trigger pulse width
}

ISR(TIMER1_OVF_vect){ //timer1 overflow
  digitalWrite(GATE,LOW); //Triac ausmachen
  TCCR1B = 0x00;          //disable timer stopd unintended triggers
}


//c) eine Funktion, die dir aus Sollwert und Netzspannung die Phasenanschnittszeit errechnet
void Sollwert(byte Prozent){ //Leistung in Prozent
 float U_Netz = U_NetzLesen();
 float Faktor_U =  U_ref / U_Netz;   // das ist der Korrekturfaktor, den du aus der abweichenden Spannung hast.
 float Faktor_G = Faktor_U * Prozent;  // das ist dein Gesamtfaktor, um den du mittels Phasenanschnitt deine Spannung

Serial.print("U_Netz: ");Serial.print(U_Netz);
Serial.print("\t Faktor_U: ");Serial.print(Faktor_U);
Serial.print("\t Prozent: ");Serial.print(Prozent);
Serial.print("\t Faktor_G: ");Serial.print(Faktor_G);Serial.println();

const int Tabpunkte = 50;
const float WerteTab[Tabpunkte][2]={     // 1.Spalte V in Prozent 1= 220V , 2.Spalte Zeit in Microsekunden

{ 0.725233373128343, 19600},
{ 2.04884152815099, 19200},
{ 3.75653798961305, 18800},
        { 5.76760037973328, 18400},
{ 8.03185633657378, 18000},
{ 10.5123471747264, 17600},
{ 13.1791534987902, 17200},
{ 16.0065727330459, 16800},
{ 18.9716372400389, 16400},
{ 22.0532660329187, 16000},
{ 25.2317515266739, 15600},
{ 28.4884385028046, 15200},
{ 31.8055204064967, 14800},
{ 35.1659108385353, 14400},
{ 38.5531651452729, 14000},
{ 41.951436442244, 13600},
{ 45.3454558986707, 13200},
{ 48.7205304460519, 12800},
{ 52.0625531752139, 12400},
{ 55.3580230518699, 12000},
{ 58.5940714931153, 11600},
{ 61.7584939718206, 11200},
{ 64.8397852526323, 10800},
{ 67.8271771743856, 10400},
{ 70.7106781186548, 10000},
{ 73.4811134683906, 9600},
{ 76.1301664807882, 9200},
{ 78.6504190855496, 8800},
{ 81.0353921805756, 8400},
{ 83.2795850361218, 8000},
{ 85.3785134379723, 7600},
{ 87.3287462010954, 7200},
{ 89.1279396673216, 6800},
{ 90.7748697626847, 6400},
{ 92.2694611303291, 6000},
{ 93.6128127709887, 5600},
{ 94.8072195123975, 5200},
{ 95.8561884891733, 4800},
{ 96.7644496439482, 4400},
{ 97.5379590584164, 4000},
{ 98.1838936915438, 3600},
{ 98.7106358471148, 3200},
{ 99.1277454250591, 2800},
{ 99.445917748684, 2400},
{ 99.6769245301471, 2000},
{ 99.8335353769449, 1600},
{ 99.9294172020061, 1200},
        { 99.9790090388604, 800},
        { 99.9973701481919, 400},
        { 100.0, 0}};

int i = 0;   
  while (i < Tabpunkte && Faktor_G > WerteTab[i][0]){i++;}  // passenden Eintrag in der Tabelle suchen
  // richtigen Wert interpolileren
  OCR1A = (((WerteTab[i][1] - WerteTab[i-1][1]) * ( Faktor_G - WerteTab[i-1][0] ))/ (WerteTab[i][0] - WerteTab[i-1][0] )) + WerteTab[i-1][1];

}


//b) eine Funktion um die Netzspannung aus dem AD-Eingang zu ermitteln.
/*************************************************************************************************
** Liest den AD-WErt an Pin "U_NetzPin" **
** und interpoliert aus der Tabelle den korrekten pysikalischen Wert. **
**      **
**  Input: nix **
**  Output: Netzspannung in Volt **
**  genutzte Globale Variablen: SensorPin **
**************************************************************************************************/
float U_NetzLesen() {
  /* Wertetabelle SpannungsWerte */ 
  const int Tabpunkte = 5;
  const float U_Ntab[Tabpunkte][2]={
  { 725, 223.1},
  { 727, 223.6},
  { 728, 224},
  { 729, 224.4},
                                        { 730, 224.7}};
                                   
  int U_NetzAD = analogRead(U_NetzPin);         
     
  //***************** Interpolation des Wertes aus der Tabelle *****************************************
  int i = 0;   
  while (i < Tabpunkte && U_NetzAD > U_Ntab[i][0]){i++;}  // passenden Eintrag in der Tabelle suchen
  // richtigen Wert interpolileren
  float Wert = (((U_Ntab[i][1] - U_Ntab[i-1][1]) * ( U_NetzAD - U_Ntab[i-1][0] ))/ (U_Ntab[i][0] - U_Ntab[i-1][0] )) + U_Ntab[i-1][1];

  return Wert;
} // End of U_NetzLesen
20  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: May 11, 2014, 02:38:01 pm
Quote
Also bei mir tut er das.
Komisch jetzt rechnet er bei mir auch Faktor_G aus.

Quote
Pack doch einfach mal ein paar Serial.print() rein

So hab ich das ja gemacht.

Was nun komisch ist das der U_NetzLesen() Teil nicht funktioniert. Er gibt verschiedene unpassende Werte aus, auch negative.
Wenn ich ihn jedoch isoliere, den Programmteil, denn misst er wieder richtig. (Alles richtig angeschlossen)
Der analoge Wert wird richtig ausgelesen und schwankt minimal +-1. Jedoch ist die Umrechnung irgendwie falsch.
Aber woran kann das liegen der sketch funktioniert isoliert sauber.
Irgendwas muss im gesamten sketch sein, was diese Umrechnung beeinflusst.
Liegt es daran das ich 2x die lineare Interpolation im gleichen sketch verwende? Beeinflusst sich da was?
Oder wie finde ich den Fehler?
21  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: May 10, 2014, 02:58:28 pm
Hab mich mittlerweile selbst an den Fehler rangetastet.
Quote
-  die Variablen Faktor_U und Faktor_G werden besser als float deklariert.
Daran Lag es zum einen, weil Faktor_U stänging 0 war.

Hab das geändert aber Faktor_G gibt ständig den Wert von Faktor_U wieder. Er multipliziert nicht mit Prozent (obwohl es als 50 eingestellt ist)

Quote
die Tabelle WerteTab muß nach der ersten Spalte aufsteigend sortiert sein.

Das werde ich noch mal ausprobieren, wobei die Tabelle bei U_NetzLesen() ja auch absteigend sortiert ist.
Muss man das immer nach der 1.Spalte aufsteigend sortieren?
22  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: May 07, 2014, 01:45:01 pm
Einzeln funktioniernen Teil b) und d) und rechnerisch müsste auch Teil c) funktionieren und die gewünschte Phasenanschnittzeit einstellen, aber die Lampe geht nicht an. Stimmt vllt damit etwas nicht?
23  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: May 06, 2014, 02:14:02 pm
Hab mir den sketch mehrmals durchgeschaut, aber mein ungeschultes Auge findet keinen Fehler.
Kann mir jemand einen Tip geben oder mir erklären wie ich den Fehler finde.
24  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: May 04, 2014, 02:58:16 pm
Quote
Lies das Poti mal nur alle 100ms oder so ein.
Danke is jetzt besser.

Hab nochmal versucht alles zusammenzuführen:
Code:
#include <avr/io.h>
#include <avr/interrupt.h>

#define GATE 9    //triac gate
#define PULSE 20   //trigger pulse width (counts) 10µs
#define DETECT 2  //zero cross detect

int U_NetzPin = A10;
unsigned long TS1, TS2;

int U_ref = 220; // bei 220V 3000W Leistung

void setup() {   
   // set up pins
  pinMode(DETECT, INPUT);     //zero cross detect
  digitalWrite(DETECT, HIGH); //enable pull-up resistor
  pinMode(GATE, OUTPUT);      //triac gate control
  // set up Timer1
  OCR1A = 0;      //initialize the comparator
  TIMSK1 |= (1 << OCIE1A); // Comperator A Interrupt aktivieren
  TIMSK1 |= (1 << TOIE1); //Overflow Interrupt aktivieren
  TCCR1A = 0x00;    //timer control registers set for
  TCCR1B = 0x00;    //normal operation, timer disabled


  // set up zero crossing interrupt
  attachInterrupt(0,zeroCrossingInterrupt, RISING);   
    //IRQ0 is pin 2. Call zeroCrossingInterrupt
    //on rising signal

  Serial.begin(57600);   
}

void loop() { 
  Sollwert(50); // 50% der Leistung also 1,5kW
 
} //end loop


//d) eine Funktion, die den Phasenanschnitt ausführt.
//the interrupt function must take no parameters and return nothing
void zeroCrossingInterrupt(){ //zero cross detect   
  TCCR1B=0x02; //start timer with divide by 8 input
  TCNT1 = 0;   //reset timer - count from zero
}

ISR(TIMER1_COMPA_vect){ //comparator match
  digitalWrite(GATE,HIGH);  //set triac gate to high
  TCNT1 = 65536-PULSE;      //trigger pulse width
}

ISR(TIMER1_OVF_vect){ //timer1 overflow
  digitalWrite(GATE,LOW); //turn off triac gate
  TCCR1B = 0x00;          //disable timer stopd unintended triggers
}


//c) eine Funktion, die dir aus Sollwert und Netzspannung die Phasenanschnittszeit errechnet
void Sollwert(byte Prozent){ //Leistung in Prozent
 float U_Netz = U_NetzLesen();
 
  int Faktor_U =  U_ref / U_Netz;   // das ist der Korrekturfaktor, den du aus der abweichenden Spannung hast.
  int Faktor_G = Faktor_U * Prozent;  // das ist dein Gesamtfaktor, um den du mittels Phasenanschnitt deine Spannung

const int Tabpunkte = 50;
const float WerteTab[Tabpunkte][2]={     // 1.Spalte V in Prozent 1= 220V , 2.Spalte Zeit in Microsekunden
{ 100.0, 0},
{ 99.9973701481919, 400}, 
{ 99.9790090388604, 800},
{ 99.9294172020061, 1200},
{ 99.8335353769449, 1600},
{ 99.6769245301471, 2000},
{ 99.445917748684, 2400},
{ 99.1277454250591, 2800},
{ 98.7106358471148, 3200},
{ 98.1838936915438, 3600},
{ 97.5379590584164, 4000},
{ 96.7644496439482, 4400},
{ 95.8561884891733, 4800},
{ 94.8072195123975, 5200},
{ 93.6128127709887, 5600},
{ 92.2694611303291, 6000},
{ 90.7748697626847, 6400},
{ 89.1279396673216, 6800},
{ 87.3287462010954, 7200},
{ 85.3785134379723, 7600},
{ 83.2795850361218, 8000},
{ 81.0353921805756, 8400},
{ 78.6504190855496, 8800},
{ 76.1301664807882, 9200},
{ 73.4811134683906, 9600},
{ 70.7106781186548, 10000},
{ 67.8271771743856, 10400},
{ 64.8397852526323, 10800},
{ 61.7584939718206, 11200},
{ 58.5940714931153, 11600},
{ 55.3580230518699, 12000},
{ 52.0625531752139, 12400},
{ 48.7205304460519, 12800},
{ 45.3454558986707, 13200},
{ 41.951436442244, 13600},
{ 38.5531651452729, 14000},
{ 35.1659108385353, 14400},
{ 31.8055204064967, 14800},
{ 28.4884385028046, 15200},
{ 25.2317515266739, 15600},
{ 22.0532660329187, 16000},
{ 18.9716372400389, 16400},
{ 16.0065727330459, 16800},
{ 13.1791534987902, 17200},
{ 10.5123471747264, 17600},
{ 8.03185633657378, 18000},
{ 5.76760037973328, 18400},
{ 3.75653798961305, 18800},
{ 2.04884152815099, 19200},
{ 0.725233373128343, 19600}};

int i = 0;   
  while (i < Tabpunkte && Faktor_G > WerteTab[i][0]){i++;}  // passenden Eintrag in der Tabelle suchen
  // richtigen Wert interpolileren
  OCR1A = (((WerteTab[i][1] - WerteTab[i-1][1]) * ( Faktor_G - WerteTab[i-1][0] ))/ (WerteTab[i][0] - WerteTab[i-1][0] )) + WerteTab[i-1][1];
}


//b) eine Funktion um die Netzspannung aus dem AD-Eingang zu ermitteln.
/*************************************************************************************************
** Liest den AD-WErt an Pin "U_NetzPin" **
** und interpoliert aus der Tabelle den korrekten pysikalischen Wert. **
**      **
**  Input: nix **
**  Output: Netzspannung in Volt **
**  genutzte Globale Variablen: SensorPin **
**************************************************************************************************/
float U_NetzLesen() {
  /* Wertetabelle SpannungsWerte */ 
  const int Tabpunkte = 5;
  const float U_Ntab[Tabpunkte][2]={ { 730, 224.7},
  { 729, 224.4},
  { 728, 224},
  { 727, 223.6},
  { 725, 223.1}};                                   
                                   
  int U_NetzAD = analogRead(U_NetzPin);         
   
  //***************** Interpolation des Wertes aus der Tabelle *****************************************
  int i = 0;   
  while (i < Tabpunkte && U_NetzAD > U_Ntab[i][0]){i++;}  // passenden Eintrag in der Tabelle suchen
  // richtigen Wert interpolileren
  float Wert = (((U_Ntab[i][1] - U_Ntab[i-1][1]) * ( U_NetzAD - U_Ntab[i-1][0] ))/ (U_Ntab[i][0] - U_Ntab[i-1][0] )) + U_Ntab[i-1][1];

  return Wert;
} // End of U_NetzLesen

Leider klappt es nicht die Lampe bleibt aus.  Die Pins stecken alle an der richtigen Stelle.
Wo liegt der Fehler? Oder wie finde ich ihn?

Quote
Faktor_U und Faktor_G können auch Werte >1 annehmen. Deine Tabelle fasst aber nur WErte <1.
Das solltest du abfangen.

Der Wert kann nur über 1 steigen wenn Die Netzspannung unter 220V liegt, was normalerweise nicht passieren kann.

Quote
Ausserdem vermisse ich die ca.500µs Zeitversatz, den dir dein Nullpunktrigger verursacht. (Reply #62)

Die habe ich immer noch nicht drin.
Quote
Wie rechne ich diese Abweichung mit in die Formel ein? Immer wenn t steht in der Formel vorkommt durch(t-0,5) ersetzen?
25  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: May 01, 2014, 02:33:25 pm
Quote
Wenn man die alten Bits belassen will oder muss, kann man einfach |= statt = machen.

Sind die anderen Bits wieder auf 0 gesetzt wenn ich mit = nur einen ändere?

Hab heute versucht die Anschnittzeit mit nem Poti einzustellen.
Code:
void loop(){ // sample code to exercise the circuit
i= analogRead(Poti);
i= map(i,0,1023,0,19980);
OCR1A = i;     //set the compare register brightness desired.                         
}
Da hat die Lampe immer geflackert, nicht hoch frequentiell aber die Lampe ging öfters kurz an und aus.
Woran liegt das und wie behebe ich das?
26  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: April 30, 2014, 02:31:05 pm
Quote
d) eine Funktion, die den Phasenanschnitt ausführt.
Quote
machst doch lieber mit einem Timerinterrupt, wie hier beschrieben: http://playground.arduino.cc/Main/ACPhaseControl

Ich habe mich erstmal wieder an diesen Teil gemacht. Hatte aber Schwierigkeiten, da ich diese ganze Timersachen nicht verstanden habe.
Aber nun habe ich es endlich grob verstanden. Und den sketch damit auch. (Übrigens ne sehr einsteigerfreundliche Seite mit Beispielen zum Nachmachen: http://www.engblaze.com/microcontroller-tutorial-avr-and-arduino-timer-interrupts/)

Code:
// AC Control V1.1
//
// This arduino sketch is for use with the heater
// control circuit board which includes a zero
// crossing detect fucntion and an opto-isolated triac.
//
// AC Phase control is accomplished using the internal
// hardware timer1 in the arduino
//
// Timing Sequence
// * timer is set up but disabled
// * zero crossing detected on pin 2
// * timer starts counting from zero
// * comparator set to "delay to on" value
// * counter reaches comparator value
// * comparator ISR turns on triac gate
// * counter set to overflow - pulse width
// * counter reaches overflow
// * overflow ISR truns off triac gate
// * triac stops conducting at next zero cross


// The hardware timer runs at 16MHz. Using a
// divide by 8 on the counter each count is
// 0,5 microseconds.  1/2 wave of a 50Hz AC signal
// is about 19980 counts (10.000 microseconds-10= 9.990).
//

#include <avr/io.h>
#include <avr/interrupt.h>

#define DETECT 2  //zero cross detect
#define GATE 9    //triac gate
#define PULSE 20   //trigger pulse width (counts) 10µs


void setup(){

  // set up pins
  pinMode(DETECT, INPUT);     //zero cross detect
  digitalWrite(DETECT, HIGH); //enable pull-up resistor
  pinMode(GATE, OUTPUT);      //triac gate control

  // set up Timer1
  //(see ATMEGA 328 data sheet pg 134 for more details)
  OCR1A = 0;      //initialize the comparator
  TIMSK1 = 0x03;    //enable comparator A and overflow interrupts
  TCCR1A = 0x00;    //timer control registers set for
  TCCR1B = 0x00;    //normal operation, timer disabled


  // set up zero crossing interrupt
  attachInterrupt(0,zeroCrossingInterrupt, RISING);   
    //IRQ0 is pin 2. Call zeroCrossingInterrupt
    //on rising signal



//Interrupt Service Routines

void zeroCrossingInterrupt(){ //zero cross detect   
  TCCR1B=0x02; //start timer with divide by 8 input
  TCNT1 = 0;   //reset timer - count from zero
}

ISR(TIMER1_COMPA_vect){ //comparator match
  digitalWrite(GATE,HIGH);  //set triac gate to high
  TCNT1 = 65536-PULSE;      //trigger pulse width
}

ISR(TIMER1_OVF_vect){ //timer1 overflow
  digitalWrite(GATE,LOW); //turn off triac gate
  TCCR1B = 0x00;          //disable timer stopd unintended triggers
}

void loop(){ // sample code to exercise the circuit


OCR1A = 9990;     //set the compare register brightness desired. //  9990= 5ms
                           

}

Das ist der Code. Viel habe ich nicht verädert, nur TCCR1B=0x02; also Prescaler 8. Damit ergibt das 0,5µs pro count.
Da eine Halbe Sinuswelle 10.000µs dauert sind es maximal 20.000 Counts bei mir.
Da im anderen Code 10µs zum wieder ausschalten gebraucht wurden ist pulse 20 (10µs).  (20.000-20=max.19980 Counts)

Der sketch funktioniert auch soweit.

Die Lampe flackert aber im Einstellbereich 9988-9992. Woran liegt das? Wie kann ich es beheben?

Quote
Ausserdem vermisse ich die ca.500µs Zeitversatz, den dir dein Nullpunktrigger verursacht. (Reply #62)
Das habe ich vergessen, danke. Dies ist übrigens auch bei dem Testen diesen Codes aufgefallen, da der gemessene Wert nach Tabelle immer ca. dem Wert von x-500µs entsprach (z.B 5ms eingestellt= 176V bei 226,5 im Netz entspricht laut Tabelle aber ca 4,5ms)

Wie rechne ich diese Abweichung mit in die Formel ein? Immer wenn t steht in der Formel vorkommt durch(t-0,5) ersetzen?

Bin mir nicht ganz sicher wie das mit diesen zahlen funktioniert TCCR1B=0x02. Wird da die letzte zahl (2) binär umgerechnet(10) und damit im Register die jewieligen bits aktiviert oder deaktiviert? Wenn ja wieso geht das bei TCCR1B=0x02 bei bit 0 nach 7 hin und bei
TIMSK1 = 0x03;  von bit 7 zu 0?



27  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: March 30, 2014, 01:23:14 pm
Quote
Das geht einfacher, und, ja, das schafft der Arduino:
- Du kriegst aus deiner Spannungsmessung die aktuelle Spannung.
- Du hast (woher auch immer) eine Leistungsanforderung
- Du kennst die Leistung, die bei einer bestimmten Spannung abgegeben wird. Das ist dein Referenzpunkt: z.B. bei U_ref =210V ist deine Leistung 2.5kw und das sind 100%
Dann geht der Rechenweg so:
Faktor_U =  U_ref / Aktuelle Spannung   // das ist der Korrekturfaktor, den du aus der abweichenden Spannung hast.
Faktor_P = 70%  // das ist deine Leistungsanforderung
Faktor_G = Faktor_U * Faktor_P  // das ist dein Gesamtfaktor, um den du mittels Phasenanschnitt deine Spannung reduzieren mußt.
Mit dem Wert geht du in ein Array  und holst dir mittels linearere Interpolation die Phasenanschnittszeiten.

Ne klasse Idee!
Ich habe mal versucht alle Punkte in Einbezug deiner Idee in einen sketch zu bringen, dabei habe ich verwendet was ich bis jetzt habe:

Quote
Du brauchst also in deiner Software:
a) eine Funkion um den Sollwert für die Leistung abzufragen.
b) eine Funktion um die Netzspannung aus dem AD-Eingang zu ermitteln.
c) eine Funktion, die dir aus Sollwert und Netzspannung die Phasenanschnittszeit errechnet
d) eine Funktion, die den Phasenanschnitt ausführt.

Code:
int U_NetzPin = A7;
unsigned long TS1, TS2;

int AC_LOAD = 3;    // Output to Opto Triac pin
int dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF

int U_ref = 220; // bei 220V 3000W Leistung

void setup() {   
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  attachInterrupt(0, zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above 
  Serial.begin(57600);   
}

void loop() { 
  Sollwert(50); // 50% der Leistung also 1,5kW
 
} //end loop

//d) eine Funktion, die den Phasenanschnitt ausführt.
//the interrupt function must take no parameters and return nothing
void zero_crosss_int()  //function to be fired at the zero crossing to dim the light
{
  // Firing angle calculation : 1 full 50Hz wave =1/50=20ms
  // Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle)
  // For 60Hz => 8.33ms (10.000/120)
  // 10ms=10000us
  // (10000us - 10us) / 128 = 78 (Approx) For 60Hz =>65

  int dimtime = (78.046875*dimming);    // For 60Hz =>65   
  delayMicroseconds(dimtime);    // Wait till firing the TRIAC

  digitalWrite(AC_LOAD, HIGH);   // Fire the TRIAC

  delayMicroseconds(10);         // triac On propogation delay (for 60Hz use 8.33)

  digitalWrite(AC_LOAD, LOW);    // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
}

//c) eine Funktion, die dir aus Sollwert und Netzspannung die Phasenanschnittszeit errechnet
int Sollwert(byte Prozent){ //Leistung in Prozent
 float U_Netz = U_NetzLesen();
 
  int Faktor_U =  U_ref / U_Netz;   // das ist der Korrekturfaktor, den du aus der abweichenden Spannung hast.
  int Faktor_G = Faktor_U * Prozent;  // das ist dein Gesamtfaktor, um den du mittels Phasenanschnitt deine Spannung

const int Tabpunkte = 50;
const float WerteTab[Tabpunkte][2]={     // 1.Spalte V in Prozent 1= 220V , 2.Spalte Zeit in Microsekunden
{ 1, 0},
{ 0.999973701481919, 200}, 
{ 0.999790090388604, 400},
{ 0.999294172020061, 600},
{ 0.998335353769449, 800},
{ 0.996769245301471, 1000},
{ 0.99445917748684, 1200},
{ 0.991277454250591, 1400},
{ 0.987106358471148, 1600},
{ 0.981838936915438, 1800},
{ 0.975379590584164, 2000},
{ 0.967644496439482, 2200},
{ 0.958561884891733, 2400},
{ 0.948072195123975, 2600},
{ 0.936128127709887, 2800},
{ 0.922694611303291, 3000},
{ 0.907748697626847, 3200},
{ 0.891279396673216, 3400},
{ 0.873287462010954, 3600},
{ 0.853785134379723, 3800},
{ 0.832795850361218, 4000},
{ 0.810353921805756, 4200},
{ 0.786504190855496, 4400},
{ 0.761301664807882, 4600},
{ 0.734811134683906, 4800},
{ 0.707106781186548, 5000},
{ 0.678271771743856, 5200},
{ 0.648397852526323, 5400},
{ 0.617584939718206, 5600},
{ 0.585940714931153, 5800},
{ 0.553580230518699, 6000},
{ 0.520625531752139, 6200},
{ 0.487205304460519, 6400},
{ 0.453454558986707, 6600},
{ 0.41951436442244, 6800},
{ 0.385531651452729, 7000},
{ 0.351659108385353, 7200},
{ 0.318055204064967, 7400},
{ 0.284884385028046, 7600},
{ 0.252317515266739, 7800},
{ 0.220532660329187, 8000},
{ 0.189716372400389, 8200},
{ 0.160065727330459, 8400},
{ 0.131791534987902, 8600},
{ 0.105123471747264, 8800},
{ 0.0803185633657378, 9000},
{ 0.0576760037973328, 9200},
{ 0.0375653798961305, 9400},
{ 0.0204884152815099, 9600},
{ 0.00725233373128343, 9800}};

int i = 0;   
  while (i < Tabpunkte && Faktor_G > WerteTab[i][0]){i++;}  // passenden Eintrag in der Tabelle suchen
  // richtigen Wert interpolileren
  dimming = (((WerteTab[i][1] - WerteTab[i-1][1]) * ( Faktor_G - WerteTab[i-1][0] ))/ (WerteTab[i][0] - WerteTab[i-1][0] )) + WerteTab[i-1][1];
}


//b) eine Funktion um die Netzspannung aus dem AD-Eingang zu ermitteln.
/*************************************************************************************************
**  Funktion U_NetzLesen() **
**************************************************************************************************
** Liest den AD-WErt an Pin "U_NetzPin" **
** und interpoliert aus der Tabelle den korrekten pysikalischen Wert. **
**  **
**  **
**      **
**  Input: nix **
**  Output: Netzspannung in Volt **
**  genutzte Globale Variablen: SensorPin **
**************************************************************************************************/
float U_NetzLesen() {
  /* Wertetabelle SpannungsWerte */ 
  const int Tabpunkte = 5;
  const float U_Ntab[Tabpunkte][2]={ { 730, 224.7},
  { 729, 224.4},
  { 728, 224},
  { 727, 223.6},
  { 725, 223.1}};                                   
                                   
  int U_NetzAD = analogRead(U_NetzPin);         
   
  //***************** Interpolation des Wertes aus der Tabelle *****************************************
  int i = 0;   
  while (i < Tabpunkte && U_NetzAD > U_Ntab[i][0]){i++;}  // passenden Eintrag in der Tabelle suchen
  // richtigen Wert interpolileren
  float Wert = (((U_Ntab[i][1] - U_Ntab[i-1][1]) * ( U_NetzAD - U_Ntab[i-1][0] ))/ (U_Ntab[i][0] - U_Ntab[i-1][0] )) + U_Ntab[i-1][1];

  return Wert;
} // End of U_NetzLesen

Das Array habe ich etwas größer gemacht damit der Wert präziser wird. Aber ich glaube das benötigt wiederum mehr Zeit richtig?

Quote
a) eine Funkion um den Sollwert für die Leistung abzufragen.
Das brauche ich eig. nicht. da ich den Sollwert entweder im Programm oder per Poti festlege.

Quote
b) eine Funktion um die Netzspannung aus dem AD-Eingang zu ermitteln.
Quote
Dazu mußt du nur die Stützstellen in deinem Array entsprechend anpassen. [...]
Da kann man noch digital filtern, dann wird das besser, aber ganz kriegst du es nicht weg.
Was meinst du mit Stützstelle und wie passe ich sie an? Und wie filter ich das Signal digital?

Quote
c) eine Funktion, die dir aus Sollwert und Netzspannung die Phasenanschnittszeit errechnet
Diesen Punkt habe ich versucht nach deiner Idee umzusetzen. Die Tabelle habe ich in Exel gefertigt.
Danke übrigens auch dafür, hab durch dich ein bisschen mit Exel umzugehen gelernt.

Quote
d) eine Funktion, die den Phasenanschnitt ausführt.
Dieser Punkt ist auch noch fraglich, da der aktuelle Code ja mit delays arbeitet. Heist das wenn da alle 10ms ein delay kommt wird der Arduino eingefroren?

Habe ich den sketch denn erstmal grob der Idee nach richtig umgesetzt?
28  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: March 27, 2014, 01:59:52 pm
Das mit der Genauigkeit stimmt mein Messgerät hat bei Wechselspannung auch 1% +-. Aber ich meinte Genauigkeit die am Messgerät orientiert ist. Wenn es 225,3 anzeigt sollte beim Arduino 225,5 stehen oder bei 227,8V 228V. Ist sowas nicht möglich? Je genauer ich diese Netzspannung messe umso genauer kann ich die Leistung einstellen.

Zum Phasenanschnittregler:
Mit der Formel suche ich immernoch nach ner Lösung auf dem Mathe Forum.

Könnte man mithilfe der Linearen Interpolation mehrere Arrays erstellen mit verschieden Netzspannungen im Bereich 220-240V(oder enger) in 0,5V Schritten (20V/0,5V=40) Das währen dann zB 40 Arrays und je nach gemessener Netzspannung wird dann das passende Array bestimmt und daraus wird dann der benötigte Phasenanschnittwert mittels Linearen Interpolation ermittelt.
Würde sowas gehen, würde der Arduino das schaffen?
29  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: March 24, 2014, 01:49:13 pm
Quote
1. Welche andere Methode den Stellwert zu berechnet?

Damit meinte ich: c) eine Funktion, die dir aus Sollwert und Netzspannung die Phasenanschnittszeit errechnet

Ich habe mich auf nem Mathe Forum gefragt und da meint einer:
Quote
Da in der Formel das t sowohl linear als auch im Argument des sin im Radikanden auftaucht, dürfte eine Auflösung nicht möglich sein, sondern nur eine numerische Approximation.
Ein anderer meint:
Quote
Üblicherweise macht man graphische Näherungslösungen, wenn die Mathekenntnisse noch nicht reif für ET sind.

Quote
Wenn du die Schaltung, so wie einige Posts früher diskutiert, aufgebaut hast, mag der Wert zwar ungenau sein, aber er sollte nicht springen.

Ja die Schaltung ist wie ausdiskutiert. Mit den Schotky Dioden und dem 1000µF Elko wie im Schaltplan.
Er springt ja nicht so extrem nur 1-2 digits hoch und runter.

Quote
Wie genau muß es denn sein?

Mindestens auf 0,5 V genau sollte es sein. Brauche ich dafür mehr Messwerte? Der Wert springt immer so in ca. 0,7V Schritten rum. ist aber annähernd richtig und manchmal sogar genau richtig, aber denn springt er halt um 0,7V wieder hoch oder runter.
30  International / Deutsch / Re: 3kW Heizung, Leistung regulieren und messen on: March 22, 2014, 10:55:06 am
Quote
Das mit den 227 in Zeile 3 kann ja nur ein Tipfehler sein.

Ja das wars.

Wiedermal danke für den Tip.

Quote
Wenn du nun langsam weiter machst, einen HW-Teil nach dem anderen und einen SW-Teil nach dem anderen entwicklest, dann hat du am Ende ein funktionierendes System. Keine Sorge, das wird!

Danke das motiviert mich, aber wie soll ich denn jetzt weitermachen?

1. Welche andere Methode den Stellwert zu berechnet?
2. Wie mache ich den Spannungsmesser (programmtechnisch) präziser. Die Werte springen schon ein bisschen rum, machmal sind sie genau richtig, und dann wieder nicht.
Pages: 1 [2] 3 4 ... 20