This is an old revision of the document!


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

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.

/* 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
}

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ä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 faili "pin.h"

//
// 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
	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, 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
		set_pin_to(LEDR, diff < 20);
		set_pin_to(LEDY, diff < 10);
		set_pin_to(LEDG, diff < 5);
 
		// Store old value
		oldIntegratedValue = integratedValue;
 
		// Wait 50 ms
		_delay_ms(50);
	}
}

Välised viited

et/examples/sensor/ir.1250537391.txt.gz · Last modified: 2020/07/20 09:00 (external edit)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0