В качестве радарного датчика будем использовать датчик HS-SR04. Это довольно простой датчик, дальность его у меня составили максимум 3 метра, минимум пару сантиметров.
Алгоритм работы простой: на вход Trig подается импульс с длительностью 10 микросекунды, после чего датчик посылает звуковой импульс на частоте 40кГц. После того, когда сигнал вернется обратно, ножка Echo устанавливается в единицу и по истечению времени, которое пропорционально времени отправки — получения импульса — устанавливается в ноль.
Зная скорость звука (340 м/с) и учитывая, что звук проходит два расстояния (до предмета и обратно) -получаем, что звук проходит 1 сантиметр за 58,8 микросекунд.
Нам остается настроить таймер, который будет запускаться по высокому уровню сигнала Echo и останавливаться после перехода уровня сигнала Echo с 1 в 0. Зная скорость счета таймера, можно высчитать расстояние которое прошел звук и как следствие расстояние до предмета.
Сигнал Echo подключается к PB0, сигнал Trig подключается к PB1.
В нашем программе таймер будет запускаться по прерыванию от сигнала Echo и останавливаться при переходе этого же сигнала с 1 в 0. В случаи если счетчик вернул ноль или досчитал до конца — мы выдаем ошибку.
Программный код:
#include «main.h»
volatile unsigned char status;
char str[4]={0};
#define TRIG PB1
volatile uint16_t impulse;
ISR(TIMER1_CAPT_vect){ //прерывание первого счетчика
TCNT1H=0;TCNT1L=0; // обнуляем счетчик
uint16_t tmp;
impulse=(uint16_t)ICR1L; // считываем младшие байты
tmp=(uint16_t)ICR1H; // считываем старшие байты
impulse |=(tmp << 8); // соединяем в единое целое старшие и младшие байты
impulse /= 45;
}
int main(void){
// настройка первого таймера
TIMSK =(1<<TICIE1);//разрешаем прерывание
TCCR1B=(1<<CS11); // претделитель 1/8
//очистка значения счетчика
TCNT1H=0;
TCNT1L=0;
impulse=1;
// настройка ножки Trig (РВ1)
DDRB |= (1<<TRIG);
// настройка экрана
I2C_init();
LCD_ini();
clearlcd();//очистка экрана
setpos(0,0);
str_lcd(«Hello World!»);
while (1){
_delay_ms(200);
if (impulse!=0){// датчик закончил мерять расстояние
cli(); // запрет прерывания
setpos(0,2);
str[0]=((impulse%10000)/1000+48); // 100 position
sendcharlcd(str[0]);
str[1]=((impulse%1000)/100+48); // 100 position
sendcharlcd(str[1]);
str[2]=(((impulse%100)/10)+48); // 10 position
sendcharlcd(str[2]);
str[3]=((impulse%10)+48); // 1 position
sendcharlcd(str[3]);
// очистка счетчика
TCNT1H=0;
TCNT1L=0;
impulse=0;
// запускаем импульс в 10мС на ножку TRIG
PORTB |= (1<<TRIG);
_delay_us(10);
PORTB &= ~(1<<TRIG);
sei();//разрешаем прерывание
}
else{
setpos(0,4);
sendcharlcd(‘!’);// выводим если ошибка в обработке данных
}
}
}