Operácie

ELSA Online: 12. Regulačné obvody: Rozdiel medzi revíziami

Zo stránky SensorWiki

Balogh (diskusia | príspevky)
Bez shrnutí editace
Balogh (diskusia | príspevky)
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 <BR> – RC  člen, pozostávajúci z rezistora 10 kΩ a kondenzátora 1uF resp. 100 uF. Použite pripravený program: ( → [[#program1]])<BR> Mer_prech_charak_01.ino
* Identifikujte parametre regulovanej sústavy  
* Pre RC člen (10 kΩ a 100 uF) Navrhnite P regulator. Upravte  - doplňte pripravený program: ( → [[#program2]])<BR> P_reg_01.ino.
** 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.


Návod viď.: Cv_12.pptx
 


'''Použijeme:'''
'''Použijeme:'''
* Arduino  
* Arduino  
* Kondenzátory 1 uF a 100 uF. Rezistor 10 kΩ
* 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="Mer_prech_charak_01.ino"><syntaxhighlight lang=c style="background: Cornsilk">
<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="P_reg_01.ino. "><syntaxhighlight lang=c style="background: Cornsilk">
<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]
* [https://www.handsontec.com/dataspecs/module/Rotary%20Encoder.pdf Rotary Encoder]




[[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). 
  
  }





Datasheety