Подключение радарного датчика HS-SR04 к микроконтроллеру Atmega8

В качестве радарного датчика будем использовать датчик 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(‘!’);// выводим если ошибка в обработке данных
}

 }
}