Table of Contents

 

Infrapuna kaugusandur

Vajalikud teadmised: [HW] Kasutajaliidese moodul, [AVR] Analoog-digitaalmuundur,
[LIB] Analoog-digitaalmuundur, [LIB] Graafiline LCD, [LIB] Andurid

Teooria

Sharp GP2Y0A21YK

Objekti kauguse mõõtmiseks on olemas triangulatsioonimeetodil töötavad optilised andurid. Levinuimad neist on firma Sharp poolt toodetavad infrapuna (inglise keeles infra-red, lühend IR) lainepikkusel töötavad analoogpinge väljundiga kaugusandurid. Sharp-i anduritel on läätsega IR LED, mis kiirgab kitsast valguskiirt. Objektilt peegeldunud kiir suunatakse läbi teise läätse positsioonitundlikule fotoelemendile (inglise keeles position-sensitive detector, lühend PSD). PSD-le langeva kiire asukohast sõltub selle juhtivus. Juhtivus muundatakse pingeks ja seda näiteks mikrokontrolleri analoog-digitaalmuunduriga digitaliseerides saab välja arvutada kauguse. Erinevatelt kaugustelt peegelduvate kiirte teekonda näitab kõrvalolev joonis.

IR kaugusmõõdiku valguskiire teekond

Sharp-i kaugusandurite väljund on pöördvõrdeline - kauguse kasvades see väheneb ja järjest aeglasemalt. Täpne kauguse ja väljundi vaheline graafik on toodud andurite andmelehel. Anduritel on vastavalt tüübile ka mõõtepiirkond, milles nende väljund on usaldusväärne. Maksimaalsele reaalselt mõõdetavale kaugusele seab piiri kaks aspekti: peegelduva valguse intensiivsuse vähenemine ja PSD-e võimetus registreerida väikest peegeldunud kiire asukoha muutust. Liiga kaugete objektide mõõtmisel jääb anduri väljund ligikaudu samaks, mis maksimaalselt mõõdetava kauguse puhulgi. Minimaalne mõõdetav kaugus on piiratud Sharp-i andurite omapära tõttu - nimelt hakkab väljundpinge kauguse vähenedes teatud kaugusel (olenevalt andurist 4-20 cm) järsult jälle vähenema. Sisuliselt tähendab see, et ühele väljundpinge väärtusele vastab kaks kaugust. Probleemide ärahoidmiseks tuleb vältida objektide andurile liiga lähedale sattumist.

Praktika

Tüüpiline Sharp IR kaugusmõõdiku pinge-kauguse graafik

Kodulabori andurite komplektis on Sharp-i infrapuna kaugusmõõdik GP2Y0A21YK mõõtepiirkonnaga 10-80 cm. Anduri väljundpinge on kuni 3 V sõltuvalt mõõdetavast kaugusest. Anduri saab ühendada Kodulabori mooduli külge valitud analoogkanalisse. Eelnevate andurite harjutuste baasil saab lihtsalt teha programmi, mis mõõdab kaugusmõõdiku väljundpinget, kuid lisaks on selle harjutuse eesmärk veel pinge kauguseks teisendamise protsessi tutvustamine.

GP2Y0A21YK andmelehel on toodud väljundpinge ja mõõdetud kauguse vahelise sõltuvuse graafik. See pole lineaarne, kuid väljundpinge ja kauguse pöördväärtuse graafik peaaegu juba on, ning sellest on suhteliselt lihtne leida valem pinge kauguseks teisendamiseks. Valemi leidmiseks tuleb sama graafiku punktid sisestada mõnda tabelarvutuse programmi ja nendest uuesti graafik luua. Tabelarvutusprogrammides on graafiku punktide põhjal võimalik arvutada automaatselt välja trendijoon. Järgnevalt on toodud GP2Y0A21YK väljundpinge ja kauguse korrigeeritud pöördväärtuse vahelise seose graafik koos lineaarse trendijoonega. Väljundpinge on valemi lihtsustamise nimel juba teisendatud 10-bitiseks +5 V võrdluspingega analoog-digitaalmuunduri väärtuseks.

Kauguse ja ADC väärtuse lineariseerimise graafik

Nagu graafikult näha, kattub trendijoon (sinine) üsna täpselt graafiku punktidega (punane joon). Selline kattuvus on saavutatud kauguse korrigeerimiskonstandi abil. Korrigeerimiskonstant on leitud katse-eksitusmeetodil - läbi on proovitud erinevaid arve, kuni on leitud selline, mille korral graafik kattub trendijoonega kõige rohkem. Antud graafiku puhul on see +2, ehk kõigile reaalsetele kaugustele on graafikus 2 otsa liidetud. Kuna nii on graafik väga sarnane lineaarsele trendijoonele, võib teha üldistuse ja öelda, et kauguse ja pinge vaheline seos on järgmine:

