Operácie

ELSA Online: 11. Regulačné obvody

Zo stránky SensorWiki

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

Téma: Inkrementálne snímače (IRC), regulácia napätia na kondenzátore.


Použijeme:

  • Arduino
  • Kondenzátory 0,1 uF, 1,0 uF a 2x 100nF.
  • Programy z prílohy


Úlohy:

  1. Zmerajte pomocou kondenzátora 0.1uF a 1.0uF hodnotu pullup rezistora. ( → #program1)
  2. Zistite priemernú hodnotu trvania A/D prevodu a porovnajte s katalógovým údajom.
  3. Upravte program zo stránky https://www.handsontec.com/dataspecs/module/Rotary%20Encoder.pdf a odskúšajte ako je citlivý na zákmity kontaktov.
  4. Ošetrite Pin2 a Pin3 proti zákmitom kondenzátormi 100nF.
  5. Vypočítajte akú frekvenciu spínania kontaktov dokážeme teoreticky takýmto spôsobom sledovať. Predpokladáme, že „pohyb“ je rovnomerný.
  6. Bonus. Pripravili sme pre Vás základ programu využívajúci prerušenia ( → #program2). Doplňte, dorobte program tak, aby načítal, resp. odčítal pri prechode z jedného stavu do druhého len jeden impulz.

...11 01 00 10 11... resp. naopak ...11 10 00 01 11...

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.


Návod: Meranie hodnoty Pullup rezistora pomocou Arduina.

Najskôr som pomocou osciloskopu zmeral skutočné hodnoty kondenzátorov. Použil som dva elektrolyty 0,1µF a 1µF.

Zmeral som prechodové charakteristiky (nabíjanie na 5V cez presný rezistor 12kΩ).

  • 0,1 µF kondenzátor ma zanedbateľný zvodový odpor.
  • 1µF kondenzátor má tiež zanedbateľný zvodový odpor pri tvrdom zdroji napätia.
  • V ustálenom stave v oboch prípadoch nameriam 5,0V.
  • Prepočítané hodnoty: 0,1µF => 0,095 µF (skut.); 1,0µF => 0,97 µF (skut.).

Zapojenie merania vnútorného odporu viď. slajdy z prezentácie k cvičeniam.

Meriam čas nábehu napätia na kondezátore v µs. Časovej konštante odpovedá napätie na kondenzátore

Program nám určí čas v µs. Odmeriame aj hodnotu ustálenú . Vstupný pin zapojený s pullup rezistorom je mäkký zdroj prúdu.

Program dokolečka odmeriava napätie na kondenzátore. Trvanie časovej konštanty prakticky odpovedá <math>n<math> A/D prevodovov. Ak podelíme τ počtom A/D prevodov získame trvanie jedného prevodu. Vypočítajte a porovnajte s údajom výrobcu.

Upravte zapojenie pre vyhodnotenie IRC. Doplňte kondenzátory. Modifikujte program a overte funkčnosť. Podrobnejšie viď. slajdy z prezentácie k cvičeniam.



// Program pre meranie hodnoty pullup rezistoru pomocou nabíjania kondenzátora
// Použite 0.1uF a 1.0 uF kondezátor
// pinA je vždy zapojený s pullup-om ako input. 
// pinB je najskôr zapojený ako output a nastavený do log. nuly. 
// pinA , pinB a A0 sú skratnuté.
// za cca 1sekundu (delay(1000))po resete bude kondenzátor určite vybytý. Potom sa
// pinB prepne do stavu input bez pullup a kondenzátor sa začne nabíjať.
// Keď dosiahne hodnotu odpovedajúcu Uc(tau) vypíše sa na seriovú linku hodnota 
// tau v [us]. 
// !!!!! Podľa KL-ov je pullup udávaný v 10-kach kOhm
// príkaz mikros() vracia systémový čas v us od spustenia programu ako "long" číslo.

int pinA = 2;
int pinB = 3;
int Poc_A_D_prevodov = 0;

long Zac_time = 0; 
long Kon_time = 0;

void setup() {
  // úvodná inicializácia
  pinMode (pinA, INPUT_PULLUP);
  pinMode (pinB, OUTPUT);
  digitalWrite(pinB, LOW);   
  Serial.begin(19200);
}

void loop() {
  // Ak treba, doplňte si/upravte deklaráciu premennných 
  // !!!!! ZAČNITE menším KONDENZÁTOROM, je to jednoduchšie. Aspoň niečo Vám bude fungovať. !!!!!
  int pom = 0;
  int nap = 0;
  int tau = 0;
  int Trvanie_A_D = 0;
  
  int konst_tau = 622; //  (int)(0,632 * (984))= 622   ====> napr. (4.8/5)*1023 * 0.63 = 618
  
  delay(1000);  // 1000ms
  pinMode (pinB, INPUT); // od tohto okamžiku sa začne kondenzátor nabíjať
  
  Zac_time = micros();
  
  while(analogRead(0)< konst_tau){Poc_A_D_prevodov++;}
  // vtomto okamžiku je Uc(tau) rovné 0,63*U(oo) 
  Kon_time = micros();
  
  Serial.print("Tau = ");
  tau = Kon_time - Zac_time;
  Serial.print(tau);
  Serial.println(" [us] ");
  Serial.println(" ");  // nový riadok
  
  Serial.print("Poc A/D prevodov = ");
  Serial.println(Poc_A_D_prevodov);
  Serial.println(" ");  // nový riadok
  
  Trvanie_A_D = tau / Poc_A_D_prevodov;
  Serial.print("Trvanie A/D prevodu = ");
  Serial.print(Trvanie_A_D);
  Serial.println(" [us] ");
  Serial.println(" ");  // nový riadok
    
  delay(1000);  // 1000ms// počkám na ustálenie a odmeriam ustálenú hodnotu 
  // vypočítajte priemer 10-tich hodnôt ustáleného napätia na kondenzátore
  // a vypíšte cez sériovú linku podobne ako to vidíte na priloženom obrázku
  // číslo v zátvorke predstavuje hodnotu 10-bitového prevodníka 
 //pomocou čísla z A/D prevodníka upresnite,vypočítajte vašu konst_tau, napr.:konst_tau = 618; 
 // niečo ako (4.8V/5.0V)*1023 * 0.63 = 618
 // 4.8V je ustálená hodnota na kondenzátore a 5.0V je napätie zdroja a v našom prípade aj
 // Uref A/D prevodníka.
 
 //---------------------
 // vypočítajte hodnotu pullup rezistoru a zobrazte
 // raz pre C = 0,1uF
 // a druhý krát pre C = 1,0uF 
    
 AAA:   goto AAA;
 // tu čakam na ďalší RESET a nové meranie
  
}



<div id="program2"></div>


// Vyhodnocujem smer a jeden impulz na otacku 
// využíva  prerušenia, nevyuživa Gray-ov kod 

const byte interruptPin0 = 2; // A
const byte interruptPin1 = 3; // B
volatile int counter = 0;
volatile int poc_prechodov = 0;
volatile int old = 0;
volatile int Pin_3;

void setup() {
  Serial.begin(115200);
  pinMode(interruptPin0, INPUT_PULLUP);
  pinMode(interruptPin1, INPUT_PULLUP);
  // CHANGE, RISING, FALLING, ...
  attachInterrupt(digitalPinToInterrupt(interruptPin0), IntUP, RISING); 
  attachInterrupt(digitalPinToInterrupt(interruptPin0), IntDOWN, FALLING);
  Serial.println(" Start ");
}
  
void loop() {
  if(old != counter ){
   Serial.print("Poc Prech =  "); 
   Serial.print(poc_prechodov);
   Serial.print("  "); 
   Serial.print("Counter =  "); 
   Serial.println(counter);
   old = counter;
  }
}
void IntUP() { //  KANAL A
  poc_prechodov++;
  Pin_3 = digitalRead(interruptPin1); 
  if ( Pin_3 == LOW )  counter++; else counter--;         
}
void IntDOWN() { //  KANAL A 
  poc_prechodov++;
  Pin_3 = digitalRead(interruptPin1); 
  if ( Pin_3 == HIGH ) counter++; else counter--;        
}





Datasheety