ELSA Online: 11. Regulačné obvody: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
Bez shrnutí editace |
||
Riadok 203: | Riadok 203: | ||
== Datasheety == | == Datasheety == | ||
* [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:30, 29. november 2020
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:
- Zmerajte pomocou kondenzátora 0.1uF a 1.0uF hodnotu pullup rezistora. ( → #program1)
- Zistite priemernú hodnotu trvania A/D prevodu a porovnajte s katalógovým údajom.
- Upravte program zo stránky https://www.handsontec.com/dataspecs/module/Rotary%20Encoder.pdf a odskúšajte ako je citlivý na zákmity kontaktov.
- Ošetrite Pin2 a Pin3 proti zákmitom kondenzátormi 100nF.
- Vypočítajte akú frekvenciu spínania kontaktov dokážeme teoreticky takýmto spôsobom sledovať. Predpokladáme, že „pohyb“ je rovnomerný.
- 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--;
}