ИК бампер
Материал из LicrymWiki
Простой самодельный датчик препятствия для робота - инфракрасный. Существуют варианты на датчиках вроде TSOP, но они имеют ряд недостатков. Попробуем сделать иной датчик.
Благодаря тому, что сенсор аналоговый, то мы получаем возможность примерно оценивать расстояние до препятствия. Не абсолютно конечно, а относительно, так как уровень сигнала сильно зависит от объекта.
Итак, схема довольно проста:
Используется пара светодиод и фототранзистор (фототранзистор эффективнее фотодиода). Транзистор Q1 используется для усиления сигнала. При освещении фототранзистора через него начинает протекать ток, который через резистор R1 попадает на базу транзистора, транзистор приоткрывается, и напряжение на коллекторе начинает падать. Напряжение с коллектора мы отправляем на вход АЦП. Для управления светодиодом используется MOSFET, так как светодиод потребляет 50 мА, в то время как максимальная нагрузка на порт – не более 20 мА.
Работает так. Мы включаем светодиод и начинаем измерять ток через фототранзистор. Если препятствие близко, то часть ИК излучения отразится от него и попадет на фототранзистор, если же препятствия нет, то ИК излучение уйдет в пустоту. Затем мы выключаем светодиод и снова измеряем ток через фототранзистор. Если препятствие есть, то оно теперь не подсвечивается, что и вызовет разницу в токе между включенным и выключенным светодиодом. И именно благодаря работе с разностью освещенности бампер нечувствителен к общему уровню засветки. Единственное, что при ярком свете через фототранзистор будет протекать такой ток, что транзистор откроется полностью, и колебания тока будут за пределом области усиления. Сей недостаток устраняется введением некого подобия АРУ, например переключение резистора в базе транзистора на более высокие значения в случае яркого освещения.
В собранном виде это может выглядеть так:
Код для работы с бампером:(написан в CodeVisionAVR)
/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.7 beta 5 Professional
Automatic Program Generator
© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 24.02.2008
Author : Spiritus Sancti
Company : licrym.org
Comments:
Chip type : ATmega8
Program type : Application
Clock frequency : 8,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega8.h>
#include <delay.h>
#define ADC_VREF_TYPE 0x40
bit ADC_complete;
int gADC_result;
interrupt [ADC_INT] void adc_isr(void) //обработчик прерывания по завершению преобразования АЦП
{
unsigned int adc_data;
adc_data=ADCW;
gADC_result=adc_data; //отсылаем считанное значение в глобальную переменную и устанавливаем флаг
ADC_complete=1;
}
int poll_sensor(void){ //процедура опроса сенсора
int delta;
PORTB.0=1; //включаем светодиод ИК подсветки
delay_ms(1); //ждем пока разгорится
ADCSRA|=0x40; //отсылаем бит, запускающий процедуру АЦП
while(ADC_complete!=1); //ждем пока не закончится АЦП
delta=gADC_result;
ADC_complete=0; //сбрасываем флаг
PORTB.0=0; //выключаем светодиод, и снова измеряем
delay_ms(1);
ADCSRA|=0x40;
while(ADC_complete!=1);
delta=gADC_result-delta;//вычисляем значение разности
ADC_complete=0; //сбрасываем флаг
return delta;
}
void main(void)
{
int razn;
//инициализация портов и т.д.
PORTB=0x00;
DDRB=0xFF;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0xFF;
TCCR0=0x00;
TCNT0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC Clock frequency: 1000,000 kHz
// ADC Voltage Reference: AVCC pin
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x8B;
// Global enable interrupts
#asm("sei")
while (1)
{
razn=poll_sensor();
//пример использования сенсора. Присвоим переменной значение разности,
// и в зависимости от полученного значения будем зажигать светодиоды на порту D
//можно просто запускать какой либо процесс, если разность превышает определенный порог
if(razn >10) PORTD.0=1;
if(razn >20) PORTD.1=1;
if(razn >30) PORTD.2=1;
if(razn >40) PORTD.3=1;
if(razn >50) PORTD.4=1;
if(razn >60) PORTD.5=1;
if(razn >70) PORTD.6=1;
if(razn >80) PORTD.7=1;
delay_ms(1);
PORTD=0;
};
}
Такой бампер также можно применять в различных схемах для определения препятствия, например в будильнике, выключающем сигнал, если над ним пронести руку.
Видео (DivX6 500кб) демонстрирующее работу бампера (в микроконтроллер прошит код выше)
http://licrym.org/images/wiki/irbump.avi
Данный датчик использован в проекте простого робота с датчиками



