概述
URM15是一款具有IP65级防水型单探头超声波测距传感器,采用标准ModbusRTU协议的RS485通信接口,具有高度的通信可靠性。测距平整墙面有效距离为30cm-500cm。并且传感器的从机地址及串口参数都可以根据实际情况作修改,因此可以方便快速的连接到各种工控主机,非常方便上手使用。该传感器具有灵活的温度补偿功能,用户可以根据实际需求选择外部温度补偿或板载温度补偿功能来避免环境温度对测量结果造成的较大影响。该传感器使用的是频率为75Khz的超声波换能器,该换能器直径约为40mm。因此这款传感器的主要特点是在具有较高灵敏度的同时,探测角度也比较小。
技术参数
- 工作电压:5~12V DC
- 最大瞬时电流:350mA
- 有效量程:30cm ~ 500cm
- 距离分辨率:10mm
- 距离误差:±1%
- 温度分辨率:0.1℃
- 温度误差:±1℃
- 测量频率:10HZ
- 工作温度:-10℃~+70℃
- 工作湿度范围:RH<75%
- 传感器声学频率:75KHz±2%
- 传感器方向角:20±2°(-6dB)
- 通信接口:RS485(Modbus-RTU)
接口说明
 
模块接口线序如下:
1、橙 ------ VCC
2、黑 ------ GND
3、蓝 ------ RS485-B
4、白 ------ RS485-A
寄存器说明
| 地址 | 数量 | 名称 | 读写 | 数据范围 | 默认值 | 数据说明 | 
|---|---|---|---|---|---|---|
| 0x00 | 1 | 模块PID寄存器 | R | 0x0000-0xFFFF | 0x0005 | 该位用于产品校验[可实现模块类型的检测] | 
| 0x01 | 1 | 模块VID寄存器 | R | 0x0000-0xFFFF | 0x0010 | 该位用于版本校验[0x0010表示V0.0.1.0] | 
| 0x02 | 1 | 模块地址寄存器 | R/W | 0x0001-0x00F7 | 0x000F | [传感器地址未知时,可通过广播地址0x00做写入寄存器操作,此时传感器不会有数据输出] 断电保存,重启后生效 | 
| 0x03 | 1 | 串口参数控制寄存器1 | R/W | 0x0000-0xFFFF | 0x0005 | 模块波特率 0x0001---2400 0x0003---9600 0x0004---14400 0x0005---19200 0x0006---38400 0x0007---57600 0x0008---115200 Other----115200 断电保存,重启后生效 | 
| 0x04 | 1 | 串口参数控制寄存器2 | R/W | 0x0000-0xFFFF | 0x0001 | 保留(串口数据格式固定为:无奇偶校验位,1位停止位,8位数据位) 断电保存,重启后生效 | 
| 0x05 | 1 | 距离寄存器 | R | 0x0000-0xFFFF | 0xFFFF | 模块测得的距离值LSB代表0.1cm | 
| 0x06 | 1 | 板载温度数据寄存器 | R | 0x0000-0xFFFF | 0x0000 | 板载温度传感器测得的温度数据LSB代表0.1摄氏度(有符号数) | 
| 0x07 | 1 | 外部温度补偿数据寄存器 | R/W | 0x0000-0xFFFF | 0x0000 | 外部温度寄存器,数据由用户写入,当使能外部温度补偿时,传感器测距时使用该寄存器的温度值作温度补偿,LSB代表0.1摄氏度(有符号数)。 | 
| 0x08 | 1 | 控制寄存器 | R/W | 0x0000-0xFFFF | 0x0004 | bit0 0-使用板载温度补偿功能 1-使用外部温度补偿功能(需用户写入温度数据至外部温度补偿数据寄存器) bit1 1-开启温度补偿功能 0-关闭温度补偿功能 bit2 0-自动测距 1-被动测距 bit3 被动模式下,向该位写入1,传感器将完成一次测距(约65ms),测距完成后可从距离寄存器读出距离值,自动测距模式下该位保留。该位置1后将自动清0 断电保存,立即生效 | 
寄存器读写示例
准备
- 硬件
- 1 x Arduino Leonardo控制板
- 1 x Arduino TTL转485扩展板
- 1 x USB数据线(USB数据线一端连接Arduino板USB口,另一端连接至电脑USB口)
 
