Introduction
This URM12 from DFRobot is the latest ultrasonic distance sensor designed for distance ranging or obstacle avoidance applications. The sensor offers up to 1500cm detection distance, 15° detection angle and built-in temperature compensation. It adopts RS485 communication interface and supports standard Modbus-RTU protocol, which is suitable for level measurement, robot obstacle avoidance and so on.
Specification
- Operating Voltage: DC 9-24V
- Rated Power: 4.8W
- Effective Detection Range: 70 ~ 1500cm
- Distance Resolution: 1cm
- Distance Accuracy: 1%
- Temperature Resolution: 0.1℃
- Temperature Accuracy: ±1℃
- Measuring Frequency: 3Hz
- Operating Temperature: -10℃~+70℃
- Operating Humidity Range: RH<75%
- Acoustics Frequency: 38~42KHz
- Direction Angle: 15°±2°(-6dB)
- IP Grade: IP65
- Communication Interface: RS485
Board Overview
Wiring Order
Black (thick line)----Shielded cable
White------------------VCC
Black (thin line)------GND
Orange-----------------RS485-A
Brown------------------RS485-B
Register Description
Register Address | Number | Name | Read/Write | Data Range | Default Value | Data Description |
---|---|---|---|---|---|---|
0x00 | 1 | Module PID Register | R | 0x0000-0xFFFF | 0x0001 | Product check (Detect module type) |
0x01 | 1 | Module VID Register | R | 0x0000-0xFFFF | 0x0010 | Version check (0x0010 represents V0.0.1.0) |
0x02 | 1 | Module Address Register | R/W | 0x0001-0x00F7 | 0x000B | When the sensor address is unknown, write to the register through the broadcast address 0x00, at this time, the sensor will not have data output |
0x03 | 1 | Serial parameter control register 1 | R/W | 0x0000-0xFFFF | 0x0005 | Module Baudrate: 0x0001---2400 0x0003---9600 0x0004---14400 0x0005---19200 0x0006---38400 0x0007---57600 0x0008---115200 Other----115200 |
0x04 | 1 | Serial parameter control register 2 | R/W | 0x0000-0xFFFF | 0x0001 | Module check bit H: Stop bit L: 0x00---None 0x00---0.5byte 0x01---Even 0x01---1byte 0x02---Odd 0x02---1.5byte other---none 0x03---2byte Other---1byte |
0x05 | 1 | Distance register | R | 0x0000-0xFFFF | 0x0000 | The distance value LSB measured by the module represents 1cm |
0x06 | 1 | Onboard temperature data register | R | 0x0000-0xFFFF | 0x0000 | The temperature value measured by the onboard temperature sensor represents 0.1℃ (with unit symbol) |
0x07 | 1 | External temperature compensation data register | R/W | 0x0000-0xFFFF | 0x0000 | LSB write ambient temperature data to this register for external temperature compensation represents 0.1℃ (with unit symbol) |
0x08 | 1 | Control register | R/W | 0x0000-0xFFFF | 0x0004 | bit 1-0 00-use onboard temperature compensation function 01-use external temperature compensation function(Users need to write temperature data to external temperature compensation data register) 1x-Not use temperature compensation function bit 2: 0-auto detection 1-passive detection bit 3: In passive detection mode, write 1 to this bit, then it will measure distance once. The distance value can be read from distance register 300ms later. This bit is disabled in passive detection mode. |
Register Read/Write
Requirements
- Hardware
- 1 x Arduino Leonardo (Since RS485 to TTL will occupy one serial port, it is recommended using a device with two or more serial ports like Arduino Leonardo. Arduino Modbus protocol takes up a lot of memory, so we recommend to use Arduino mega2560 board.)
- 1 x RS485 Shield for Arduino
- 1 x DC Power Supply (DC 24V)
- 1 x USB Cable (Connect Arduino board and a PC)
- Software
- Arduino IDE
- Open "Library Manager"(Ctrl+Shift+I) in IDE, find and install ArduinoModbus and ArduinoRS485 libraries.
- Hardware Connection
Read Measured Distance
Measure distance in passive ranging mode.
/**************************************************************************************************************
*This code tests the range finder function of the URM12 ultrasonic sensor(1500cm&RS485)
*@ author : roker.wang@dfrobot.com
*@ data : 30.09.2019
*@ version: 1.0
**************************************************************************************************************/
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>
#define slave_addr 0x0b
#define TEMP_CONFIG_BIT (0x03)
#define MEASURE_MODE_BIT (0x01 << 2)
#define MEASURE_TRIG_BIT (0x01 << 3)
typedef enum
{
PID,
VID,
SLAVE_ADDR,
COM_BAUDRATE,
COM_PARITY_STOP,
DISTANCE,
INTERNAL_TEMP,
EXTERN_TEMP,
CR
} regindex;
volatile uint16_t cr_t = 0;
uint16_t read_data(uint16_t addr_t, uint16_t reg)
{
uint16_t data_t;
if (!ModbusRTUClient.requestFrom(addr_t, HOLDING_REGISTERS, reg, 1))
{
Serial.print("failed to read registers! ");
Serial.println(ModbusRTUClient.lastError());
data_t = 0xffff;
}
else
{
data_t = ModbusRTUClient.read();
}
return data_t;
}
uint16_t write_data(uint16_t addr_t, uint16_t reg, uint16_t data)
{
if (!ModbusRTUClient.holdingRegisterWrite(addr_t, reg, data))
{
Serial.print("Failed to write coil! ");
Serial.println(ModbusRTUClient.lastError());
return 0;
}
else
return 1;
}
void setup() {
ModbusRTUClient.begin(19200);
Serial.begin(9600);
cr_t |= MEASURE_MODE_BIT;// Set bit2
cr_t &= ~(uint16_t)TEMP_CONFIG_BIT;//internal temp compensation
write_data(slave_addr, CR, cr_t); //write CR
delay(100);
}
volatile uint16_t dist_t;
void loop() {
cr_t |= MEASURE_TRIG_BIT;//Set bit3
write_data(slave_addr, CR, cr_t); //write CR
delay(300);// delay 300ms
dist_t = read_data(slave_addr,DISTANCE);
Serial.print("distance = ");
Serial.print(dist_t, 1);
Serial.println("cm");
}
Read Data from Onboard Temperature Sensor
/**************************************************************************************************************
*This code tests the temperature measurement function of the URM12 ultrasonic sensor(1500cm&RS485)
*@ author : roker.wang@dfrobot.com
*@ data : 30.09.2019
*@ version: 1.0
*RX(RS485 Shield) -> TX1/D1 (Arduino Leonardo) TX(RS485 Shield)-> RX1/D0 (Arduino Leonardo)
**************************************************************************************************************/
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>
#define slave_addr 0x0b
typedef enum
{
PID,
VID,
SLAVE_ADDR,
COM_BAUDRATE,
COM_PARITY_STOP,
DISTANCE,
INTERNAL_TEMP,
EXTERN_TEMP,
CR
} regindex;
uint16_t read_data(uint16_t addr_t, uint16_t reg)
{
uint16_t data_t;
if (!ModbusRTUClient.requestFrom(addr_t, HOLDING_REGISTERS, reg, 1))
{
Serial.print("failed to read registers! ");
Serial.println(ModbusRTUClient.lastError());
data_t = 0xffff;
}
else
{
data_t = ModbusRTUClient.read();
}
return data_t;
}
uint16_t write_data(uint16_t addr_t, uint16_t reg, uint16_t data)
{
if (!ModbusRTUClient.holdingRegisterWrite(addr_t, reg, data))
{
Serial.print("Failed to write coil! ");
Serial.println(ModbusRTUClient.lastError());
return 0;
}
else
return 1;
}
void setup() {
Serial.begin(9600);
ModbusRTUClient.begin(19200);
}
volatile float temp;
void loop() {
temp = read_data(slave_addr,INTERNAL_TEMP) / 10.0;
Serial.print("internal temp = ");
Serial.print(temp,1);
Serial.println("C");
delay(500);
}
Modify Module Address
/**************************************************************************************************************
*This code tests the address modification function of the URM12 ultrasonic sensor(1500cm&RS485)
*@ author : roker.wang@dfrobot.com
*@ data : 30.09.2019
*@ version: 1.0
*RX(RS485 Shield) -> TX1/D1 (Arduino Leonardo) TX(RS485 Shield)-> RX1/D0 (Arduino Leonardo)
**************************************************************************************************************/
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>
#define addr_public 0x00
typedef enum
{
PID,
VID,
SLAVE_ADDR,
COM_BAUDRATE,
COM_PARITY_STOP,
DISTANCE,
INTERNAL_TEMP,
EXTERN_TEMP,
CR
} regindex;
uint16_t cr_t = 0;
uint16_t read_data(uint16_t addr_t, uint16_t reg)
{
uint16_t data_t;
if (!ModbusRTUClient.requestFrom(addr_t, HOLDING_REGISTERS, reg, 1))
{
Serial.print("failed to read registers! ");
Serial.println(ModbusRTUClient.lastError());
data_t = 0xffff;
}
else
{
data_t = ModbusRTUClient.read();
}
return data_t;
}
uint16_t write_data(uint16_t addr_t, uint16_t reg, uint16_t data)
{
if (!ModbusRTUClient.holdingRegisterWrite(addr_t, reg, data))
{
//Serial.print("Failed to write coil! ");
//Serial.println(ModbusRTUClient.lastError());
return 0;
}
else
return 1;
}
void setup() {
Serial.begin(9600);
ModbusRTUClient.begin(19200);
delay(3000);
}
volatile uint16_t addr, res;
void loop() {
addr = 0x11;
res = write_data(addr_public, SLAVE_ADDR, addr);
Serial.print("The device address has been modified as ");
Serial.print(addr);
Serial.println(".please power off and restart the device");
while (1);
}
Modify Module Baud Rate
/**************************************************************************************************************
*This code tests the baudrate modification function of the URM12 ultrasonic sensor(1500cm&RS485)
*@ author : roker.wang@dfrobot.com
*@ data : 30.09.2019
*@ version: 1.0
*RX(RS485 Shield) -> TX1/D1 (Arduino Leonardo) TX(RS485 Shield)-> RX1/D0 (Arduino Leonardo)
**************************************************************************************************************/
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>
#define addr_default 0x0B
#define baudrate_default 19200
typedef enum
{
PID,
VID,
SLAVE_ADDR,
COM_BAUDRATE,
COM_PARITY_STOP,
DISTANCE,
INTERNAL_TEMP,
EXTERN_TEMP,
CR
} regindex;
uint16_t cr_t = 0;
uint16_t read_data(uint16_t addr_t, uint16_t reg)
{
uint16_t data_t;
if (!ModbusRTUClient.requestFrom(addr_t, HOLDING_REGISTERS, reg, 1))
{
Serial.print("failed to read registers! ");
Serial.println(ModbusRTUClient.lastError());
data_t = 0xffff;
}
else
{
data_t = ModbusRTUClient.read();
}
return data_t;
}
uint16_t write_data(uint16_t addr_t, uint16_t reg, uint16_t data)
{
if (!ModbusRTUClient.holdingRegisterWrite(addr_t, reg, data))
{
Serial.print("Failed to write coil! ");
Serial.println(ModbusRTUClient.lastError());
return 0;
}
else
return 1;
}
void setup() {
Serial.begin(9600);
ModbusRTUClient.begin(baudrate_default);
delay(3000);
}
volatile uint16_t baudrate_index, res;
void loop() {
baudrate_index = 3;//0x0001---2400 0x0002---4800 0x0003---9600 0x0004---14400
//0x0005---19200 0x0006---38400 0x0007---57600 0x0008---115200 Other----115200
res = write_data(addr_default, COM_BAUDRATE, baudrate_index);
if(res)
Serial.print("The baudrate has been modified as 9600.please power off and restart the device");
while (1);
}
Detetion Angle and Sensitivity
Normally, the detection area of an ultrasonic sensor is irregular and hard to define due to its physical characteristics. In actual use, we found that the detection area and sensitivity of this sensor may be larger than other ultrasonic sensors. Therefore, when the sensor is used in a narrow space, a non-target object may be detected.
We used two kinds of reference target obstacles to repeatedly test many sample products. The reference detection area of the corresponding target is as follows:
- Detection area for 7.5cm PVC pipe
- Detection area for 100x30cm plane plate