Linearisierung B2 Stromrichter mit ATMEGA 2561

OP #3676677
Lesenswert?

Hallo Liebe Leute,

in ein bestehendes Programm habe ich die Funktion "Linearisierung" 
eingebunden die mir einen neuen Zündwinkel ALPHA in Abhängigkeit der 
gemessenen Leitdauer LAMBDA und des am Potentiometer eingestellten 
Wertes u berechnet.

Die Formel für diesen Zündwinkel lautet:

An einer Gleichstrommaschine 200V, 0,51A habe ich meine Funktion 
getestet. Die Linearisierung soll verhindern das bei Belastung die 
Spannung einbricht. Wenn ich Spannungen bis 130V einstelle funktioniert 
alles wunderbar, der neu berechnete ALPHA verhindert das die Spannung 
einbricht. Bei Spannungen größer 130V treten verschiedene Phänomene ein. 
Wenn ich also z.B. 140V einstelle und nicht belaste springt der Wert 
manchmal einfach ohne das ich am Poti drehe auf z.B. 160V, aber nur 
manchmal. Manchmal funktioniert es auch wenn ich bei Spannungen größer 
130V belaste das er die Spannung hält, manchmal jedoch bricht die 
Spannung stark ein auch wenn ich dann nicht mehr belaste bleibt er auf 
dem Spannungswert mit Belastung und springt dann auf einmal nach ca. 
3-20 Sekunden wieder auf den alten Wert.

Mein Quellcode befindet sich im Bildformat im Anhang ich hoffe das ist 
so in Ordnung. Die Variable "drehrichtung" muss noch geändert werden, 
richtig müsste sie "linearisierung" heißen.

Woran kann es liegen? Fehlerhafte Leitdauererkennung? Vielleicht ein VZ1 
Filter für den berechneten ALPHA um Sprünge zu vermeiden?

Vielleicht findet sich hier jemand der Erfahrung mit der Materie hat und 
mal einen Blick drüber werfen kann, ich bin über jegliche Hilfe dankbar.

Gruß Steffen
Angehängte Dateien:
OP #3676719
Lesenswert?

Die Beleidigung ignoriere ich jetzt einfach mal. Ich dachte mir der 
Beitrag wird sonst zu lang aber hier bitte der Quellcode:

1
 #include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#include "ButtonPress.h"
5
#include "TrigonometrischeFunktionen.h"
6
#include "Initialisierung.h"
7

8
/*****************************Variablen-Deklaration****************/
9
float u = 0;
10
const float uMin = 0;
11
const float uMax = 1023;
12
int ALPHA = 17900;
13
volatile int ALPHAnutz = 17900;
14
const int ALPHAmax = 17900;
15
const int ALPHAmin = 10000;        //6500
16
volatile int LAMBDA = 4000;
17
int gezuendet = 0;
18
int ausschaltsicherung = 0;
19
int drehrichtung = 0;          //!!!DIESE VARIABLE IHREM ZWECK ENTSPRECHEND UMBENENNEN!!!
20
int leitdauerErkennung = 0;
21
int steigendeFlanke = 0;
22
int zweiteHalbwelle = 0;
23
int weiterZuenden = 0;
24

25
/****************************Funktionen-Deklaration****************/
26
int ADC_Lesen(void);
27
int Linearisierung();
28

29
/****************************MAIN-Funktion*************************/
30
int main(void)
31
{
32
  int linearisierungsBeschraenkung = 20;
33

34
  cli();  //Interrupts deaktivieren
35
  Init();  //Initialisierung
36
  sei();  //Interrupts aktivieren
37

38
  while(1)
39
  {
40
    if(drehrichtung == 0)
41
    {
42
      ALPHA = (((ALPHAmax - ALPHAmin) / 1023) * (ADC_Lesen()) + ALPHAmin);
43
    }
44
    
45
    if(drehrichtung == 1)
46
    {
47
      u = (((uMax - uMin) / 1023) * (ADC_Lesen()) + uMin);
48

49
      if(linearisierungsBeschraenkung >= 20)      //alle 20 main-Durchläufe wird hier rein gesprungen
50
      {
51
        linearisierungsBeschraenkung = 0;
52
        ALPHA = Linearisierung();// - 480;  //ACHTUNG: Dieser Korrekturfaktor ist nur für die ALTE Schaltung!!!
53
      }
54
    }
55

56
    if(ButtonPressed(0, PINA, 2, 500))  //an-/ausschalten
57
    {
58
      if(gezuendet)          //aus
59
      {
60
        if(ausschaltsicherung)
61
        {
62
          gezuendet = 0;
63

64
          PORTB |= (1<<PINB2);  //LED links aus
65
          PORTB |= (1<<PINB4);  //LED rechts aus
66
          PORTB &= ~(1<<PINB3);  //rote LED an
67
        }
68
        else
69
        {
70
          _delay_us(2500);
71
        }
72
      }
73
      else              //an
74
      {
75
        gezuendet = 1;
76

77
        PORTB |= (1<<PINB3);    //rote LED aus
78

79
        if(drehrichtung)
80
        {
81
          PORTB &= ~(1<<PINB4);  //LED rechts an
82
        }
83
        else
84
        {
85
          PORTB &= ~(1<<PINB2);  //LED links an
86
        }
87
      }
88
    }
89

90
    if(gezuendet)
91
    {
92
      if(ausschaltsicherung)
93
      {
94
        if(ButtonPressed(1, PINA, 1, 500))  //Links- oder Rechtslauf
95
        {
96
          if(drehrichtung)        //Linkslauf
97
          {
98
            drehrichtung = 0;
99
            PORTB &= ~(1<<PINB2);    //LED links an
100
            PORTB |= (1<<PINB4);    //LED rechts aus
101
          }
102
          else              //Rechtslauf
103
          {
104
            drehrichtung = 1;
105
            PORTB &= ~(1<<PINB4);    //LED rechts an
106
            PORTB |= (1<<PINB2);    //LED links aus
107
          }
108
        }
109
      }
110
      else
111
      {
112
        _delay_us(2500);
113
      }
114
    }
115
    linearisierungsBeschraenkung++;
116
  }
117
}
118

