PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : brauch Hilfe digitale Regelung



decharteau
27.05.2010, 13:58
hallo Zusammen, ich habe das Forum heute entdeckt, und will auch beitragen

ich beschäftige mich seit einige Moment mit einem Projekt im Rahmen des Studium. es geht um die Spannung- und Stromregler bei schaltnetzteil. Nach analyse der schaltung soll ich PID und PI Regler jeweil für Spannung- und Strom digitale entwerfen und in µC implementieren. Da ich neu im Bereich µC programmierung und digitale Regelung bin, habe erst ein PID Regler als Spannungsregler in C programmiert. kompiliert schon ok, execute auch und ADC und DAC getestet. Die Algo habe ich von der seite RN. Aber weiß nicht ob meine Anfangsbedingungen ok sind . ealt habe ich global und auf 0 definiert. esum=0 am anfang. weiß nicht ob ich auch y zu 0 setzt oder so lassen.
mein D-Anteil funktioniert nicht richtig. ich auch nicht warum. hat jemand ein idee dafür?

das ganzediese (PID Regler) habe ich noch am Netzgerät getstet. könnte jemand mir sagen worauf man achten soll beim test am Netzgerät. muss ich beim test am gerät den Istwert initialisieren oder so lassen.


2 . Punkt
ok mit dem PID Regler. ja weiß ich schon wie man ein Regler programmiert. jetzt will ich nur ein Programm für spannung und stromregler. mir fällt das Konzept oder gutes Algo wie ich das ding machen kann. ich weiß schon, dass es eine kaskaderegelung ist. der stromregler soll schneller sein. dh wenn der U_regler ein Abtastzeit von z.B 100 ms wie im Programm ( das ist noch nicht richtig definiert nur um programm funktionfähig zu bringen) ist dis Abtastzeit der Stromregler 10ms.

ich habe vor der stromregler in einem Interrupt zu schreiben, dr alle 10ms kommt und führ folgende aktion.
ISR_PI_Berechnung( parameter)
{

ADCCON= // starten
ADCCP= // kanal auswählen
value1= (ADCDAT )

ADCCON= // starten
ADCCP= // kanal auswählen
value2= (ADCDAT )

e= value1 - value2;
esum= esum+e;
y=kp*e + ki*Ta*esum

}

im Main wie oben rufe ich diese Routine.

verständnisproblem.
wenn ich so verfahre. wird jede 10ms den Strom geregelt. Aber im prinzip soll der Stromregler nur aktiv sein, wenn der aktuele Strom die Begrenzung erreicht oder größe diese ist. sons läuft der spannungsregler.
hat jemand schon solche Sache programmiert?ich suche eine richtige Strukture und möglicherweise Beispielprogram oder ähnlicher Aufgabe mit gute erklärungen.


ich dringen auf Ihre Beiträge und freue mich schon bald Ihnen zu lesen.

Hessibaby
27.05.2010, 17:28
Den Strom (bzw. Spannungsabfall) über einen Shunt messen, evtl. mit einem OPA diese Spannung auf messbares Potential aufpeppeln, an einen ADC-Eingang und mit dem Sollwert vergleichen. Solange IST<SOLL passiert Nichts und wenn IST>=SOLL entweder interruptgesteuert die Spannung runterregeln oder ausschalten. Wie im wahren Leben eben .

decharteau
29.07.2010, 09:11
hallo zusammen,
ich komme wieder mit ein Frage zu dem Regler. Meine I-Anteil ist nicht ruhig liegt das an die Begrenzung? ich habe für den esum auf einem Max und Min begrenz trozdem habe ich noch problem im programm.

2.Frage was passiert wenn error negativ ist? muss man korrktur machen oder ist egal für den Mikrocontroller egal und seine Rechninhgen immer richtig macht. wäre net , wenn jemand mir das gut erklärt.

grüß

avion23
30.07.2010, 00:33
Hallo,
hier mal code aus einem P-Spannungsregler für pc-lüfter. Funktioniert hier einwandfrei. Ausregelzeit ist natürlich bescheiden, aber es ist ein step up der avalanche rated ist. D.h. Wegfall der Last im laufenden Betrieb ist i.O.

Der code ist nur für mich geschrieben und nie für die Veröffentlichung vorgesehen. Deswegen auch kaum comments.



// set voltage in mV
void setVoltage(uint16_t voltageDesired){
setPoint = voltageDesired / VOLTAGE_FACTOR;
}

void setUseSetPoint(bool flag){
useSetPoint = flag;
}

ISR(ADC_vect)
{
static uint8_t counter;
counter++;
// calculate new pwm value
if (counter % 4 == 0) {
static uint16_t adc;

setADC(3); // 3 = poti

adc -= (adc >> LOWPASS);
adc += getADC();
int16_t error = setPoint - adc;
if (error > 0 && (adc < (VOLTAGE_MAX/VOLTAGE_FACTOR)) ) {
setTimer1(error * KP);
} else {
setTimer1(0);
}
}

// measure setPoint
// only every second pass is possible
else if (counter % 4 == 2){
static uint16_t adc;

setADC(1); // 1 = voltage divider
adc -= (adc >> LOWPASS);
adc += getADC();

// only use this value if bool flag is set.
// used for startup
if(useSetPoint){
setPoint = adc;
}
}
}



#define VOLTAGE_START 13000 // startup voltage in mV
#define VOLTAGE_MAX 14000

/* PID Control
*/

#define LOWPASS 2
#define KP 2

/*
* lower resistor = 1k
* upper resistor = 12k
* U = 1k/13k = 0.0769
* 10bit resolution, 0 = 0mV_ref, 1023 = 1100mV_ref
* 1 unit = 1100mV_ref / 1023 = 1.0753mV_ref
* 1 unit = ( 1100mV_ref / 1023 ) * ( 13k / 1k ) = 13,9785mV
* 1023 units = 14300mV
*/
#define VOLTAGE_FACTOR (14>>LOWPASS) // error = 0,15%