ATmega128 적외선 거리센서(SHARP_2Y0A21) 제어하기

2019. 8. 4. 18:20임베디드/ATmega128

적외선 거리센서의 구동원리는 적외선을 발광하여 반사물에 반사되는 적외선 양에 따라 거리를 측정하며, 측정된 거리만큼 아날로그 전압으로 출력되는 것이다. 거리 측정은 10~80cm로, 10cm 이하는 측정이 되지 않는다. 그리고 반사물의 색상과 반사율에 의한 영향을 크게 받지 않는 것과 초음파 센서와 다르게 값이 잘 튀지 않는 다는 것이 장점이다

 

실제 데이터시트를 보면 triangulation method를 채택했기 때문에, 거리 감지에 있어서 반사율, 온도 그리고 동작 지속 시간은 영향을 받지 않는다고 나와있다

 

http://www.sharp-world.com/products/device/lineup/data/pdf/datasheet/gp2y0a21yk_e.pdf

 

http://www.sharp-world.com/products/device/lineup/data/pdf/datasheet/gp2y0a21yk_e.pdf

 

그리고 측정하는 시간에 대해서 자세하게 알아야 한다. 최대로 50ms당 한 번씩 측정을 해야만 한다

 

 

그리고 가장 중요한 거리 환산표다

 

 

아래 그래프를 역으로 눕혀서 생각해보면 volt가 입력이고, dist가 출력이 된다. 따라서 대충 1을 기준으로 맞춘다면 0.04*volt가 출력인 y가 된다. 이를 뒤집는다면 실제 거리가 구해질 것이다

 

깃허브주소: https://github.com/surinoel/avr/tree/master/adc/SHARP_2Y0A21/SHARP_2Y0A21

 

/*
* adc.c
*
* Created: 2019-05-18 오후 10:14:50
* Author: yeong
*/
#include "adc.h"
extern FILE OUTPUT;
extern FILE INPUT;
void adc_init(unsigned char ch) {
ADMUX |= (1<<REFS0);
ADMUX = ((ADMUX & 0xE0) | ch);
ADCSRA |= 0x07;
ADCSRA |= (1<<ADEN) | (1<<ADFR) | (1<<ADSC);
}
void adc_change_channel(unsigned char ch) {
ADMUX = ((ADMUX & 0xE0) | ch);
_delay_us(50);
}
int adc_read(void) {
_delay_ms(50);
while(!(ADCSRA & (1<<ADIF)));
return ADC;
}
view raw 2y0a21.c hosted with ❤ by GitHub
/*
* SHARP_2Y0A21.c
*
* Created: 2019-08-04 오후 12:28:29
* Author : yeong
*/
#include <avr/io.h>
#include "uart.h"
#include "adc.h"
float calc_distance(float volt)
{
float val = 0.04 * volt;
return (1/val);
}
int main(void)
{
float volt, dist;
uart0_init();
adc_init(0x01);
/* Replace with your application code */
while (1)
{
volt = 5.0*adc_read()/1024;
// printf("voltage:%f\r\n", 5.0*adc_read()/1024);
dist = calc_distance(volt);
if(dist>=10 && dist<=80) {
printf("dist:%f\r\n", dist);
}
}
}
view raw main.c hosted with ❤ by GitHub