ELSA Online: 12. Regulačné obvody: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
Bez shrnutí editace |
||
(Jedna medziľahlá úprava od rovnakého používateľa nie je zobrazená.) | |||
Riadok 1: | Riadok 1: | ||
'''Úlohy:''' | '''Úlohy:''' | ||
* Identifikujte parametre regulovanej sústavy | * Identifikujte parametre regulovanej sústavy | ||
* Pre RC člen (10 kΩ a 100 | ** 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]]) | ||
<BR> | |||
* 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. | ** 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. | ** 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. | ||
Riadok 11: | Riadok 13: | ||
** Najskôr použite celočíselnú aritmetiku. Vysvetlite prečo vznikne trvalá regulačná odchýlka aj pre PI regulator. | ** 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. | ** 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:''' | '''Poznámky:''' | ||
Riadok 18: | Riadok 22: | ||
* Nezabudnite, vnútorný odpor zdroja má byť oveľa menší ako je odpor záťaže. | * Nezabudnite, vnútorný odpor zdroja má byť oveľa menší ako je odpor záťaže. | ||
'''Použijeme:''' | '''Použijeme:''' | ||
* Arduino | * Arduino | ||
* Kondenzátory 1 | * Kondenzátory 1 µF a 100 µF. Rezistor 10 kΩ | ||
* Programy ... | * Programy ... | ||
Návod viď príloha v classroome a vysvetlivky na cvičení. | |||
<div id="program1"></div> | <div id="program1"></div> | ||
<tabs> | <tabs> | ||
<tab name=" | <tab name="Meranie prechodovej charakteristiky.ino"><syntaxhighlight lang=c style="background: Cornsilk"> | ||
// 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 | |||
} | |||
Riadok 36: | Riadok 146: | ||
<div id="program2"></div> | <div id="program2"></div> | ||
<tabs> | <tabs> | ||
<tab name=" | <tab name="P regulator.ino. "><syntaxhighlight lang=c style="background: Cornsilk"> | ||
#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). | |||
} | |||
Riadok 53: | Riadok 277: | ||
* [https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf ATmega328P8-bit AVR Microcontroller] | * [https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf ATmega328P8-bit AVR Microcontroller] | ||
[[Category: ELSA]] | [[Category: ELSA]] |
Aktuálna revízia z 21:11, 6. december 2020
Ú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).
}