OpenHarmony设备开发(五)-超声波传感器

系统 OpenHarmony
本次学习了超声波模组,利用已学的知识给遥控小车加上一个简单的自动避障功能,有了超声波模组,以后可以开发更有意思的小实验,例如简单的无人操控小车、简单的量尺。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

前言

在之前学习了很多新的有趣知识,本次学习了超声波模组,利用已学的知识给遥控小车加上一个简单的自动避障功能。

有了超声波模组,以后可以开发更有意思的小实验,例如简单的无人操控小车、简单的量尺…

准备

创建文件夹和相关的代码文件。

#打卡不停更#【FFH】OpenHarmony设备开发(五)-超声波传感器-开源基础软件社区

其中WIFI_car保存网络连接遥控小车的代码,WIFI_hcsr04保存超声波模组相关的代码。

编辑BUILD.gn,加入相关头文件的引用路径(小tips:不知道路径的头文件可以用Ctrl+P搜索)。

static_library("WIFI_car_demo") {
sources = [
"WIFI_car.c",
"WIFI_hcsr04.c",
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/peripheral/interfaces/kits",
"//ohos_bundles/@ohos/device_soc_hisilicon/hi3861v100/sdk_liteos/include",
"//ohos_bundles/@ohos/device_soc_hisilicon/hi3861v100/sdk_liteos/third_party/lwip_sack/include",

]
}

编辑app路径下的BUILD.gn,使我们的遥控小车能被系统编译加载。

格式是:"文件夹名:静态库名"。

#打卡不停更#【FFH】OpenHarmony设备开发(五)-超声波传感器-开源基础软件社区

#打卡不停更#【FFH】OpenHarmony设备开发(五)-超声波传感器-开源基础软件社区

超声波模组

本次样例学习的是HC-SR04超声波模组。

超声波模组一共有4个引脚,分别为Vcc、 Trig(控制端)、 Echo(接收端)、 GND;其中VCC、GND接上5V电源。

HC-SR04超声波距离传感器的核心是两个超声波传感器。一个Trig(控制端)控制发出的超声波信号,将电信号转换为40 KHz超声波脉冲。Echo(接收端)监听发射的脉冲。

#打卡不停更#【FFH】OpenHarmony设备开发(五)-超声波传感器-开源基础软件社区

初始化

通过查询原理图,可以得知小车连接超声波的GPIO口为7和8。

其中GPIO7是Trig(输入口),GPIO8是Echo(输出口)。

首先我们要对这两个GPIO口进行初始化。

GPIO口初始化老三套:IO口初始化、IO口复用、IO口输入输出方向。

#define GPIO_Trig 7
#define GPIO_Echo 8
int hcsr_gpio_init(void)
{
IoTGpioInit(GPIO_Trig);
hi_io_set_func(GPIO_Trig, 0); //0是普通IO口的意思
IoTGpioSetDir(GPIO_Trig, IOT_GPIO_DIR_OUT);
IoTGpioInit(GPIO_Echo);
hi_io_set_func(GPIO_Echo, 0);
IoTGpioSetDir(GPIO_Echo, IOT_GPIO_DIR_IN);
}

编写检测距离函数

我们要检测距离,首先要懂得超声波传感器的原理。

超声波传感器通过Trig高电平发送声波,Echo接收超声波,通过计算发送和接收到的时间差,辅以声波的速度,得以计算出小车和障碍之间的距离。

程序设计流程:

  1. 发送trig高电平。
  2. 等待20us,trig设置为低电平。
  3. Echo接收到了高电平,计时高电平时间,高电平持续时间就是超声波从发射到返回的总时间。

其中为了减少干扰,可以先发送trig高电平50us,再将trig置为低电平,Echo接收到的数据从高电平降为低电平,便可开始。

为了准确性,还可以检测数次距离,再对其数据做平均值以及除错(当声波没有被反射回来,则回波信号将在38毫秒后超时并返回低电平。因此38 ms的脉冲表示在传感器范围内没有阻塞。)

本次样例只简单编写了一个检测函数:

float GetDistance(void)
{
IotGpioValue value = IOT_GPIO_VALUE0;
float distance = 0.0;
int flag = 0;
static unsigned long start_time = 0, time = 0;
//发送声波
IoTGpioSetOutputVal(GPIO_Trig, IOT_GPIO_VALUE1);
hi_udelay(20);
IoTGpioSetOutputVal(GPIO_Trig, IOT_GPIO_VALUE0);
while (1)
{//不断检测声波
IoTGpioGetInputVal(GPIO_Echo, &value);
//记录下高电平持续时间
if (value == IOT_GPIO_VALUE1 && flag == 0)
{
start_time = hi_get_us();
flag = 1;
}
if (value == IOT_GPIO_VALUE0 && flag == 1)
{
time = hi_get_us() - start_time;
start_time = 0;
break;
}
}
distance = time * 0.034 / 2;
printf("distance is %f\r\n", distance);
return distance;
}

