一、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-ThreadUART受控输出方式 代码示例:

  1. 定时器每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;}
  1. 在串口接收中断函数中释放信号量
static rt_err_t uart_input(rt_device_t dev, rt_size_t size){rt_sem_release(&rx_sem);return RT_EOK;}
  1. 在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));}}