Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: STM32, ультразвуковой измеритель HC-SR04  (Прочитано 3072 раз)
0 Пользователей и 1 Гость смотрят эту тему.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« : 09-01-2022 20:59 » 

Продолжаю баловаться железом. На очереди готовый модуль HC-SR04 — ультразвуковой датчик растояния на 40 кГц. Все так же куплено на Али по случаю скидок исключительно с целью поиграться. Китайцы обожают затирать номиналы микросхем: у меня затерты две из трех и нет маркировки на кварце. При этом в интернете есть фотки, где затерта только одна и кварц маркирован. Каждый развлекается как может.
У меня плата выглядит так:


Китайцы заявляют рабочий диапазон от 2 см до 4 м с и точностью 2 мм. Для пуска нужен импульс от 10 мкс в линию Trig. После чего нужно ждать ответный импульс на линии Echo и измерить его длительность — это будет полетное время, то есть делим на два и умножаем на 340 м/с для опредления дистанции до препятствия. Но это будет не точно, потому как скорость звука зависит от атмосферного давления и температуры. Еще китайцы пишут про "квадратную волну", могу предположить, что имелась в виду "плоская волна". Может быть, не могу проверить. Расхождение луча на 3-х метрах уже такое, что задевает все в комнате, и более 2.5 м зафиксировать не смог. На расстоянии ближе 50 мм начинает сильно врать и уже на 10-15 мм перестает видеть полностью.
Собираем простейшую схему на макетной плате: модуль Nucleo STM32L432KC (тут FPU есть), модуль HC-SR04, макетная плата, несколько соединительных проводов. Запитываю от USB, по нему же назад идут логи через UART.

Питается оно от 5 В, когда как STM32 работает от 3.3 В. Впрочем, устройство входной импульс 3.3 В вполне понимает, а STM32 безболезненно принял сигнал 5 В, хотя данный вывод не отмечен как "5 V tolerant I/O", только как "3.6". В реальном устройстве, конечно, надо бы защиту поставить, но тут эксперимент, продолжаем.
Конфигурирование выводов в STM32CubeMX:

Если взять предел датчика в 4 м, это будет примерно 11.7 мс в одну сторону при скорости 340 м/с. 340 — это при "нормальных условиях", то есть при 760 мм рт.ст. и 20° C. Что у меня — черт его знает, в квартире все показометры показывают каждый что-то свое, но очень точно. Век электроники же, калибровать ширпотреб никто не будет. И я очень не уверен, что 4 метра — это предел и эхо не прилетит с опозданием. Так что на всякий случай взял с запасом, цикл сканирования будет 40 мс, что примерно соответствует расстоянию в 6.8 метра.
Формировать стартовый импульс, принимать фронты ответа, а за одно и управлять яркостью светодиода будет таймер TIM2 (хотя ШИМ 25 Гц — это жуткое мерцание). Тактирую таймер от 80 МГц с делителем на 8, то есть дискретность 100 нс, что в пересчете на расстояние — 17 мкм, что явно с избытком, но я так хочу. Это же эксперимент.
Тут: CH1 — строб, CH2 — LED, CH3 и CH4 — замеры эха.

Судя по осциллограммам, начало ответного импульса стартует примерно через пол миллисекунды. Не знаю, что именно должно ограничивать точность ответного импульса, он же не дискретный. Я очень грубо его пересчитал на точность 1 мм, таймер и осциллограф говорят, что вполне можно иметь и такую точность. Расстояние до препятствия примерно похожее. Кажется все. Скучно. Попробуем померить точность, померить дрожание фаз, увеличить частоту сканирования.

Уменьшил цикл до 30 мс. Распечатываю в UART значения захвата счетчика и вычисленное расстояние. При фиксированном препятствии (по данным датчика — 95 мм) вычисленное целочисленное расстояние, с точностью до 1 мм, не меняется. Ну почти. Если сделать много выборок — у меня их около 400 — вырисовывается такая картина: начало импульса весьма стабильно 475±2 мкс, а вот ширина импульса имеет среднее отклонение в переделах 0.5 мм и есть регулярные выбросы до ±5 мм. Так что китайцы с ±2 мм немного обманули. Двигая плату в пределах 70-150 мм от вертикального препятствия, получаю среднее с точностью 1 мм, но опять таки с выбросами до 5 мм.

Добавим фильтр. Предпочитаю IIR low pass bicubic с Q=1/sqrt(2), как меньше всего искажающий пропускаемую полосу, но дающий сильное подавление вне полосы. FIR вообще перестал использовать, он либо слаб, либо сильно сдвигает фазу, да и bicubic считается очень просто, без циклов.
Код: (C)
typedef struct {
    float xz[2];
    float yz[2];
} iir_filter_t;

typedef struct {
        float a[3];
        float b[2];
} iir_coef_t;

void iir_filter_init(iir_filter_t *f, float start_x) {
    f->xz[0] = f->xz[1] = f->yz[0] = f->yz[1] = start_x;
}

float iir_filter_step(iir_filter_t *f, const iir_coef_t* k, float x) {
    float y = x * k->a[0]
        + f->xz[0] * k->a[1]
        + f->xz[1] * k->a[2]
        - f->yz[0] * k->b[0]
        - f->yz[1] * k->b[1];
    f->xz[1] = f->xz[0];
    f->xz[0] = x;
    f->yz[1] = f->yz[0];
    f->yz[0] = y;
    return y;
}
Частота среза F=6/33. Выбросы сократились до ±3 мм. Не вариант. Зажимаем до F=1/33. Вроде гладко, но есть какая-то волна. Подложил под макетку, чтобы приподнять над столом, выставил по линейке 140 мм до коробки, изображающей из себя препятствие, не дышу. Несколько секунд строго 140 без волнений, потом 136-137 на секунду и снова 140. С расстоянием 1500 мм ведет себя точно также. Моя квартира не настолько велика, чтобы создавать резонансы на сотни метров. Видимо особенность схемы и фильтр тут не поможет.
Уменьшил цикл еще немного — до 25 мс. Работает стабильно.

Так, а что у него с распознанием препятствий, на что он реагирует, на что нет?
Лист картона — видит отлично.
Бумага писчая — аналогично.
Салфетка тканевая махровая. Невидима! Если положить ее в один слой на датчик, он продолжает работать, но процентов на 5 завышает показания. Два слоя — тоже работает, еще больше погрешность. 4 слоя — сигнал потерян. Руку, обернутую салфеткой видит.
Салфетка бумажная. Все тоже самое, только на двух слоях уже сбои начинаются.

Эксперименты с коробкой показали, что важен угол падения, потому как 1/cos. А еще под углом может прилететь далекое отражение, аж за 2.5 метра. То есть по цепочке: излучатель — коробка — стена — потолок — другая стена — коробка — приемник.
В итоге, я оценил этот датчик как показометр "ничего не вижу" и "что-то недалеко есть". Бесполезен полностью.

* board_back.jpg (135.77 Кб - загружено 545 раз.)
* board_front.jpg (82.66 Кб - загружено 537 раз.)
* maket.jpg (86.68 Кб - загружено 364 раз.)
* cubemx_chip.png (110.86 Кб - загружено 412 раз.)
* cubemx_tim2.png (124.06 Кб - загружено 432 раз.)
« Последнее редактирование: 09-01-2022 21:03 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines