Operácie

ELSA Online: 12. Regulačné obvody

Z SensorWiki

Verzia z 21:11, 6. december 2020, ktorú vytvoril Balogh (diskusia | príspevky)
(rozdiel) ← Staršia verzia | Aktuálna úprava (rozdiel) | Novšia verzia → (rozdiel)

Ú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