1 / (d + k) = a ⋅ ADC + b

kus

Valemist saab avaldada kauguse d:

d = (1 / (a ⋅ ADC + B)) - k

Põhimõtteliselt saakski selle valemiga kauguse välja arvutada, kuid see eeldaks ujukoma-arvutusi, sest jagatises tekivad murdarvud. Täisarvudega opereeriva mikrokontrolleri jaoks tuleb valemit lihtsustada ja suuremate tegurite peale ümber teisendada. Valemi jagatist lineaarliikmega läbi jagades saab see kuju:

d = (1 / a) / (ADC + B / a) - k

Viies valemisse korrigeerimiskonstandi väärtuse ja trendijoone võrrandist saadud lineaar- ja vabaliikme (saadud jooniselt), tuleb kauguse arvutamise valemiks:

d = 5461 / (ADC - 17) - 2

See valem on arvutatav 16-bitiste täisarvudega ja täiesti jõukohane AVR-ile. Enne arvutamist tuleb aga veenduda, et ADC väärtus oleks üle 17, sest muidu tekib nulliga jagamine või negatiivne kaugus, mis on ebaloogiline.

Järgnevalt on toodud Kodulabori teegis kirja pandud funktsioon ADC väärtuse sentimeetriteks teisendamise kohta. Lineaar- ja vabaliige ning korrigeerimiskonstant pole funktsiooni jäigalt sisse kirjutatud, vaid need antakse ette IR kaugusanduri parameetrite struktuuri objektiga. Hoides parameetreid eraldi konstandis, saab hiljem programmi lihtsalt lisada uusi IR kaugusandurite mudeleid.

// IR kaugusanduri parameetrite struktuur
typedef const struct
{
	const signed short a;
	const signed short b;
	const signed short k;
}
ir_distance_sensor;
 
// GP2Y0A21YK anduri parameetrite objekt
const ir_distance_sensor GP2Y0A21YK = { 5461, -17, 2 };
 
// IR kaugusanduri ADC väärtuse sentimeetriteks teisendamine
// Tagastatakse -1, kui teisendus ei õnnestunud
signed short ir_distance_calculate_cm(ir_distance_sensor sensor,
	unsigned short adc_value)
{
	if (adc_value + sensor.b <= 0)
	{
		return -1;
	}
 
	return sensor.a / (adc_value + sensor.b) - sensor.k;
}

Teisenduse tegemiseks tuleb välja kutsuda ir_distance_calculate_cm funktsioon, mille esimene parameeter on IR kaugusanduri parameetrite objekt, teine aga ADC väärtus. Funktsioon tagastab arvutatud kauguse sentimeetrites. Väära tehte (ehk siis ebaloomuliku ADC väärtuse) korral tagastab funktsioon -1. IR kaugusanduri ja teisendusfunktsiooni kasutamist demonstreerib järgnev programm. Kasutusel on LCD ekraan, kus kuvatakse mõõtetulemust. Ebaloomuliku kauguse puhul kuvatakse küsimärki.

 

// Kodulabori IR kaugusmõõdiku näidisprogramm
// LCD ekraanil kuvatakse mõõdetud kaugus sentimeetrites
#include <stdio.h>
#include <homelab/adc.h>
#include <homelab/delay.h>
#include <homelab/module/sensors.h>
#include <homelab/module/lcd_gfx.h>
 
#define ADC_CHANNEL 0
 
// Põhiprogramm
int main(void)
{
	signed short value, distance;
	char text[16];
 
        // Robootika Kodulabor II Andurite moodul väliste andurite viik
	//pin ex_sensors = PIN(G, 0);
	//pin_setup_output(ex_sensors);
	//pin_set(ex_sensors);
 
	// LCD ekraani seadistamine
	lcd_gfx_init();
	lcd_gfx_clear();
	lcd_gfx_goto_char_xy(1,2);
	lcd_gfx_write_string("Kaugusandur");
 
	// ADC muunduri seadistamine
	adc_init(ADC_REF_AVCC, ADC_PRESCALE_8);
 
	// Lõputu tsükkel
	while (1)
	{
		// Anduri väljundpinge 4-kordselt ümardatud väärtuse lugemine
		value = adc_get_average_value(ADC_CHANNEL, 4);
 
		// ADC väärtuse kauguseks ümberarvutamine
		distance = ir_distance_calculate_cm(GP2Y0A21YK, value);
 
		lcd_gfx_goto_char_xy(1,3);
 
		// Kauguse või veateate kuvamine
		if (distance >= 0)
		{
			sprintf(text, "%3d cm   ", distance);
		}
		else
		{
			sprintf(text, "Viga   ");
		}
 
		lcd_gfx_goto_char_xy(1,3);
		lcd_gfx_write_string(text);
		sw_delay_ms(500);
	}
}