- 
软件 - Arduino IDE, 点击下载Arduino IDE
- 在IDE中打开Library Manager(Ctrl+Shift+I),搜索并安装DFRobot_RTU库
 
- 
与LEONARDO连接示意图 
  
- 
与UNO连接示意图 
  
- 
与MEGA连接示意图 
  
读取测量距离示例
/**************************************************************************************************************
 * @This code tests the range finder function of the URM15 ultrasonic sensor
 * @brief 修改modbus从机的设备ID。每个modbus从机都有唯一识别的设备ID号,范围0x0000~0x00F7(0~247),修改设备ID有2种方式:
 * @n 1: 不知道设备的ID地址,可以通过广播地址0x00修改从机的ID地址,此命令会将总线上所有的从机的地址都修改为设置的ID(用0x00修改地址时,总线上最好只接一个设备)
 * @n 2: 知道设备的ID地址,直接用ID修改
 * @n note:运行此demo必须知道设备的串口配置(波特率,数据位,校验位,停止位)
 * @n connected table
 * ---------------------------------------------------------------------------------------------------------------
 * sensor pin |             MCU                | Leonardo/Mega2560/M0 |    UNO    | ESP8266 | ESP32 |  microbit  |
 *     VCC    |            3.3V/5V             |        VCC           |    VCC    |   VCC   |  VCC  |     X      |
 *     GND    |              GND               |        GND           |    GND    |   GND   |  GND  |     X      |
 *     RX     |              TX                |     Serial1 RX1      |     5     |5/D6(TX) |  D2   |     X      |
 *     TX     |              RX                |     Serial1 TX1      |     4     |4/D7(RX) |  D3   |     X      |
 * ---------------------------------------------------------------------------------------------------------------
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @ author : roker.wang@dfrobot.com
 * @ data   : 26.10.2021
 * @ version: 1.0
**************************************************************************************************************/
#include "DFRobot_RTU.h"
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
#include <SoftwareSerial.h>
#endif
#define   SLAVE_ADDR                ((uint16_t)0x0F)
#define   TEMP_CPT_SEL_BIT          ((uint16_t)0x01)
#define   TEMP_CPT_ENABLE_BIT       ((uint16_t)0x01 << 1)
#define   MEASURE_MODE_BIT          ((uint16_t)0x01 << 2)
#define   MEASURE_TRIG_BIT          ((uint16_t)0x01 << 3)
typedef enum{ 
  ePid,
  eVid,
  eAddr,
  eComBaudrate,
  eComParityStop,
  eDistance,
  eInternalTempreture,
  eExternTempreture,
  eControl
}eRegIndex_t;//Sensor register index
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
  SoftwareSerial mySerial(/*rx =*/4, /*tx =*/5);
  DFRobot_RTU modbus(/*s =*/&mySerial);
#else
  DFRobot_RTU modbus(/*s =*/&Serial1);
#endif
volatile uint16_t cr = 0;
void setup() {
  Serial.begin(9600);
  while(!Serial){                                                     //Waiting for USB Serial COM port to open.
  }
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
    mySerial.begin(19200);
#elif defined(ESP32)
  Serial1.begin(19200, SERIAL_8N1, /*rx =*/D3, /*tx =*/D2);
#else
  Serial1.begin(19200);
#endif
  delay(1000);
  cr |= MEASURE_MODE_BIT;//Set bit2 , Set to trigger mode
  cr &= ~(uint16_t)TEMP_CPT_SEL_BIT;//Select internal temperature compensation
  cr |= (uint16_t)TEMP_CPT_ENABLE_BIT;//enable temperature compensation
  modbus.writeHoldingRegister(/*id =*/SLAVE_ADDR, /*reg =*/ eControl, /*val =*/cr);
  delay(1000);
}
float  dist;
void loop() {
  cr |= MEASURE_TRIG_BIT;//Set trig bit
  modbus.writeHoldingRegister(/*id =*/SLAVE_ADDR, /*reg =*/ eControl, /*val =*/cr);
  delay(300);
  dist = modbus.readHoldingRegister(SLAVE_ADDR, eDistance);
  if(dist == 65535){
    Serial.println("out of range!");
  }else{
    Serial.print("distance = ");
    Serial.print(dist / 10, 1);
    Serial.println("cm");
  }
}
 
