Forum: Mikrocontroller und Digitale Elektronik Linearisierung B2 Stromrichter mit ATMEGA 2561


von Steffen C. (kerkerian)


Angehängte Dateien:

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

: Bearbeitet durch User
von Cyblord -. (cyblord)


Lesenswert?

Ich frag mich echt, welche Art von Hirnverletzung man erlitten haben 
muss, damit man QuellTEXT als Screenshots anhängt.

von Steffen C. (kerkerian)


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
}

von Cyblord -. (cyblord)


Lesenswert?

Ja viel besser... NICHT

ProTip für Kopfverletzte: Du kannst und sollst Quellcode als Datei 
anhängen. Aber als Quellcode (also direkt .c) und nicht als Bild. Aber 
weißt, wenns schon daran scheitert, was will man da noch groß auf den 
Inhalt eingehen?

von spess53 (Gast)


Lesenswert?

Hi

>Ich dachte mir der Beitrag wird sonst zu lang ...

Ja. Deshalb postet man den auch als Anhang.

MfG Spess

von Steffen C. (kerkerian)


Lesenswert?

So habe die .c Datei im Ausgangsposting angehängt. Ich hoffe damit sind 
jetzt alle, auch die 
im-internet-anonym-beleidiger-und-im-echten-leben-so-klein-mit-hut-Leute 
,  zufrieden.

von Steffen C. (kerkerian)


Lesenswert?

Hat sich erledigt, es war ein Hardwarefehler bei der Leitdauererfassung.

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.