Эксперимент #25: Ультразвуковой модуль измерения расстояния HC-SR04

Следующим шагом для небольшого проекта стал модуль измерения расстояния  HC-SR04.

Попробуем завести эту штуковину с помощью микроконтроллера PIC16f628a :)

Начнем, пожалуй, с даташита.

Девайс имеет 4 пина: Vcc, Gnd, Trig, Echo. Если с первыми двумя все понятно, то с остальными не совсем. Если их рассматривать по простому,то по Trig мы управляем датчиком, а по Echo – снимаем результаты.

Вот как это выглядит в даташите:

Мы поднимаем линию Trig на 10 мкс и ждем сигнала на Echo. Тут надо сказать, что меня немного поставило в тупик две вещи: картинка выше и следующая выкладка в даташите:

You can calculate the range through the time interval between sending trigger signal and receiving echo signal.

Налицо два противоречивых указания: в одном говорится что, длина импульса пропорциональна расстоянию, во втором, что пропорционально время от посылки сигнала до получения отклика по пину Echo. Оказалось что первое утверждение правильное, так что если кто будет по моей статье разбираться учтите :)

Чтобы получить расстояние в сантиметрах:

Расстояние (см) = Время импульса (мкс)/58

Ну вроде все понятно, пробуем получить хоть что-нибудь:


if (!RB1)
 {
  __delay_ms(100);
   if (!RB1)
    {
     RMeas = 0;
     RMeas = 1;
     __delay_us(10);
     RMeas = 0;
    }//if (!RB1) inner
}//if (!RB1)

RMeas – пин, на который подключен вывод Trig, он настроен на выход, ну а по коду все просто – обычый короткий 10 мкс импульс по нажатию кнопки.

Собираем тестовую установку:

Примерно 13 см от платы до препятствия, +можно накинуть 1 см на расстояние от платы, до непосредственно датчика, пробуем:

630/58 = 11 см, таким образом ошибка составляет 1-1.5 см, для наших целей вполне терпимо.

Алгоритм обработки тоже видится достаточно прозрачным:

  • Засекаем нарастающий фронт и запускаем таймер
  • Засекаем спадающий фронт и снимаем показания таймера
  • Переводим значение таймера в микросекунды и производим все необходимые вычисления

Функция снятия значений выглядит примерно так:


void GetRange()
{
 tempTmr1 = 0;
 StRMeas = 0;                //Инициализируем модуль
 RMeas = 0;
 RMeas = 1;
 __delay_us(10);
 RMeas = 0;
 StRMeas = 0;
 __delay_us(100);
 RBIE = 1; //Включаем прерывания по изменению состояния порта
 RBlowFlag = 0; //Статусная переменная

 while (!RBlowFlag)         //Цикл пока не закончится импульс от Echo
  {
   if (RBhighFlag)          //По возрастающему фронту
    {
      InitTimer1();         //Запускаем таймер1
      RBhighFlag = 0;
    }
  }

 TMR1ON = 0;
 tempTmr1 = TMR1H;          //Сливаем значение таймера в локальную переменную
 tempTmr1 <<= 8;
 tempTmr1 |= TMR1L;

 lcd_clear();               //и выводим инфу на дисплей
 lcd_goto(0x00);

 Range = tempTmr1/174 + 2; //Поправочный коэффициент - 2 см
 lcd_puts("Range, cm");
 display_digit(Range, 0x40);
}

Ну и небольшая часть обработчика прерываний по выводу Echo:


void interrupt isr()
{
if (RBIF)
  {
  if (!Recho)
    {
     RBlowFlag = 1;
     RB5 = 0;
    }
  if (Recho)
    {
     RB5 = 1;
     RBhighFlag = 1;
    }
RBIF = 0;

}//if (RBIF)

} //isr()

Здесь поправочный коэффициент 2 выбран экспериментальным путем. Ну собственно и все, напоследок видео с результатом работы:

Эксперимент #25: Ультразвуковой модуль измерения расстояния HC-SR04: 7 комментариев

  1. молодец!не хватает в твоей лаборатории опыта с давлением воды и датчиком освещенности

    Ответить

    sarge Ответил:

    Спасибо, в первом как то необходимости не возникало, а вот со вторым как раз жду с китая фоторезисторы и буду делать регулировку подсветки экрана для небольшого проекта :)

    Ответить

  2. а в лаборатории выложишь про освещенность ?

    Ответить

    sarge Ответил:

    Там к мк отношения девайс иметь не будет, так что опишу только в проекте, который надеюсь в скором времени закончить.

    Ответить

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.