这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 有奖活动 » 在WT9932C61-TINY上实现超声波测距

共1条 1/1 1 跳转至

在WT9932C61-TINY上实现超声波测距

菜鸟
2026-06-16 17:17:43     打赏

HC-SR04超声波测距模块是一种常见的功能模块,它可提供2cm-400cm的非接触式距离检测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路见图1所示

image.png

1 超声波测距模块 

模块特点如下:

1典型工作用电压:5V

2超小静态工作电流:小于5mA

3精度可达0.3cm

4盲区接近2cm 

模块共有4个引脚,即:VCC5V)、 Trig(控制端)、 Echo(接收端)、地(GND 

超声波测距是通过不断检测超声波发射后遇到障碍物所反射的回波, 从而测出发射和接收回波的时间差Δt , 然后求出距离S 。在速度v 已知的情况下,距离S 的计算,公式如下:S = vΔt/ 2在空气中,常温下超声波的传播速度是334 /,但其传播速度V 易受空气中温度、湿度、压强等因素的影响,其中受温度的影响较大,如温度每升高1 , 声速增加约0. 6 / 秒。因此在测距精度要求很高的情况下, 应通过温度补偿的方法对传播速度加以校正。已知现场环境温度T , 超声波传播速度V 的计算公式如下:

V = 331. 5+0.607T

这样, 只要测得超声波发射和接收回波的时间差Δt 以及现场环境温度T,就可以精确计算出发射点到障碍物之间的距离。

image.png

2 信号时序关系

在使用WT9932C61-TINY的情况下,其引脚连接关系为:

TRIG---IO2

ECHO---IO1 

具体的程序内容为:

#define HC_SR04_TRIG_GPIO   2
#define HC_SR04_ECHO_GPIO  1
 
#define EXAMPLE_GPTIMER_RESOLUTION_HZ  1000000  // 1MHz, 1 tick = 1us
 
typedef struct {
    gptimer_handle_t gptimer;
    TaskHandle_t task_to_notify;
    gpio_num_t echo_gpio;
} gpio_callback_user_data_t;
 
static void hc_sr04_echo_callback(void *user_data)
{
    static uint64_t cap_val_end_of_sample = 0;
    static uint64_t cap_val_begin_of_sample = 0;
    gpio_callback_user_data_t *callback_user_data = (gpio_callback_user_data_t *)user_data;
    gpio_num_t echo_gpio = callback_user_data->echo_gpio;
    TaskHandle_t task_to_notify = callback_user_data->task_to_notify;
    gptimer_handle_t gptimer = callback_user_data->gptimer;
    if (gpio_get_level(echo_gpio) == 1) {
        gptimer_get_captured_count(gptimer, &cap_val_begin_of_sample);
        cap_val_end_of_sample = cap_val_begin_of_sample;
    } else {
        gptimer_get_captured_count(gptimer, &cap_val_end_of_sample);
        uint32_t tof_ticks = (uint32_t)(cap_val_end_of_sample - cap_val_begin_of_sample);
        xTaskNotifyFromISR(task_to_notify, tof_ticks, eSetValueWithOverwrite, NULL);
    }
}
 
static void gen_trig_output(void)
{
    gpio_set_level(HC_SR04_TRIG_GPIO, 1); 
    esp_rom_delay_us(10);
    gpio_set_level(HC_SR04_TRIG_GPIO, 0); 
}
 
void app_main(void)
{
    ESP_LOGI(TAG, "Configure trig gpio");
    gpio_config_t trig_io_conf = {
        .mode = GPIO_MODE_OUTPUT,
        .pin_bit_mask = 1ULL << HC_SR04_TRIG_GPIO,
    };
    ESP_ERROR_CHECK(gpio_config(&trig_io_conf));
    ESP_ERROR_CHECK(gpio_set_level(HC_SR04_TRIG_GPIO, 0));
 
    ESP_LOGI(TAG, "Configure echo gpio");
    gpio_config_t echo_io_conf = {
        .mode = GPIO_MODE_INPUT,
        .intr_type = GPIO_INTR_ANYEDGE, 
        .pull_up_en = GPIO_PULLUP_ENABLE, 
        .pin_bit_mask = 1ULL << HC_SR04_ECHO_GPIO,
    };
    ESP_ERROR_CHECK(gpio_config(&echo_io_conf));
    ESP_LOGI(TAG, "Create etm event handle for echo gpio");
    esp_etm_event_handle_t gpio_event = NULL;
    gpio_etm_event_config_t gpio_event_config = {
        .edge = GPIO_ETM_EVENT_EDGE_ANY, 
    };
    ESP_ERROR_CHECK(gpio_new_etm_event(&gpio_event_config, &gpio_event));
    ESP_ERROR_CHECK(gpio_etm_event_bind_gpio(gpio_event, HC_SR04_ECHO_GPIO));
 
    ESP_LOGI(TAG, "Create gptimer handle");
    gptimer_handle_t gptimer = NULL;
    gptimer_config_t timer_config = {
        .clk_src = GPTIMER_CLK_SRC_DEFAULT,
        .direction = GPTIMER_COUNT_UP,
        .resolution_hz = EXAMPLE_GPTIMER_RESOLUTION_HZ,
    };
    ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
 
    ESP_LOGI(TAG, "Get gptimer etm task handle (capture)");
    esp_etm_task_handle_t gptimer_capture_task = NULL;
    gptimer_etm_task_config_t gptimer_etm_task_conf = {
        .task_type = GPTIMER_ETM_TASK_CAPTURE,
    };
    ESP_ERROR_CHECK(gptimer_new_etm_task(gptimer, &gptimer_etm_task_conf, &gptimer_capture_task));
 
    ESP_LOGI(TAG, "Create ETM channel then connect gpio event and gptimer task");
    esp_etm_channel_handle_t etm_chan = NULL;
    esp_etm_channel_config_t etm_chan_config = {};
    ESP_ERROR_CHECK(esp_etm_new_channel(&etm_chan_config, &etm_chan));
      ESP_ERROR_CHECK(esp_etm_channel_connect(etm_chan, gpio_event, gptimer_capture_task));
    ESP_LOGI(TAG, "Install GPIO edge interrupt");
    ESP_ERROR_CHECK(gpio_install_isr_service(0));
    gpio_callback_user_data_t callback_user_data = {
        .gptimer = gptimer,
        .echo_gpio = HC_SR04_ECHO_GPIO,
        .task_to_notify = xTaskGetCurrentTaskHandle(),
    };
    ESP_ERROR_CHECK(gpio_isr_handler_add(HC_SR04_ECHO_GPIO, hc_sr04_echo_callback, &callback_user_data));
 
    ESP_LOGI(TAG, "Enable etm channel and gptimer");
    ESP_ERROR_CHECK(esp_etm_channel_enable(etm_chan));
    ESP_ERROR_CHECK(gptimer_enable(gptimer));
    ESP_ERROR_CHECK(esp_etm_dump(stdout));
    ESP_LOGI(TAG, "Start gptimer");
    ESP_ERROR_CHECK(gptimer_start(gptimer));
    uint32_t tof_ticks;
    while (1) {
        gen_trig_output();
        if (xTaskNotifyWait(0x00, ULONG_MAX, &tof_ticks, pdMS_TO_TICKS(1000)) == pdTRUE) {
            if (tof_ticks > 35000) {
                continue;
            }
            float distance = (float) tof_ticks / 58.0f;
            ESP_LOGI(TAG, "Measured distance: %.2fcm", distance);
        }
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

经程序编译和下载,其结果如图3和图4所示。

image.png

3 编译结果

image.png

4 完成下载 

在探头朝向屋顶时,其检测结果如图5所示。

image.png

5 屋顶距离

在进行物距检测时,见图6和图7所示,检测结果与实际距离基本一致。

image.png

6 物距检测

image.png

7 检测结果



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]