This is an old revision of the document!
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
Joonis 2 Anduri ühendamine
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.
/* Lihtne AD muunduri kasutamine Mikael Hellgren/Raivo Sell (2008) */ #include <avr\io.h> int main(void) { unsigned int adc10; ADMUX = 0xC0; while(1) { ADCSRA = 0xC3; while ( ADCSRA & (1<<ADSC) ) {;} // oodatakse kuni konverteerimine on lõpetatud adc10 = ADC; } }
Põhjalikum AD muunduri funktsioon
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<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // AD konfigureerimine prescaler 8 (1) ja ADC aktiveerimine (1) ADMUX = mux; // Kanali määramine (funktsiooni sisendmuutuja mux kaudu) ADMUX |= (1<<REFS1) | (1<<REFS0); // Referentspinge määramine (sisemine ref = 2,56V) /* Peale ADC aktiveerimist on soovitav teha üks test lugem, ehk "soojendada konverter üles" */ ADCSRA |= (1<<ADSC); // ühe AD lugemi võtmine while ( ADCSRA & (1<<ADSC) ) { ; // oodatakse kuni konverteerimine on lõpetatud } // Tegelik mõõtmine, täpsema väärtuse saamiseks tehakse 4 mõõtmist (i max väärtus) for(i=0;i<4;i++) { ADCSRA |= (1<<ADSC); // ADC "single conversion" reziim while ( ADCSRA & (1<<ADSC) ) { ; // oodatakse kuni konverteerimine on lõpetatud } result += ADCW; // Tulemused liidetakse kokku (4 x) } ADCSRA &= ~(1<<ADEN); // ADC deaktiveerimine (2) result /= 4; // Tulemus jagatakse 4-ga: võetakse arit. keskmine return result; //Tagastatakse tulemus }
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äljundidplaat.
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, toitepingest ja muudest füüsilistest teguritest võib kaugusmõõdiku näit muutuda ka ilma, et keegi selle ees liigutaks. Seepärast tulebki kasutada suhteliselt näidu muutuse võrdlust.
See näide kasutab viikude operatsiooni teeki mille leiab siit.
// // ADC sampling and integrating demonstration // // Mikk Leini // // 2009 // // Include avrlibc #include <avr/io.h> #include <util/delay.h> // Include common library #include "pin.h" // Math operations #define DIFF(a, b) ((a) < (b) ? (b) - (a) : (a) - (b)) #define INTEGRATE(value, new_value, n) value = (value * (n - 1) + new_value) / n; // 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, ADSC)) { asm volatile ("nop"); } } // // 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, ADSC); adc_wait_until_done(); // Real sampling, sum up specifed number of samples for (unsigned char i = 0; i < num_samples;i++) { SET_BIT(ADCSRA, ADSC); adc_wait_until_done(); // Sum-up result += ADCW; } // De-activate ADC CLEAR_BIT(ADCSRA, ADEN); // 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 pin_setup_output(LEDR); pin_setup_output(LEDY); pin_setup_output(LEDG); // Endless loop while (1) { // Sample ADC channel 0 sampledValue = adc_sample_value(0, 4); // Integrate value over 3 steps (each 50 ms) INTEGRATE(integratedValue, sampledValue, 5); // Calculate difference between old and new value diff = DIFF(integratedValue, oldIntegratedValue); // Display LED-s depending of difference pin_set_to(LEDR, diff < 20); pin_set_to(LEDY, diff < 10); pin_set_to(LEDG, diff < 5); // Store old value oldIntegratedValue = integratedValue; // Wait 50 ms _delay_ms(50); } }
Alljärgnev kood võtab anduri lugemi ja näitab tulemuse LCD ekraanil. NB! tegemist ei ole kaugusega sentimeetrites vaid muunduri väljundiga, mis on analoogsignaali (pinge) konverteerimise tulemus digitaalkujul. Näide kasutab tekstilise LCD ekraani teeki (lcd.c ja lcd.h).
#include <avr/io.h> #include "lcd.h" int main(void) { //tekstiline muutuja char buffer[15]; // LCD algväärtustamine ja puhastamine lcd_init(LCD_DISP_ON); lcd_clrscr(); //AD kanali ja võrdluspinge määramine ADMUX = 0x43; // Võrdluspinge 5 V, Kanal ADC3 //Konverteri lubamine ja käivitamine ADCSRA = 0xC0; //Konverteerimine ja tulemuse ootamine while ( ADCSRA & (1<<ADSC) ) {;} //Tulemuse konverteerimine tekstiks // itoa (number, string, (10=decimal,16=hexadecimal) ) itoa(ADC, buffer, 10); //Uue väärtuse kuvamine ekraanil lcd_puts(buffer); }