SEN0310

概 述

URM13是一款开放式单探头超声波测距传感器,支持TRIG脉冲触发测距(兼容SR04)、UART和I2C,传感器可以在三种接口模式间无缝切换。该传感器尺寸紧凑、并且兼容如Arduino、树莓派等各种3.3V或5V主控板,非常方便用户集成和应用,UART模式使用标准Modbus-RTU协议并集成了收发控制输出,可简单通过外接RS485收发器扩展RS485接口。该传感器在保持同类传感器尺寸及重量优势的同时还具有非常出色的测距灵敏度,使得他对于一些低声波反射率的探测目标同样具备超越同类传感器的探测性能。URM13传感器会在每次测距时自动检测环境及电源噪声并以此来动态调节测量参数,确保它能在各种复杂应用场景之下依旧能够稳定工作。
为了满足不同的用户需求,URM13内置两段测距量程:
1、小量程15-150cm:可以实现高达50HZ的高频率探测,适用于室内机器人避障等场景。
2、大量程40-900cm:具有卓越的测量灵敏度,测量频率为常规10HZ,适用于空旷场景或需要高灵敏度、高量程距离探测的场景。
实际使用时,可通过重复触发2段量程的测距,以实现整个量程的检测。

技术参数

接口及尺寸

接口及尺寸示意图

板载LED灯状态指示

UART与I2C模式切换

URM13传感器默认出厂设置为UART模式。 传感器可以在I2C、UART两种模式间通过上电前短接不同的引脚实现简单的模式切换:

在模式切换成功后,用户即可断开对应引脚的短接,切换后的模式将被传感器记录保存,永久生效。

UART寄存器说明

UART接口下,传感器为Modbus从机,主机需要通过Modbus协议与传感器进行通信。