避障线程

简单的避障功能需要以下几点需求:

  1. 避障线程的优先级需要高于遥控的优先级,这样当快要撞上障碍时能保证自动避障能正常运行。
  2. 需要设计一个信号量,信号量的作用是保证两个或多个关键代码不被并发调用,在这里是为了避免避障线程和遥控线程并发调用。本次样例使用一个sem_d变量代替了信号量,sem_d为1时使遥控功能睡眠。
  3. 不断判断距离是否小于特定值,当小于特定值做出相对应的避障。
void hcsr04_avoid(void)
{
float distance = 0;
//io口初始化
hcsr_gpio_init();
while (1)
{
//获取距离信息
distance=GetDistance();
if (distance < 20)
{
printf("Distance <20!!!");
sem_d = 1;
car_stop();
car_backward();
sleep(1);
car_stop();
sem_d = 0;
}
}
}
void hcsr04_demo(void)
{
osThreadAttr_t attr;
attr.name = "hcsr04_Task";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 4096;
attr.priority = 24;
if (osThreadNew((osThreadFunc_t)hcsr04_avoid, NULL, &attr) == NULL)
{
printf("[hcsr04_Task] Falied to create hcsr04_Task!\n");
}
}

网络连接遥控小车

源代码文件

为了加入超声波传感器线程,我们可以在小车IO口之后启动超声波线程(也可直接用SYS_RUN()启动线程,此处因为遥控之前用不到避障,因而延迟启动线程):

extern void hcsr04_demo(void);
hcsr04_demo();

信号量的使用:

首先创建全局变量,记得要在头文件中extern该变量,WIFI_hcsr04.c才能使用到该变量。

当sem_d为1时,休眠遥控代码,直至sem_d为0。

int sem_d=0;
while(1)
{
if(sem_d==1)
{
continue;
}
//遥控小车代码...
}

#打卡不停更#【FFH】OpenHarmony设备开发(五)-超声波传感器-开源基础软件社区

头代码文件

此处代码为了WIFI_hcsr04.c能调用到一些需要用到的函数和变量。

#ifndef __WIFI_CAR__
#define __WIFI_CAR__
void car_stop(void);
void car_backwward(void);
extern int sem_d;

#endif

其它

效果

#打卡不停更#【FFH】OpenHarmony设备开发(五)-超声波传感器-开源基础软件社区

问题

测试了几轮下来,发现了有以下问题。

  1. 在测试中偶尔会遇到栈溢出的情况,原因尚未找到。

#打卡不停更#【FFH】OpenHarmony设备开发(五)-超声波传感器-开源基础软件社区

  1. 超声波传感器的精确度不高,容易会误判障碍物(虚无的障碍emm)。

当前解决方案:

  1. 加大线程的栈大小(无法从根本解决)。
  2. 找到栈溢出原因,设计超时机制,避免内存不断堆积。
  3. 设计检测距离的算法,对获取的数据进行取平均值以及除去最大最小。
float distance_sum[5];
float distance = 0;
//获取数据
for (int i = 0; i < 5; i++)
{
distance_sum[i] = GetDistance();
}
int max_id = 0;
int min_id = 0;
//记录最大最小的数组下标
for (int i = 1; i < 5; i++)
{
if (distance_sum[i] > distance_sum[max_id])
{
max_id = i;
}
if (distance_sum[i] < distance_sum[min_id])
{
min_id = i;
}
}
for (int i = 0; i < 5; i++)
{
if (i != max_id && i != min_id)
{
distance += distance_sum[i];
}
}
distance /= 3.0;

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。

责任编辑:jianghua 来源: 51CTO开源基础软件社区
相关推荐

2016-01-29 11:20:26

蝙蝠超声波传感器

2024-02-23 09:42:09

自动驾驶感知

2022-04-19 11:09:13

Wi-Fi IoT智能小车鸿蒙

2022-09-30 13:50:07

设备开发鸿蒙

2011-09-27 20:03:55

手机支付摩宝蝙蝠

2013-08-21 15:15:39

E524.14LIN智能超声波

2023-01-03 15:14:43

2021-04-25 10:06:57

鸿蒙HarmonyOS应用

2017-03-01 15:18:16

2023-03-20 16:05:49

HDF传感器驱动开发

2020-04-28 09:56:45

iPhone5G苹果

2021-03-29 15:36:46

人工智能机器学习技术

2017-08-01 15:20:38

2023-07-11 18:30:05

智能设备半导体

2022-05-24 15:55:37

避障小车华为

2021-10-19 09:46:04

苹果ARVR

2017-05-08 09:25:03

APP黑客uXDT技术

2009-05-17 10:17:39

Windows Mob微软移动OS

2023-12-22 10:53:08

2017-05-06 23:52:15

点赞
收藏

51CTO技术栈公众号