一、A22超声波传感器
该模块是基于机器人自动控制应用而设计的超声波避障传感器,针对目前市场上对于超声波传感器模组盲区大、测量角度大、响应时间长、安装适配性差等问题而着重设计。
具备了盲区小、测量角度小、响应时间短、过滤同频干扰、体积小、安装适配性高、防尘防水、寿命长、可靠性高等一系列优点。
参数
- 宽电压供电,工作电压 3.3~12V;
- 1cm 标准盲区(产品盲区最小可达 0.8cm);
- 最远量程可设置,可通过指令设置 50cm、150cm、250cm、350cm 共 4 级量程等级;
- 多种输出方式可选,UART 自动/受控、PWM 受控、开关量 TTL 电平、RS485、IIC 等,输出方式不一样但功能完全一致;
- 默认波特率为 115200,可支持修改为 4800、9600、14400、19200、38400、57600、76800;
- ms 级响应时间,数据输出时间最快可达 13ms;
- 角度可设置区域范围 30°、40°、50°、60°共 4 级角度等级,以适用不同应用场景;
- 内置降噪功能,可支持 5 级降噪等级设置,适用电池供电、短/长距离 USB 供电、开关电源供电以及较大噪声电源供电;
引脚
四根线,分别是VCC、GND、TX、RX。
输出方式
支持多种输出方式:
-
1. UART自动输出
当触发输入引线“RX”悬空或者输入高电平时,模组按照处理值输出,数据更稳定,响应时间为 100~140ms;当输入低电平时模组按照实时值输出,响应时间为 100~130ms(注意:“RX”电平检测仅在上电 500ms 内检测有效,之后将不做电平检测)。 -
2. UART受控输出
当触发输入引线“RX” 接收到一个有下降沿的触发脉冲或任意一个串口数据,下降沿会触发模组工作一次,输出引线“TX”将输出一次测量数据,模组的触发周期必须大于150ms。当超过5秒未收到“RX”脚的触发脉冲,模组将进入休眠状态,功耗最低。当休眠时收到“RX”触发脉冲,将立即唤醒工作,但响应时间会比未休眠时增加12ms。 -
3. PWM输出
当触发输入引线“RX” 接收到一个有下降沿的触发脉冲,下降沿会触发模组工作一次,输出引线“TX”将输出一次TTL电平的PWM高电平脉宽信号,模组的触发周期必须大于50ms, 如果模组没有检测到物体,输出引线“TX”将输出约21ms的固定脉宽(量程等级4)。当超过5秒未收到“RX”脚的触发脉冲,模组将进入休眠状态,功耗最低。当休眠时收到“RX”触发脉冲,将立即唤醒工作,但响应时间会比未休眠时增加12ms。 -
。。。。。。
输出格式
UART
输出为4个字节数据,分为是帧头+数据高八位+数据第八位+通讯校验和
距离值= Data_H*256+ Data_L=0X07A1; 转换成十进制等于1953;
当modbus寄存器0x0209的参数值为0x00时,单位为mm,表示当前测量的距离值为1953mm;
当modbus寄存器0x0209的参数值为0x01时,单位为us,表示当前测量的距离回波时间值为1953us,此值除以5.75得mm单位的距离值=1953/5.75≈340mm。
PWM
公式:S=T*V/2(S为距离值,T为PWM高电平脉宽时间,V为声音在空气中的传播速度)。
在常温下得声速V为348M/S,可简化公式得S= T/57.5 (此时距离S单位为厘米,时间T单位为微秒)。
举例:当输出引线“TX”的PWM高电平脉宽时间T3为10000us时,
得S= T/57.5=10000/57.5≈173.9(cm),表示当前测量的距离值为173.9cm。
软件设计
以下为RT-Thread 下UART受控输出方式 代码示例:
- 定时器每200ms向传感器发送一次触发信号
rt_device_set_rx_indicate(hw_dev, timeout_cb);
/* 设置计数频率(若未设置该项,默认为1Mhz 或 支持的最小计数频率) */
rt_device_control(hw_dev, HWTIMER_CTRL_FREQ_SET, &freq);
/* 设置模式为周期性定时器(若未设置,默认是HWTIMER_MODE_ONESHOT)*/
mode = HWTIMER_MODE_PERIOD;
ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);
if (ret != RT_EOK)
{
rt_kprintf("set mode failed! ret is :%d\n", ret);
}
/* 设置定时器超时值为1s并启动定时器 */
timeout_s.sec = 0; /* 秒 */
timeout_s.usec = 200000; /* 微秒 */
if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s))
{
rt_kprintf("set timeout value failed\n");
}
static rt_err_t timeout_cb(rt_device_t dev, rt_size_t size)
{
rt_device_write(serial, 0, "1", 1); //触发信号
return 0;
}
- 在串口接收中断函数中释放信号量
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
rt_sem_release(&rx_sem);
return RT_EOK;
}
- 在main线程中接收数据,并判断帧数据
if(rt_device_read(serial, 0, &ch[t], 1) != 0)
{
/* 阻塞等待接收信号量,等到信号量后再次读取数据 */
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
t++;
if(t==4)
{
t=0;
if(ch[0]==0xFF )
{
int a=(int)ch[1];
int b=(int)ch[2];
long int c=a*256+b;
int d=c%10;
c/=10;
rt_kprintf("%d.%d\n",c,d);
}
memset(ch, 0, sizeof(ch));
}
}