地址 数量 名称 读写 数据范围 默认值 数据说明
0x00 1 模块PID寄存器 R 0x0000-0xFFFF 0x0003 该位用于产品校验[可实现模块类型的检测]
0x01 1 模块VID寄存器 R 0x0000-0xFFFF 0x0010 该位用于版本校验[0x0010表示V0.0.1.0]
0x02 1 模块地址寄存器 R/W 0x0001-0x00F7 0x000D [传感器地址未知时,可通过广播地址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 模块校验位H    停止位L
0x00--无        0x00--0.5Byte
0x01--Even      0x01--1Byte
0x02--Odd      0x02--1.5Byte
Other--无       0x03--2Byte
                Other--1Byte        
断电保存,重启后生效
0x05 1 距离寄存器 R 0x0000-0xFFFF 0xFFFF 模块测得的距离值LSB代表0.1mm
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
0-开启温度补偿功能
1-关闭温度补偿功能
bit2
0-自动测距
1-被动测距
bit3
被动模式下,向该位写入1,传感器将完成一次测距,测距完成后(约100ms)可从距离寄存器读出距离值,自动测距模式下该位保留。该位置1后将自动清0
bit4
0-大量程测距(40-900cm)
1-小量程测距(15-150cm)
断电保存,立即生效
0x09 1 电源噪声等级寄存器 R 0x0000-0x0A 0x0000 0x0000-0x000A对应噪声等级0-10
该参数能够反映供电电源以及环境对传感器的影响程度。噪声等级越小,传感器得到的距离值将更精准。
0x0A 1 测距灵敏度设置寄存器 R/W 0x0000-0x0A 0x0000 0x0000-0x000A:灵敏度等级0-10
设置传感器大量程段(40-900cm)的测距灵敏度,该值越小,灵敏度越高
断电保存,立即生效

UART模式Arduino示例

准备

库安装

UART接线示意图

基于Arduino Modbus库示例代码

/**************************************************************************************************************
     This code tests the range finder function of the URM13 ultrasonic sensor
     @ author : roker.wang@dfrobot.com
     @ data   : 21.08.2020
     @ version: 1.0
**************************************************************************************************************/
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>

#define   SLAVE_ADDR                ((uint16_t)0x0D)

#define   TEMP_CPT_SEL_BIT          ((uint16_t)0x01 << 0)
#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)
#define   MEASURE_RANGE_BIT         ((uint16_t)0x01 << 4)

typedef enum {
  ePid,
  eVid,
  eAddr,
  eComBaudrate,
  eComParityStop,
  eDistance,
  eInternalTempreture,
  eExternTempreture,
  eControl,
  eNoise,
  eSensitivity
} eRegIndex_t; //Sensor register index

/*
 *@brief Read data from holding register of client
 *
 *@param addr : Address of Client
 *@param reg: Reg index
 *@return data if execute successfully, false oxffff.
 */
uint16_t readData(uint16_t addr, eRegIndex_t reg)
{
  uint16_t data;
  if (!ModbusRTUClient.requestFrom(addr, HOLDING_REGISTERS, reg, 1)){
    Serial.print("failed to read registers! ");
    Serial.println(ModbusRTUClient.lastError());
    data = 0xffff;
  }else{
    data =  ModbusRTUClient.read();
  }
  return data;
}

/*
 *@brief write data to holding register of client 
 *
 *@param addr : Address of Client
 *@param reg: Reg index
 *@param data: The data to be written
 *@return 1 if execute successfully, false 0.
 */
uint16_t writeData(uint16_t addr, eRegIndex_t reg, uint16_t data)
{
  if (!ModbusRTUClient.holdingRegisterWrite(addr, reg, data)){
    Serial.print("Failed to write coil! ");
    Serial.println(ModbusRTUClient.lastError());
    return 0;
  }else
    return 1;
}

int16_t  dist;float temp;
volatile uint16_t cr = 0;
void setup() {
  ModbusRTUClient.begin(19200);
  Serial.begin(9600);
  cr &= ~TEMP_CPT_SEL_BIT;//clear bit0, select internal temperature compensation
  //cr |= TEMP_CPT_SEL_BIT;//set bit0,select external temperature compensation
  cr &= ~TEMP_CPT_ENABLE_BIT;//clear bit1,enable temperature compensation
  //cr |= TEMP_CPT_ENABLE_BIT; //set bit1,disable temperature compensation
  cr |= MEASURE_MODE_BIT;//set bit2 , set to trigger mode
  //cr &= ~MEASURE_MODE_BIT;//clear bit2 , set to Automatic ranging mode
  cr &= ~MEASURE_RANGE_BIT;//clear bit4,long-range ranging mode
  //cr |= MEASURE_RANGE_BIT; //set bit4,short-range ranging mode
  writeData(SLAVE_ADDR, eControl, cr); //Writes the setting value to the control register
  delay(100);
}

void loop() {
  cr |= MEASURE_TRIG_BIT;//Set trig bit
  writeData(SLAVE_ADDR, eControl, cr); //Write the value to the control register and trigger a ranging
  delay(300);//Delay of 300ms(minimum delay should be greater than 100ms) is to wait for the completion of ranging
  dist = readData(SLAVE_ADDR, eDistance);//Read distance register, one LSB is 1cm
  delay(10);
  temp = (float)readData(SLAVE_ADDR, eInternalTempreture) / 10.0;//Read tempreture register, one LSB is 0.1 ℃
  Serial.print("dist = ");
  Serial.print(dist);
  Serial.print("cm---");

  Serial.print("temp = ");
  Serial.print(temp);
  Serial.println(" ℃");
}
串口Modbus库读取演示

基于Arduino串口发送命令示例代码

/**************************************************************************************************************
     This code tests the range finder function of the URM13 ultrasonic sensor
     @ author : roker.wang@dfrobot.com
     @ data   : 21.08.2020
     @ version: 1.0
**************************************************************************************************************/
#define   SLAVE_ADDR                ((uint16_t)0x0D)

#define   TEMP_CPT_SEL_BIT          ((uint16_t)0x01 << 0)
#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)
#define   MEASURE_RANGE_BIT         ((uint16_t)0x01 << 4)

#define   MB_OP_WRITE_SINGLE_HOLDING_REG  ((uint8_t)0x06)
#define   MB_OP_READ_HOLDING_REGS         ((uint8_t)0x03)

typedef enum {
  ePid,
  eVid,
  eAddr,
  eComBaudrate,
  eComParityStop,
  eDistance,
  eInternalTempreture,
  eExternTempreture,
  eControl,
  eNoise,
  eSensitivity
} eRegIndex_t; //Sensor register index

static const uint8_t aucCRCHi[] = {
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  0x00, 0xC1, 0x81, 0x40
};

static const uint8_t aucCRCLo[] = {
  0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
  0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
  0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
  0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
  0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
  0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
  0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
  0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
  0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
  0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
  0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
  0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
  0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
  0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
  0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
  0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
  0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
  0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
  0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
  0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
  0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
  0x41, 0x81, 0x80, 0x40
};

static uint16_t mbCrcCalculated(uint8_t  * pCmd, uint8_t  usLen )
{
  uint8_t ucCRCHi = 0xFF;
  uint8_t ucCRCLo = 0xFF;
  int16_t iIndex;

  while ( usLen-- )
  {
    iIndex = ucCRCLo ^ *( pCmd++ );
    ucCRCLo = ( uint8_t )( ucCRCHi ^ aucCRCHi[iIndex] );
    ucCRCHi = aucCRCLo[iIndex];
  }
  return ( uint16_t )( (uint16_t)ucCRCHi << 8 | ucCRCLo );
}
/*
  @brief Read data from holding register of client

  @param addr : Address of Client
  @param reg: Reg index
  @param regNum: The number of registers to read,The register is 16 bits wide
  @param pBuf:Points to the receive data buffer
*/
void readHoldingRegisters(uint16_t addr, eRegIndex_t regIndex, uint16_t regNum, uint8_t *pBuf)
{
  uint8_t pCmdBuf[8], i;
  uint16_t crc;

  pCmdBuf[0] = addr;
  pCmdBuf[1] = MB_OP_READ_HOLDING_REGS;
  pCmdBuf[2] = regIndex >> 8;
  pCmdBuf[3] = (uint8_t)regIndex;
  pCmdBuf[4] = regNum >> 8;
  pCmdBuf[5] = (uint8_t)regNum;

  crc = mbCrcCalculated(pCmdBuf, 6);
  pCmdBuf[6] = (uint8_t)crc;
  pCmdBuf[7] = crc >> 8;

  for (i = 0; i < 8; i++) {
    Serial1.write( pCmdBuf[i]);
  }
  delay(150);
  i = 0;
  while (Serial1.available()) {
    pBuf[i++] = (Serial1.read());
  }
}
/*
  @brief Write data to holding register of client

  @param addr : Address of Client
  @param reg: Reg index
  @param data: The data to be sent
  @param pBuf:Points to the receive data buffer
*/
void writeSigleHoldingRegister(uint16_t addr, eRegIndex_t regIndex, uint16_t data, uint8_t *pBuf)
{
  uint8_t pCmdBuf[8], i;
  uint16_t crc;

  pCmdBuf[0] = addr;
  pCmdBuf[1] = MB_OP_WRITE_SINGLE_HOLDING_REG;
  pCmdBuf[2] = regIndex >> 8;
  pCmdBuf[3] = (uint8_t)regIndex;
  pCmdBuf[4] = data >> 8;
  pCmdBuf[5] = (uint8_t)data;

  crc = mbCrcCalculated(pCmdBuf, 6);
  pCmdBuf[6] = (uint8_t)crc;
  pCmdBuf[7] = crc >> 8;

  for (i = 0; i < 8; i++) {
    Serial1.write( pCmdBuf[i]);
  }
  delay(150);
  i = 0;
  while (Serial1.available()) {
    pBuf[i++] = (Serial1.read());
  }
}

uint8_t rxBuf[100];
int16_t  dist; float temp;

volatile uint16_t cr = 0;
void setup() {
  Serial1.begin(19200);
  Serial.begin(9600);
  cr &= ~TEMP_CPT_SEL_BIT;//clear bit0, select internal temperature compensation
  //cr |= TEMP_CPT_SEL_BIT;//set bit0,select external temperature compensation
  cr &= ~TEMP_CPT_ENABLE_BIT;//clear bit1,enable temperature compensation
  //cr |= TEMP_CPT_ENABLE_BIT; //set bit1,disable temperature compensation
  cr |= MEASURE_MODE_BIT;//set bit2 , set to trigger mode
  //cr &= ~MEASURE_MODE_BIT;//clear bit2 , set to Automatic ranging mode
  cr &= ~MEASURE_RANGE_BIT;//clear bit4,long-range ranging mode
  //cr |= MEASURE_RANGE_BIT; //set bit4,short-range ranging mode
  writeSigleHoldingRegister(SLAVE_ADDR, eControl, cr, rxBuf); //Writes the setting value to the control register
  delay(100);
}

void loop() {
  cr |= MEASURE_TRIG_BIT;//Set trig bit
  writeSigleHoldingRegister(SLAVE_ADDR, eControl, cr, rxBuf); //Write the value to the control register and trigger a ranging
  delay(300);//Delay of 300ms(minimum delay should be greater than 100ms) is to wait for the completion of ranging
  readHoldingRegisters(SLAVE_ADDR, eDistance, 1, rxBuf); //Read distance register, one LSB is 1cm
  dist = (int16_t)rxBuf[3] << 8 | rxBuf[4];
  delay(10);
  readHoldingRegisters(SLAVE_ADDR, eInternalTempreture, 1, rxBuf); //Read tempreture register
  temp = (float)((int16_t)rxBuf[3] << 8 | rxBuf[4]) / 10.0;// one LSB is 0.1 ℃
  Serial.print("dist = ");
  Serial.print(dist);
  Serial.print("cm---");

  Serial.print("temp = ");
  Serial.print(temp);
  Serial.println(" ℃");
}
串口发送命令演示

I2C寄存器说明

地址 名称 读写 数据范围 默认值 数据说明
0x00 传感器地址寄存器 R 0x01-0xF7 0x12 I2C从机地址
断电保存,重启后生效
0x01 传感器PID寄存器 R 0x00-0xFF 0x02 该位用于产品校验[可实现传感器类型的检测]
0x02 传感器VID寄存器 R 0x00-0xFF 0x10 固件版本号:0x10代表V1.0
0x03
0x04
距离值寄存器高位
距离值寄存器低位
R
R
0x00-0xFF
0x00-0xFF
0xFF
0xFF
LSB为1cm,例:0x0064 = 100cm
0x05
0x06
板载温度值寄存器高位
板载温度值寄存器低位
R
R
0x00-0xFF
0x00-0xFF
0xFF
0xFF
LSB代表0.1摄氏度,有符号数,例:读出的高位值 TEMP_H = 0x00,低位值TEMP_L = 0xfe,则实际测得的温度值为0x00fe / 10 = 25.4℃
0x07
0x08
外部温度补偿数据寄存器高位
外部温度补偿数据寄存器低位
R/W
R/W
0x00-0xFF
0x00-0xFF
0x00
0x00
写入环境温度数据到该寄存器用于外部温度补偿,LSB代表0.1摄氏度(有符号数)
0x09 配置寄存器 R/W 0x00-0xFF 0x04 bit5-bit7:保留
bit4(最大测量距离设置位):
0:大量程测距(40 - 900cm)
1:小量程测距(15-150cm)
bit3:保留
bit2:
0:自动测量模式,模块一直在进行距离测量,并不断更新距离寄存器
1:被动测量,发送一次测距命令,模块测量一次距离并将测量的距离值存入距离寄存器
bit1:
0:温度补偿开启
1:关闭温度补偿
bit0:
0:使用板载温度补偿
1:使用外部温度补偿
断电保存,立即生效
0x0A 命令寄存器 R/W 0x00-0xFF 0x00 bit7-bit6:保留
bit0:
向该位写1,触发一次测距,向该位写0被忽略
0x0B 电源噪声等级寄存器 R 0x00-0x0A 0x00 0x00-0x0A对应噪声等级0-10
该参数能够反映供电电源以及环境对传感器的影响程度。噪声等级越小,传感器得到的距离值将更精准。
0x0C 测距灵敏度设置寄存器 R/W 0x00-0x0A 0x00 0x00-0x0A:灵敏度等级0-10
用于设置传感器大量程段(40-900cm)的测距灵敏度,该值越小,灵敏度越高
断电保存,立即生效

I2C模式Arduino示例

###准备

测距演示

示例代码

/*!
       Download this demo to test config to URM13, connect sensor through IIC interface
       Data will print on your serial monitor

       This example is the ultrasonic passive measurement distance and the temperature of the module.

       Copyright   [DFRobot](http://www.dfrobot.com), 2018
       Copyright   GNU Lesser General Public License

       version  V1.0
       date  21/08/2020
*/
#include <Wire.h>
typedef enum {
  eAddr = 0,
  ePid,
  eVid,
  eDistanceH ,
  eDistanceL,
  eInternalTempretureH,
  eInternalTempretureL,
  eExternalTempretureH,
  eExternalTempretureL,
  eConfig,
  eCmd,
  eNoise,
  eSensitivity,
  eRegNum
} regindexTypedef;

#define    MEASURE_RANGE_BIT        ((uint8_t)0x01 << 4)
#define    MEASURE_MODE_BIT         ((uint8_t)0x01 << 2)
#define    TEMP_CPT_ENABLE_BIT      ((uint8_t)0x01 << 1)
#define    TEMP_CPT_SEL_BIT         ((uint8_t)0x01 << 0)

#define    IIC_SLAVE_ADDR           ((uint8_t)0x12)
#define    isSensorBusy()           (digitalRead(busyPin))

int16_t    busyPin = 4;
/*
  @brief Write data to register of client

  @param addr : Address of Client
  @param regIndex: Reg index
  @param pDataBuf: point to data buffer
  @param dataLen: data length
*/
void i2cWriteBytes(uint8_t addr, regindexTypedef regIndex , uint8_t *pDataBuf, uint8_t dataLen )
{
  Wire.beginTransmission(addr); // transmit to device
  Wire.write(regIndex);              // sends one byte
  for (uint8_t i = 0; i < dataLen; i++) {
    Wire.write(*pDataBuf);
    pDataBuf++;
  }
  Wire.endTransmission();    // stop transmitting
}
/*
  @brief Read data from register of client

  @param addr : Address of Client
  @param regIndex: Reg index
  @param pDataBuf: point to data buffer
  @param dataLen: data length
*/
void i2cReadBytes(uint8_t addr, regindexTypedef regIndex , uint8_t *pDataBuf, uint8_t dataLen )
{
  unsigned char i = 0;
  Wire.beginTransmission(addr); // transmit to device #8
  Wire.write(regIndex);              // sends one byte
  Wire.endTransmission();    // stop transmitting
  Wire.requestFrom(addr, dataLen);
  while (Wire.available()) {  // slave may send less than requested
    pDataBuf[i] = Wire.read();
    i++;
  }
}

uint8_t cfg = 0, cmd = 0;
uint8_t rxBuf[100] = {0};
void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(9600); // join i2c bus (address optional for master)
  pinMode(busyPin, INPUT);
  cfg &= ~MEASURE_RANGE_BIT;//clear bit4,long-range ranging mode
  //cfg |= MEASURE_RANGE_BIT;//set bit4,short-range ranging mode
  cfg |=  MEASURE_MODE_BIT;//Set bit2,i2c passive mode
  //cfg &= ~MEASURE_MODE_BIT;//clear bit2 , set to Automatic ranging mode
  cfg &= ~TEMP_CPT_ENABLE_BIT;//clear bit1,enable temperature compensation
  //cfg |= TEMP_CPT_ENABLE_BIT;//set bit1,disable temperature compensation
  cfg &= ~TEMP_CPT_SEL_BIT;//clear bit0,select internal temperature compensation
  //cfg |= TEMP_CPT_SEL_BIT;//set bit0,select external temperature compensation
  i2cWriteBytes(IIC_SLAVE_ADDR, eConfig , &cfg, 1 );
  delay(100);
}
void loop() {
  int16_t  dist, temp;
  cmd |= 0x01;//Set trig bit
  i2cWriteBytes(IIC_SLAVE_ADDR, eCmd , &cmd, 1 );//Write command register
  //You can replace the delay with these two lines of code
  //while(isSensorBusy()== HIGH);  //Wait for the sensor to start ranging
  //while(isSensorBusy()== LOW);   //Wait for sensor ranging to complete
  delay(100);//delay 100ms
  i2cReadBytes(IIC_SLAVE_ADDR, eDistanceH, rxBuf, 2 ); //Read distance register
  dist = ((uint16_t)rxBuf[0] << 8) + rxBuf[1];
  delay(10);
  i2cReadBytes(IIC_SLAVE_ADDR, eInternalTempretureH, rxBuf, 2 ); //Read the onboard temperature register
  temp = ((uint16_t)rxBuf[0] << 8) + rxBuf[1];

  Serial.print(dist, DEC);
  Serial.print("cm");
  Serial.print("------");

  Serial.print((float)temp / 10, 1);
  Serial.println("℃");
}
修改模块地址演示

