A02YYUW防水超声波传感器

概述

超声波测距是通过发射超声波,并计算传感器收到回声的时间差,从而得出传感器到目标物体距离的一种方法。
A02YYUW是一款防水的超声波测距模块,有效测量距离4.5米,支持3.3~5V宽电压供电,可直接兼容3.3V或者5V控制设备,例如Arduino,树莓派等。A02YYUW平均工作电流仅8mA,绝大部分控制器IO端口便可以为A02YYUW模块提供工作电流。 它采用封闭式分体的超声波探头,具有一定的防尘防水能力,即使你的测量环境比较恶劣,它也能够胜任。其探测夹角约为100°,外形小巧,质量轻盈。预留2.54间距-4P接口,采用UART通信方式,能够适应更多系统架构的二次开发与应用。
A02YYUW防水超声波传感器各项参数都经过我们长时间严格的实验测定和优化,具有一流的测距响应速度、稳定性、灵敏度及低功耗。如果您的产品或设计对超声波传感器性能有着近乎苛刻的要求,那么A02YYUW绝对是您的最佳选择。

技术参数

波束指向特性示意图

  • 工作电压:3.3~5V
  • 待机电流:≤5mA
  • 平均电流:≤8mA
  • 盲区距离:3cm
  • 平面物体量程:3-450cm
  • 输出方式:UART串口
  • 响应时间:100ms
  • 探头中心频率:40K±1.0K
  • 工作温度:-15~60℃
  • 存储温度:-25~80℃
  • 探测角度:60°
  • 防水等级:IP67

功能特点

  • 盲区小
  • 抗干扰强
  • 数据输出稳定可靠
  • 功耗低
  • 响应时间快
  • 抗静电强
  • 工作温度宽
  • 测量精度高

安装尺寸

安装尺寸

接口定义

接口图

引脚说明

引脚编号 名称 功能描述
1 VCC 电源输入引线
2 GND 电源接地引线
3 RX 处理值和实时值输出选择引线
4 TX UART 输出引线

UART输出说明

UART通信说明

模组上电时会对 RX 引线进行检测,当 RX 引线悬空或者输入高电平时,模组按照处理值输出,数据更稳定,响应时间为500ms;当 RX 引线输入低电平时,模组按照实时值输出,响应时间为100ms。(模组对 RX 引线检测时间约为1秒,使用实时值输出时,建议先将 RX 引线连接低电平,再给模组供电)

切换方法:上电前把RX接到GND就能把500ms切换到100ms模式,上电后要一直保持

UART 数据位 停止位 奇偶校验 波特率
TTL电平 8 1 9600bps

UART输出格式

帧数据 说明 字节
帧头 固定为0xFF 1字节
DATA_H 距离数据高8位 1字节
DATA_L 距离数据低8位 1字节
SUM 通讯校验和 1字节

UART输出举例

帧头 DATA_H DATA_L SUM
0xFF 0x07 0xA1 0xA7

注:校验和只保留累加数值的低8位;

SUM =(帧头+ Data_H+ Data_L)&0x00FF
	=(0XFF + 0X07 + 0XA1)&0x00FF
	=0XA7;
	
距离值=Data_H\*256+ Data_L=0X07A1;

转换成十进制等于1953;
表示当前测量的距离值为1953毫米

Arduino平台应用

准备工作

  • Arduino UNO
  • UNO IO传感器扩展板
  • A02YYUW超声波传感器
  • 4P连接线一根

软件

Arduino连接图

Arduino与超声波传感器连接图

示例代码

#include <SoftwareSerial.h>

SoftwareSerial mySerial(11, 10);  // RX, TX

const uint8_t HEADER_BYTE = 0xFF;
const uint16_t READ_TIMEOUT_MS = 200;
const int ERROR_DISTANCE = -1;  // 错误返回值

void setup() {
  Serial.begin(115200);
  mySerial.begin(9600);
}

void loop() {
  Serial.print("distance=");
  Serial.print(getDistance());
  Serial.println("mm");
}

uint8_t readN(uint8_t *buf, size_t len) {
  size_t offset = 0, left = len;
  uint8_t *buffer = buf;
  long curr = millis();
  while (left) {
    if (mySerial.available()) {
      buffer[offset] = mySerial.read();
      offset++;
      left--;
    }
    if (millis() - curr > READ_TIMEOUT_MS) {
      break;
    }
  }
  return offset;
}

/**
 * 从传感器获取距离数据
 * @return 成功时返回距离值(非负),失败时返回-1
 */