读取板载温度示例
/**************************************************************************************************************
 * @This code tests the temperature measurement function of the URM14 ultrasonic sensor
 * @brief 修改modbus从机的设备ID。每个modbus从机都有唯一识别的设备ID号,范围0x0000~0x00F7(0~247),修改设备ID有2种方式:
 * @n 1: 不知道设备的ID地址,可以通过广播地址0x00修改从机的ID地址,此命令会将总线上所有的从机的地址都修改为设置的ID(用0x00修改地址时,总线上最好只接一个设备)
 * @n 2: 知道设备的ID地址,直接用ID修改
 * @n note:运行此demo必须知道设备的串口配置(波特率,数据位,校验位,停止位)
 * @n connected table
 * ---------------------------------------------------------------------------------------------------------------
 * sensor pin |             MCU                | Leonardo/Mega2560/M0 |    UNO    | ESP8266 | ESP32 |  microbit  |
 *     VCC    |            3.3V/5V             |        VCC           |    VCC    |   VCC   |  VCC  |     X      |
 *     GND    |              GND               |        GND           |    GND    |   GND   |  GND  |     X      |
 *     RX     |              TX                |     Serial1 RX1      |     5     |5/D6(TX) |  D2   |     X      |
 *     TX     |              RX                |     Serial1 TX1      |     4     |4/D7(RX) |  D3   |     X      |
 * ---------------------------------------------------------------------------------------------------------------
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @ author : roker.wang@dfrobot.com
 * @ data   : 26.10.2021
 * @ version: 1.0
**************************************************************************************************************/
#include "DFRobot_RTU.h"
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
#include <SoftwareSerial.h>
#endif
#define   SLAVE_ADDR                ((uint16_t)0x0F)
#define   TEMP_CPT_SEL_BIT          ((uint16_t)0x01)
#define   TEMP_CPT_ENABLE_BIT       ((uint16_t)0x01 << 1)
#define   MEASURE_MODE_BIT          ((uint16_t)0x01 << 2)
#define   MEASURE_TRIG_BIT          ((uint16_t)0x01 << 3)
typedef enum{ 
  ePid,
  eVid,
  eAddr,
  eComBaudrate,
  eComParityStop,
  eDistance,
  eInternalTempreture,
  eExternTempreture,
  eControl
}eRegIndex_t;//Sensor register index
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
  SoftwareSerial mySerial(/*rx =*/4, /*tx =*/5);
  DFRobot_RTU modbus(/*s =*/&mySerial);
#else
  DFRobot_RTU modbus(/*s =*/&Serial1);
#endif
volatile uint16_t cr = 0;
void setup() {
  Serial.begin(9600);
  while(!Serial){ //Waiting for USB Serial COM port to open.
  }
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
    mySerial.begin(19200);
#elif defined(ESP32)
  Serial1.begin(19200, SERIAL_8N1, /*rx =*/D3, /*tx =*/D2);
#else
  Serial1.begin(19200);
#endif
  delay(1000);   
}
float  temp;
void loop() {
  temp = modbus.readHoldingRegister(SLAVE_ADDR, eInternalTempreture);
  Serial.print(temp / 10,1);
  Serial.println("C");
  delay(500);
}
 
