ELSA Online: 12. Regulačné obvody
Zo stránky SensorWiki
Úlohy:
- Identifikujte parametre regulovanej sústavy
- Sústavu predstavuje RC člen, pozostávajúci z rezistora 10 kΩ a kondenzátora 1µF resp. 100 µF. Použite pripravený program: ( → #program1)
- Pre RC člen (10 kΩ a 100 µF) navrhnite P regulátor. Upravte - doplňte pripravený program: ( → #program2)
- Vysvetlite, prečo nedosiahneme dobré výsledky pre časovú konštantu 10ms.
- Navrhnite P (zosilnenie 1, 2 a 3) regulátor pre časovú konštantu 1s a vypočítajte trvalú regulačnú odchýlku pre w_zel = 3V.
- Výsledky porovnajte s nameranými.
- Ako sa mení dynamika uzatvoreného regulačného obvodu?
- Bonus. Doplňte program regulátora o I zložku a navrhnite parametre.
- Najskôr použite celočíselnú aritmetiku. Vysvetlite prečo vznikne trvalá regulačná odchýlka aj pre PI regulator.
- Použite Float aritmetiku. Doplňte program o zmenu záťaže. Vypočítajte a meraním overte veľkosť trvalej regulačnej odchýlky pri skokovej zmene záťaže.
Poznámky:
- Nezabudnite zapojiť na výstup PWM signálu filter.
- Nepoužité OZ v púzdre je v hodné „ošetriť“.
- Nepoužitý vstup A/D prevodníka je vhodné „ošetriť“.
- Nezabudnite, vnútorný odpor zdroja má byť oveľa menší ako je odpor záťaže.
Použijeme:
- Arduino
- Kondenzátory 1 µF a 100 µF. Rezistor 10 kΩ
- Programy ...
Návod viď príloha v classroome a vysvetlivky na cvičení.
// Meranie prechodovej charakteristiky
// Použijeme Serial Plotter
#define C_1uF //
#define SerialPlotter //
//#define C_100uF //
// --------------------------
// Program pre vykreslenie prechodovej charakteristiky RC člena
// Použite 100uF a 1.0 uF kondezátor
// pinA je vždy zapojený cez 10kOhm rezistor ako OUTPUT.
// pinB je najskôr zapojený ako output a následne nastavený do log. nuly.
// pinB a A0 sú skratnuté.
// za cca 1sekundu (delay(1000)) po resete bude kondenzátor určite vybitý. Potom sa
// pinB prepne do stavu input bez pullup a kondenzátor sa začne nabíjať.
// Keď program dosiahne čas 10*T (T - časová konštanta RC člena) vykreslovanie sa zastaví.
// príkaz micros() vracia systémový čas v us od spustenia programu ako "long" číslo.
// Vykreslovanie na Serial Plotter sa deje v diskrétnom čase. Každých n*Ts (n = 0, 1, 2, ...),
// kde Ts je perióda vzorkovania.
// Vykreslovanie je v pomerných jednotkách. 1SJ = 1023 (10b-ový prevodník).
// 1SJ odpovedá napätiu 5V
// Vykreslujú sa tri čiary:
// 1.) Uc, 2.) 1023 (5V) a 3.) 647 = int(0.632*1023)
int pinA = 2;
int pinB = 3;
long t_0_tau = 0;
long Zac_time = 0;
long Kon_time = 0;
long tau = 0; // časová konštanta RC člena
#ifdef C_100uF // T = R*C = 10kOhm*100uF = 1000ms = 1s
// Doplňte
#endif
#ifdef C_1uF // T = R*C = 10kOhm*1uF = 10ms
long Ts = 1000; // 1ms
int t_diskr = 0; // nacitavam pocet Ts
// Dvojnásobok ustálenia prechodovej chrakteristiky:
int t_diskr_kon = 100; // ((2 * 5T) = 0,1sek)/ (Ts = 1 ms)) = 100;
#endif
void setup() {
// úvodná inicializácia
pinMode (pinA, OUTPUT);
digitalWrite(pinA, HIGH);
pinMode (pinB, OUTPUT);
digitalWrite(pinB, LOW);
Serial.begin(115200);
}
void loop() {
int nap = 0;
// počkám na ustálenie sa pomerov na RC
delay(1000); // 1000ms
Zac_time = micros();
// výpis v čase t = 0.0 s
t_0_tau = Zac_time;
nap = analogRead(0); // Počiatočná hodnota napätia na kondenzátore
pinMode (pinB, INPUT); // Od tohto okamžiku sa začne kondenzátor nabíjať
Serial.print(1023); // "5,0V"
Serial.print(" ");
Serial.print(647); // "0,632*5V"
Serial.print(" ");
Serial.println( nap );
// Meranie prechodovej charakteristiky
do {
Kon_time = micros();
nap = analogRead(0);
if((Kon_time - Zac_time) >= Ts ){
//nap = analogRead(0);
//Zac_time = Kon_time; //Takoto by narastala chyba
Zac_time += Ts; // Začiatok predchádzajúcej periódy vzorkovania
// výpisy
Serial.print(1023 );
Serial.print(" ");
Serial.print(647 ); // 0,63% z1023
Serial.print(" ");
Serial.println( nap );
t_diskr++; // počet periód vzokovania
}
if(( nap >= 647 ) && ( !tau )){// Spresnosťou na trvanie A/D prevodu odmeriame tau v mikrosekundach
tau = Kon_time - t_0_tau;
}
}
while( t_diskr < t_diskr_kon);
#ifdef SerialPlotter //
// Vypisujeme na Serial Plotter
#elseif
// vypisujeme na Serial Monitor
delay(1000); // 1000ms
delay(1000); // 1000ms
Serial.print("tau = ");
Serial.print( tau );
Serial.println(" [us] ");
#endif
//---------------------
AAA: goto AAA; // tu čakám na ďalší RESET a nové meranie
}
#define C_1uF //
// #define C_100uF //
// --------------------------
// Regulačný obvod s P regulátorom
// Regulovaná sústava 1. rádu, staticka s prenosovou funkciou S(s) = K/(1+T.s)
// časová konštanta je raz cca 10ms a druhý krát 1s.
// Použite 100uF a 1.0 uF kondezátor a 10kOhm rezistor.
// pin3, resp. pin6 je vždy zapojený cez 10kOhm rezistor ako OUTPUT.
// pin A0 je pripojený na spoj rezistor - kondenzátor.
// Keď program dosiahne čas 10*T (T - časová konštanta RC člena) vykreslovanie sa zastaví.
// príkaz micros() vracia systémový čas v us od spustenia programu ako "long" číslo.
// Vykreslovanie na Serial Plotter sa deje v diskrétnom čase. Každých n*Ts (n = 0, 1, 2, ...),
// kde Ts je perióda vzorkovania.
// Vykreslovanie je v pomerných jednotkách. 1SJ = 1023 (10b-ový prevodník).
// 1SJ odpovedá napätiu 5V
// Vykreslujú sa tri čiary:
// 1.) Uc, 2.) 1023 (5V) a 3.) 614 (3V)
int PWM_3_490 = 3; // PWM
int PWM_6_980 = 6;
int PWM = PWM_6_980;
long t_0 = 0;
long Zac_time = 0;
long Kon_time = 0;
long tau = 0; // časová konštanta RC člena
int nap = 0; // regulovaná veličina
int w_zel = 614; // 3V
int e_wy; // regulačná odchýlka
int e_oo = 0; // trvalá regulačná odchýlka
int akc_zas = 0; // akčný zásah, plnenie PWM signálu
int K_P = 1; // Zosilnenie regulátora
#ifdef C_100uF // T = R*C = 10kOhm*100uF = 1000ms = 1s, Ts = 50ms
// doplňte
#endif
#ifdef C_1uF // T = R*C = 10kOhm*1uF = 10ms
long Ts = 1000; // 1ms
int t_diskr = 0; // nacitavam pocet Ts
// Dvojnásobok ustálenia prechodovej chrakteristiky:
int t_diskr_kon = 100; // ((2 * 5T) = 0,1sek)/ (Ts = 1 ms)) = 100; {2*(5*T) = 1sek}
#endif
void setup() {
// úvodná inicializácia
// Nastavenie PWM signálu
pinMode(PWM, OUTPUT); // sets the pin as output
analogWrite(PWM, 0); // sets to "0.0V"
// počet opakovani je daný časovou konštantou
for(int i = 0; i < ????; i++){
delay(1000); // 1000ms // Na začiatku vybijem kondenzátor
}
Serial.begin(115200);
}
void loop() {
Zac_time = micros();
// výpis v čase t = 0.0 s
t_0 = Zac_time;
nap = analogRead(0); // Počiatočná hodnota napätia na kondenzátore
Serial.print(1023); // "5,0V"
Serial.print(" ");
Serial.print(w_zel); // "3V/5V*1023"
Serial.print(" ");
Serial.println( nap );
// Regulácia
do {
Kon_time = micros();
if((Kon_time - Zac_time) >= Ts ){
nap = analogRead(0);
P_reg();
//nap = analogRead(0);
//Zac_time = Kon_time; //Takoto by narastala chyba
Zac_time += Ts; // Začiatok predchádzajúcej periódy vzorkovania
// výpisy
Serial.print(1023);
Serial.print(" ");
Serial.print(w_zel);
Serial.print(" ");
Serial.println( nap );
t_diskr++; // počet periód vzokovania
}
}
while( t_diskr < t_diskr_kon);
// tu môžem vypočítať
// e_oo = w_zel - nap;
//---------------------
AAA: goto AAA;
// tu čakam na ďalší RESET a nové meranie
}
// Počítam v takzv. SJ (1SJ = 1023, resp. 5V )
void P_reg(){
// doplňte
// regulačná odchýlka
// akc_zas
// Obmedzenia
analogWrite(PWM, akc_zas >> 2); // the duty cycle: between 0 (always off) and 255 (always on).
}