int getDistance(void) {
  uint8_t data[4] = { 0 };
  uint8_t receivedByte = 0;
  unsigned long startTime = millis();

  while (millis() - startTime < READ_TIMEOUT_MS) {                      //检测是否超时
    if (readN(&receivedByte, 1) == 1 && receivedByte == HEADER_BYTE) {  //查找数据头字节
      data[0] = receivedByte;
      if (readN(&data[1], 3) == 3) {                     // 读取剩余3个字节
        uint8_t checksum = data[0] + data[1] + data[2];  // 校验数据和
        if (checksum == data[3]) {
          uint16_t distance = (data[1] << 8) | data[2];  // 计算并返回距离
          return distance;
        }
      }
    }
    Serial.println("Error data");
  }
  Serial.println("Error Reading data timeout");
  return ERROR_DISTANCE;
}

Raspberry Pi平台应用

准备工作

  • 树莓派4B
  • 树莓派 IO扩展板
  • A02YYUW超声波传感器
  • 4P连接线一根

Raspberry Pi连接图

Raspberry Pi与超声波传感器连接图

示例代码

下载超声波库文件

# -*- coding:utf-8 -*-

'''
  # demo_get_distance.py
  #
  # Connect board with raspberryPi.
  # Run this demo.
  #
  # Connect A02 to UART
  # get the distance value
  #
  # Copyright   [DFRobot](https://www.dfrobot.com), 2016
  # Copyright   GNU Lesser General Public License
  #
  # version  V1.0
  # date  2019-8-31
'''

import time

from DFRobot_RaspberryPi_A02YYUW import DFRobot_A02_Distance as Board

board = Board()


def print_distance(dis):
    if board.last_operate_status == board.STA_OK:
        print("Distance %d mm" % dis)
    elif board.last_operate_status == board.STA_ERR_CHECKSUM:
        print("ERROR")
    elif board.last_operate_status == board.STA_ERR_SERIAL:
        print("Serial open failed!")
    elif board.last_operate_status == board.STA_ERR_CHECK_OUT_LIMIT:
        print("Above the upper limit: %d" % dis)
    elif board.last_operate_status == board.STA_ERR_CHECK_LOW_LIMIT:
        print("Below the lower limit: %d" % dis)
    elif board.last_operate_status == board.STA_ERR_DATA:
        print("No data!")


if __name__ == "__main__":
    dis_min = 0  # Minimum ranging threshold: 0mm
    dis_max = 4500  # Highest ranging threshold: 4500mm
    board.set_dis_range(dis_min, dis_max)
    while True:
        distance = board.getDistance()
        print_distance(distance)
        time.sleep(0.3)  # Delay time < 0.6s

注:从树莓派3开始,树莓派有2个串口,默认被映射到板载蓝牙串口,需要通过设置将串口重新映射到GPIO的串口上

树莓派串口映射教程.pdf

ESP32平台应用

ESP32连接图

SEN0311接线图

示例代码

#include <HardwareSerial.h>

const uint8_t HEADER_BYTE = 0xFF;
const uint16_t READ_TIMEOUT_MS = 200;
const int ERROR_DISTANCE = -1;  // 错误返回值

HardwareSerial mySerial(1);

void setup() {
  Serial.begin(115200);
  mySerial.begin(9600, SERIAL_8N1, 0, 4);
}

void loop() {
  Serial.print("distance=");
  Serial.print(getDistance());
  Serial.println("mm");
}

uint8_t readN(uint8_t *buf, size_t len) {
  size_t offset = 0, left = len;
  uint8_t *buffer = buf;
  long curr = millis();
  while (left) {
    if (mySerial.available()) {
      buffer[offset] = mySerial.read();
      offset++;
      left--;
    }
    if (millis() - curr > READ_TIMEOUT_MS) {
      break;
    }
  }
  return offset;
}

/**
 * 从传感器获取距离数据
 * @return 成功时返回距离值(非负),失败时返回-1
 */
int getDistance(void) {
  uint8_t data[4] = { 0 };
  uint8_t receivedByte = 0;
  unsigned long startTime = millis();

  while (millis() - startTime < READ_TIMEOUT_MS) {                      //检测是否超时
    if (readN(&receivedByte, 1) == 1 && receivedByte == HEADER_BYTE) {  //查找数据头字节
      data[0] = receivedByte;
      if (readN(&data[1], 3) == 3) {                     // 读取剩余3个字节
        uint8_t checksum = data[0] + data[1] + data[2];  // 校验数据和
        if (checksum == data[3]) {
          uint16_t distance = (data[1] << 8) | data[2];  // 计算并返回距离
          return distance;
        }
      }
    }
    Serial.println("Error data");
  }
  Serial.println("Error Reading data timeout");
  return ERROR_DISTANCE;
}