119
/******************************EXTERNE Interrupts*****************/
120

121
/*Netzsynchronisation*/
122
ISR (INT0_vect)        //NDG; 240us Verzögerung bei altem Leistungsteil
123
{
124
  TCNT1 = 0;
125
  ALPHAnutz = ALPHA;
126
  OCR1A = ALPHAnutz;
127
}
128

129
/*Leitdauererfassung*/
130
ISR (INT1_vect)        //Leitdauer; 304us Verzögerung bei altem Leistungsteil
131
{
132
  static int LAMBDAmess = 4000;
133
  if(bit_is_clear(PIND, 1))    
134
  {
135
    steigendeFlanke = 1;
136
    TCNT3 = 0;
137
  }
138
  else if(steigendeFlanke)
139
  {
140
    steigendeFlanke = 0;
141
    LAMBDAmess = TCNT3;// + 608;    //ACHTUNG: Dieser Korrekturfaktor ist nur für die ALTE Schaltung!!!
142

143
    if(LAMBDAmess >= 2640)      //mindestens >= 1000 um den fehlerhaften Zündimpuls nicht zu berücksichtigen!!!
144
    {
145
      LAMBDA = LAMBDAmess;
146
    }
147
  }
148
}
149

150
/******************************SOFTWARE Interrupts****************/
151

152
/*Timer1: Zünden und Löschen der Thyristoren*/
153
ISR (TIMER1_COMPA_vect)         //Zündung erste Halbwelle
154
{
155
  if(gezuendet)
156
  {
157
    zweiteHalbwelle = 1;
158
    ausschaltsicherung = 0;
159
    weiterZuenden = 1;
160

161
    PORTA |= (1<<PINA4);      //T1 an
162
    PORTA |= (1<<PINA5);      //T2 an
163

164

165
    OCR1B = ALPHAnutz + 400;
166
  }
167
}
168

169
ISR (TIMER1_COMPB_vect)          //Löschen aller gezündeten Pins
170
{
171
  if(gezuendet)
172
  {
173
    if(weiterZuenden)
174
    {
175
      ausschaltsicherung = 1;
176

177
        PORTA &= ~(1<<PINA4);    //T1T2 aus
178
        PORTA &= ~(1<<PINA5);    //T3T4 aus
179

180
        PORTA &= ~(1<<PINA6);    //T5T6 aus
181
        PORTA &= ~(1<<PINA7);    //T7T8 aus
182

183
      if(zweiteHalbwelle)
184
      {
185
        zweiteHalbwelle = 0;
186
        OCR1C = ALPHAnutz + 20000;
187
      }
188
      else
189
      {
190
        weiterZuenden = 0;
191
      }
192
    }
193
  }
194
}
195

196
ISR (TIMER1_COMPC_vect)          //Zündung zweite Halbwelle
197
{
198
  if(gezuendet)
199
  {
200
    if(weiterZuenden)
201
    {
202
      ausschaltsicherung = 0;
203

204
      PORTA |= (1<<PINA6);      //T3 an
205
      PORTA |= (1<<PINA7);      //T4 an
206

207
      OCR1B = ALPHAnutz + 20400;
208
    }
209
  }
210
}
211

212
/****************************Funktionen************************/
213

214
/*Linearisierung*/
215
int Linearisierung()
216
{
217
  if(LAMBDA < 12)        //Gleichung gilt nur für LAMBDA > 0!
218
  {
219
    LAMBDA = 12;
220
  }
221
  else if (LAMBDA > 20000)  //Lambda darf max. Pi werden
222
  {
223
    LAMBDA = 20000;
224
  }
225

226
  const float Pi = 20000;
227
  float relativ_u = u / uMax;
228

229
  float Term1 = LAMBDA / 2;
230
  float Term2 = Sinus(Term1);
231
  float Term3 = Term2 / 10000;
232
  float Term4 = Term3* Pi;
233
  float Term5 = LAMBDA / Term4;
234
  float Term6 = Term5 * relativ_u;
235
  float Term7 = Term6 * 10000;
236
  float Term8 = ArcSinus(Term7);
237

238
  float result = Pi - Term8 - Term1;
239
  
240
  if(result > 19000)  // 171°
241
  {
242
    result = 19000;
243
  }
244
  else if(result < 8000)
245
  {
246
    result = 8000;
247
  }
248
  return result;  
249
}
250

251
/*Analog-Digital-Konvertierung*/
252
int ADC_Lesen(void)
253
{
254
  ADCSRA |=(1<<ADEN);           //ADC aktivieren
255
  ADCSRA |= (1<<ADSC);              //nächste Umwandlung starten
256
  while (ADCSRA & (1<<ADSC));      //warten bis die Umwandlung abgeschlossen ist
257

258
  ADCSRA &= ~(1<<ADEN);        //ADC deaktivieren
259
  return ADCW;            //Ergebnis von 0 bis 1023 ausgeben
260
}

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