TRIG脉冲触发示例

准备

测距演示
/*!
       This example is the ultrasonic distance measurement of the module.

       Copyright   [DFRobot](http://www.dfrobot.com), 2020
       Copyright   GNU Lesser General Public License

       version  V1.0
       date  21/08/2020
*/
#define    VELOCITY_TEMP(temp)       ( ( 331.5 + 0.6 * (float)( temp ) ) * 100 / 1000000.0 ) // The ultrasonic velocity (cm/us) compensated by temperature

int16_t trigPin = 5;
int16_t echoPin = 6;
uint16_t distance;
uint32_t pulseWidthUs;
void setup() {
  Serial.begin(9600);
  pinMode(trigPin,OUTPUT);
  digitalWrite(trigPin,LOW);
  pinMode(echoPin,INPUT);
  delay(100);
}
void loop() {
  int16_t  dist, temp;
  digitalWrite(trigPin,HIGH);//Set the tirgPin High
  delayMicroseconds(50);     //Delay of 50 microseconds
  digitalWrite(trigPin,LOW); //Set the tirgPin Low

  pulseWidthUs = pulseIn(echoPin,HIGH);//Measure echo high level time, the output high level time represents the ultrasonic flight time (unit: us)
  distance = pulseWidthUs * VELOCITY_TEMP(33) / 2.0;//The distance can be calculated according to the flight time of ultrasonic wave,/
                                                    //and the ultrasonic sound speed can be compensated according to the actual ambient temperature
  Serial.print(distance, DEC);
  Serial.println("cm");
  delay(100);
}
修改模块地址演示

常见问题

1、如有疑问,欢迎通过qq或者论坛联系我们! 更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。

更多

DFshopping_car1.png [Link DFRobot商城购买链接] [11]: https://makelog.dfrobot.com.cn/wiki2/index/add/df_cn?subject=SKU_SEN0352_URM13_Ultrasonic_Sensor