修改模块地址
/**************************************************************************************************************
 * @This code tests the address modification function of the URM14 ultrasonic sensor
 * @brief 修改modbus从机的设备ID。每个modbus从机都有唯一识别的设备ID号,范围0x0000~0x00F7(0~247),修改设备ID有2种方式:
 * @n 1: 不知道设备的ID地址,可以通过广播地址0x00修改从机的ID地址,此命令会将总线上所有的从机的地址都修改为设置的ID(用0x00修改地址时,总线上最好只接一个设备)
 * @n 2: 知道设备的ID地址,直接用ID修改
 * @n note:运行此demo必须知道设备的串口配置(波特率,数据位,校验位,停止位)
 * @n connected table
 * ---------------------------------------------------------------------------------------------------------------
 * sensor pin |             MCU                | Leonardo/Mega2560/M0 |    UNO    | ESP8266 | ESP32 |  microbit  |
 *     VCC    |            3.3V/5V             |        VCC           |    VCC    |   VCC   |  VCC  |     X      |
 *     GND    |              GND               |        GND           |    GND    |   GND   |  GND  |     X      |
 *     RX     |              TX                |     Serial1 RX1      |     5     |5/D6(TX) |  D2   |     X      |
 *     TX     |              RX                |     Serial1 TX1      |     4     |4/D7(RX) |  D3   |     X      |
 * ---------------------------------------------------------------------------------------------------------------
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @ author : roker.wang@dfrobot.com
 * @ data   : 26.10.2021
 * @ version: 1.0
**************************************************************************************************************/
#include "DFRobot_RTU.h"
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
#include <SoftwareSerial.h>
#endif
#define   SLAVE_ADDR                ((uint16_t)0x0F)
#define   TEMP_CPT_SEL_BIT          ((uint16_t)0x01)
#define   TEMP_CPT_ENABLE_BIT       ((uint16_t)0x01 << 1)
#define   MEASURE_MODE_BIT          ((uint16_t)0x01 << 2)
#define   MEASURE_TRIG_BIT          ((uint16_t)0x01 << 3)
typedef enum{ 
  ePid,
  eVid,
  eAddr,
  eComBaudrate,
  eComParityStop,
  eDistance,
  eInternalTempreture,
  eExternTempreture,
  eControl
}eRegIndex_t;//Sensor register index
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
  SoftwareSerial mySerial(/*rx =*/4, /*tx =*/5);
  DFRobot_RTU modbus(/*s =*/&mySerial);
#else
  DFRobot_RTU modbus(/*s =*/&Serial1);
#endif
volatile uint16_t cr = 0;
void setup() {
  Serial.begin(9600);
  while(!Serial){                                                     //Waiting for USB Serial COM port to open.
  }
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
    mySerial.begin(19200);
#elif defined(ESP32)
  Serial1.begin(19200, SERIAL_8N1, /*rx =*/D3, /*tx =*/D2);
#else
  Serial1.begin(19200);
#endif
  delay(1000);   
}
volatile uint16_t newAddr, res;
void loop() {
  newAddr = 0x11;
  modbus.writeHoldingRegister(/*id =*/SLAVE_ADDR, /*reg =*/ eAddr, /*val =*/newAddr);
  delay(50);
  res = modbus.readHoldingRegister(SLAVE_ADDR, eAddr);
  if(res ==  newAddr){
    Serial.print("The device address has been modified as ");
    Serial.print(newAddr);
    Serial.println(".please reset the device!");
    
   }else{
    Serial.print("Failed to change the sensor address!");
   }
  while(1);
}
 
