This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| et:examples:sensor:ir [2009/08/17 19:29] – mikk.leini | et:examples:sensor:ir [2010/01/07 14:58] (current) – eemaldatud mikk.leini | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Analoog digitaal muundur ====== | ||
| - | |||
| - | ====== Infrapunaandur ====== | ||
| - | {{: | ||
| - | |||
| - | ===== Infrapuna kaugusandur ===== | ||
| - | |||
| - | Sharp kaugusandur on infrapunamoodul mille tuvastatav vahemaa on 0,2-1,5 meetrit. | ||
| - | |||
| - | Anduri väljundiks on 2,7-0,5 V (vastavalt vahemaale) analoogsignaal. Anduri ühendus on näidatud joonistel 1 ja 2. Tähelepanu tuleks pöörata anduri väljundile (joonis 1). Anduri väljund on sama nii 9 kui 30 cm korral. See tähendab, et kauguse täpseks tuvastamiseks peab arvestama nii signaali kaldega kui ka liikumissuunaga. | ||
| - | NB! SHARP infrapuna kaugusandureid on mitut tüüpi. Kontrolli kasutatava anduri tüüpi ja vali sellele vastav graafik anduri andmelehelt. | ||
| - | |||
| - | {{: | ||
| - | |||
| - | Joonis 1 Anduri väljund | ||
| - | |||
| - | {{examples: | ||
| - | |||
| - | Joonis 2 Anduri ühendamine ATmega128 plaadiga | ||
| - | |||
| - | ===== ATmega128 analoogmuundur ===== | ||
| - | |||
| - | Muundur on 10-bitine. Maksimaalne lugemite diskreetimise kiirus täisresolutsiooni korral on 15 kSPS. Suuremad kiirused on võimalikud madalamate resolutsioonide korral. Lisateavet ja spetsifikatsioonid leiate ATmega128 andmelehelt lk. 230-245. Analoogmuundurit saab kasutada nii tupik- kui ka diferentsiaalmuundurina. Kolme vähemolulist bitti saab kasutada diferentsiaalrežiimi negatiivse väljundina. | ||
| - | |||
| - | <code c> | ||
| - | /* Lihtne AD muunduri kasutamine | ||
| - | Mikael Hellgren/ | ||
| - | */ | ||
| - | #include < | ||
| - | |||
| - | int main(void) { | ||
| - | |||
| - | unsigned int adc10; | ||
| - | ADMUX = 0xC0; | ||
| - | |||
| - | while(1) { | ||
| - | ADCSRA = 0xC3; | ||
| - | while ( ADCSRA & (1<< | ||
| - | // oodatakse kuni konverteerimine on lõpetatud | ||
| - | adc10 = ADC; | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | |||
| - | Põhjalikum AD muunduri funktsioon | ||
| - | <code c> | ||
| - | |||
| - | uint16_t ReadChannel(uint8_t mux) //mux - määrab ära AD kanali | ||
| - | { | ||
| - | uint8_t i; // tsükli kordaja muutuja | ||
| - | uint16_t result = 0; // konverteerimise tulemuse muutuja | ||
| - | |||
| - | ADCSRA = (1<< | ||
| - | // AD konfigureerimine prescaler 8 (1) ja ADC aktiveerimine (1) | ||
| - | ADMUX = mux; | ||
| - | // Kanali määramine (funktsiooni sisendmuutuja mux kaudu) | ||
| - | ADMUX |= (1<< | ||
| - | // Referentspinge määramine (sisemine ref = 2,56V) | ||
| - | |||
| - | /* Peale ADC aktiveerimist on soovitav teha üks test lugem, ehk " | ||
| - | ADCSRA |= (1<< | ||
| - | while ( ADCSRA & (1<< | ||
| - | ; | ||
| - | } | ||
| - | // Tegelik mõõtmine, täpsema väärtuse saamiseks tehakse 4 mõõtmist (i max väärtus) | ||
| - | for(i=0; | ||
| - | { | ||
| - | ADCSRA |= (1<< | ||
| - | while ( ADCSRA & (1<< | ||
| - | ; // oodatakse kuni konverteerimine on lõpetatud | ||
| - | } | ||
| - | result += ADCW; // Tulemused liidetakse kokku (4 x) | ||
| - | } | ||
| - | ADCSRA &= ~(1<< | ||
| - | result /= 4; // Tulemus jagatakse 4-ga: võetakse arit. keskmine | ||
| - | return result; // | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | |||
| - | ===== Väärtuse ümardamine ja integreerimine ===== | ||
| - | |||
| - | Järgnev näide demonstreerib kuidas ADC kanali pingeväärtusi lugeda, neid ümardada ja integreerida. Sujuvad muutuse demonstreerimiseks süüdatakse olenevalt muutuse suuresest rohkem LED-e. Vaja on ühendada [[Digitaalsed sisend-väljundid]]plaat. | ||
| - | |||
| - | Näite põhjal saaks teha valveseadme. Kui kaugusmõõdiku ees toimub liikumine läheb olenevalt liikumise kiirusest kas roheline või kollane LED põlema, kui aga järsk liigutus, süttib punane. Valveseadet ei saa liiga tundlikuks teha kuna olenevalt keskkonnast, | ||
| - | |||
| - | See näide kasutab viikude operatsiooni faili {{examples: | ||
| - | |||
| - | <code c> | ||
| - | // | ||
| - | // ADC sampling and integrating demonstration | ||
| - | // | ||
| - | // Mikk Leini | ||
| - | // | ||
| - | // 2009 | ||
| - | // | ||
| - | |||
| - | // Include avrlibc | ||
| - | #include < | ||
| - | #include < | ||
| - | |||
| - | // Include common library | ||
| - | #include " | ||
| - | |||
| - | // Math operations | ||
| - | #define DIFF(a, b) ((a) < (b) ? (b) - (a) : (a) - (b)) | ||
| - | #define INTEGRATE(value, | ||
| - | |||
| - | // Configure pins | ||
| - | #define LEDR PORTPIN(C, 5) | ||
| - | #define LEDY PORTPIN(C, 4) | ||
| - | #define LEDG PORTPIN(C, 3) | ||
| - | |||
| - | // | ||
| - | // ADC conversion waiting | ||
| - | // | ||
| - | void adc_wait_until_done(void) | ||
| - | { | ||
| - | while (IS_BIT_SET(ADCSRA, | ||
| - | { | ||
| - | asm volatile (" | ||
| - | } | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // ADC channel value sampling | ||
| - | // | ||
| - | unsigned short adc_sample_value(unsigned char channel, unsigned char num_samples) | ||
| - | { | ||
| - | unsigned short result = 0; | ||
| - | |||
| - | // ADC setup - prescaler 8 | ||
| - | ADCSRA = BIT(ADEN) | BIT(ADPS1) | BIT(ADPS0); | ||
| - | |||
| - | // Specify channel | ||
| - | ADMUX = channel & 0x0F; | ||
| - | |||
| - | // Reference voltage to external (+5V) | ||
| - | ADMUX |= BIT(REFS0); | ||
| - | |||
| - | // Take test sample to "warm up" converter | ||
| - | // Usually the first sample is discarded | ||
| - | SET_BIT(ADCSRA, | ||
| - | adc_wait_until_done(); | ||
| - | |||
| - | // Real sampling, sum up specifed number of samples | ||
| - | for (unsigned char i = 0; i < num_samples; | ||
| - | { | ||
| - | SET_BIT(ADCSRA, | ||
| - | adc_wait_until_done(); | ||
| - | |||
| - | // Sum-up | ||
| - | result += ADCW; | ||
| - | } | ||
| - | |||
| - | // De-activate ADC | ||
| - | CLEAR_BIT(ADCSRA, | ||
| - | |||
| - | // Return averaged result | ||
| - | return (result / num_samples); | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // Program entrance function | ||
| - | // | ||
| - | int main(void) | ||
| - | { | ||
| - | unsigned short sampledValue = 0; | ||
| - | unsigned short integratedValue = 0, oldIntegratedValue = 0; | ||
| - | unsigned short diff = 0; | ||
| - | |||
| - | // LED initialization | ||
| - | setup_output_pin(LEDR); | ||
| - | setup_output_pin(LEDY); | ||
| - | setup_output_pin(LEDG); | ||
| - | |||
| - | // Endless loop | ||
| - | while (1) | ||
| - | { | ||
| - | // Sample ADC channel 0 | ||
| - | sampledValue = adc_sample_value(0, | ||
| - | |||
| - | // Integrate value over 3 steps (each 50 ms) | ||
| - | INTEGRATE(integratedValue, | ||
| - | |||
| - | // Calculate difference between old and new value | ||
| - | diff = DIFF(integratedValue, | ||
| - | |||
| - | // Display LED-s depending of difference | ||
| - | set_pin_to(LEDR, | ||
| - | set_pin_to(LEDY, | ||
| - | set_pin_to(LEDG, | ||
| - | |||
| - | // Store old value | ||
| - | oldIntegratedValue = integratedValue; | ||
| - | |||
| - | // Wait 50 ms | ||
| - | _delay_ms(50); | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ===== Välised viited ===== | ||
| - | * [[http:// | ||