修改模块波特率
/**************************************************************************************************************
 * @This code tests the baudrate modification function of the URM14 ultrasonic sensor
 * @brief 修改modbus从机的设备ID。每个modbus从机都有唯一识别的设备ID号,范围0x0000~0x00F7(0~247),修改设备ID有2种方式:
 * @n 1: 不知道设备的ID地址,可以通过广播地址0x00修改从机的ID地址,此命令会将总线上所有的从机的地址都修改为设置的ID(用0x00修改地址时,总线上最好只接一个设备)
 * @n 2: 知道设备的ID地址,直接用ID修改
 * @n note:运行此demo必须知道设备的串口配置(波特率,数据位,校验位,停止位)
 * @n connected table
 * ---------------------------------------------------------------------------------------------------------------
 * sensor pin |             MCU                | Leonardo/Mega2560/M0 |    UNO    | ESP8266 | ESP32 |  microbit  |
 *     VCC    |            3.3V/5V             |        VCC           |    VCC    |   VCC   |  VCC  |     X      |
 *     GND    |              GND               |        GND           |    GND    |   GND   |  GND  |     X      |
 *     RX     |              TX                |     Serial1 RX1      |     5     |5/D6(TX) |  D2   |     X      |
 *     TX     |              RX                |     Serial1 TX1      |     4     |4/D7(RX) |  D3   |     X      |
 * ---------------------------------------------------------------------------------------------------------------
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @ author : roker.wang@dfrobot.com
 * @ data   : 26.10.2021
 * @ version: 1.0
**************************************************************************************************************/
#include "DFRobot_RTU.h"
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
#include <SoftwareSerial.h>
#endif
#define   SLAVE_ADDR                ((uint16_t)0x0F)
#define   TEMP_CPT_SEL_BIT          ((uint16_t)0x01)
#define   TEMP_CPT_ENABLE_BIT       ((uint16_t)0x01 << 1)
#define   MEASURE_MODE_BIT          ((uint16_t)0x01 << 2)
#define   MEASURE_TRIG_BIT          ((uint16_t)0x01 << 3)
typedef enum{ 
  ePid,
  eVid,
  eAddr,
  eComBaudrate,
  eComParityStop,
  eDistance,
  eInternalTempreture,
  eExternTempreture,
  eControl
}eRegIndex_t;//Sensor register index
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
  SoftwareSerial mySerial(/*rx =*/4, /*tx =*/5);
  DFRobot_RTU modbus(/*s =*/&mySerial);
#else
  DFRobot_RTU modbus(/*s =*/&Serial1);
#endif
volatile uint16_t cr = 0;
void setup() {
  Serial.begin(9600);
  while(!Serial){                                                     //Waiting for USB Serial COM port to open.
  }
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
    mySerial.begin(19200);
#elif defined(ESP32)
  Serial1.begin(19200, SERIAL_8N1, /*rx =*/D3, /*tx =*/D2);
#else
  Serial1.begin(19200);
#endif
  delay(1000);
  cr |= MEASURE_MODE_BIT;//Set bit2 , Set to trigger mode
  cr &= ~(uint16_t)TEMP_CPT_SEL_BIT;//Select internal temperature compensation
  cr |= (uint16_t)TEMP_CPT_ENABLE_BIT;//enable temperature compensation
  modbus.writeHoldingRegister(/*id =*/SLAVE_ADDR, /*reg =*/ eControl, /*val =*/cr);
  delay(1000);
}
volatile uint16_t baudrateIndex, res;
void loop() {
  uint16_t res;
  baudrateIndex = 3;       //0x0001---2400   0x0002---4800 0x0003---9600   0x0004---14400
                           //0x0005---19200  0x0006---38400 0x0007---57600 0x0008---115200 Other----115200
  modbus.writeHoldingRegister(SLAVE_ADDR, eComBaudrate, baudrateIndex);//Writes the new baud rate value to the corresponding register
  delay(50);
  res = modbus.readHoldingRegister(SLAVE_ADDR, eComBaudrate);
  if (res ==  baudrateIndex)
    Serial.print("The baudrate has been modified as 9600.please reset the device!");
  while (1);
}
 
探测角度及灵敏度说明
超声波传感器的物理特性决定了其实际具有不规则的探测区域,因此超声波测距传感器的探测角度难以被准确的定义。我们分别使用了2种参考目标障碍物对多样本产品进行了测试,对应目标的参照检测区域如下图示:
常见问题
1、如有疑问,欢迎通过qq或者论坛联系我们!
更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。
