URM37 V5.0超声波测距传感器

简介

URM37是一款功能强大的超声波传感器模块,内置温度补偿,确保在温度变化的应用场景中实现准确测距。它具有丰富的接口,集成了开关量、串口(TTL和RS232电平可选)、脉宽输出、模拟量输出等功能。模块还具备舵机角度驱动测距的功能,可以通过外接一个舵机组成一个空间超声波扫描仪。URM37已在市场销售多年,并在各种领域发挥着重要作用,我们也在不断对其进行优化和改进。V5.0版本机械尺寸、引脚接口以及通信命令兼容老版本模块。 在老版本基础上做了如下改进:

产品参数

产品规格

技术说明

引脚说明

URM37 V5.0模块正面管脚

引脚 引脚说明
VCC 电源输入(3.3V-5.5V)
GND 电源地
NRST 模块复位,低电平复位(不用时可以悬空)
ECHO 测量到的距离数据以PWM脉宽方式输出0-25000US,每50US代表1厘米
SERVO 舵机控制脚
COMP/TRIG COMP: 比较模式开关量输出,测量距离小于设置比较距离时输出低电平/TRIG:PWM模式触发脉冲输入
DAC_OUT 模拟电压输出,电压和测量距离成正比
RXD 异步通讯模块接收数据管脚,RS232电平或者TTL电平
TXD 异步通讯模块发送数据管脚,RS232电平或者TTL电平

使用教程

URM37 V5.0模块功能强大到超乎你的想象,首先我们要了解这个模块的基本功能,测距的模式有三种:一PWM触发测量模式、二自动测量模式、三串口被动测量。还具有一下特性:模拟量输出(和测量距离正比)、温度读取、和串口电平方式设置(TTL或者RS232电平)、内部EEPROM掉电不丢失数据保存、串口读取EEPROM数据等。URM37出厂时我们进行了严格的测试,用户购买到之后可根据自己的需求进行相关设置,首先是串口电平方式的设置(TTL或者RS232电平),设置好之后我们就可以通过串口对模块进行访问,然后设置测距模式(对内部EEPROM地址0x02写入数据),之后就可以通过MCU或者PC对超声波模块驱动。

通讯协议

模块串口波特率9600,无奇偶校验,一位停止位。控制命令通过一致的帧结构通讯,帧长度4字节:命令+数据0+数据1+校验和。校验和=命令+数据0+数据1的相加和的低8位。模块可以直接通过PC串口或单片机串口进行操作。

注意:NC代表任意数据,SUM代表校验和。

温度读取指令

*发送:0x11+NC+NC+SUM *返回:0x11+温度高+温度低+SUM

命令启动一次读取命令,测量温度完毕后模块发出带相同命令头的数据加两字节的温度数据:0x11+温度高+温度低+SUM(SUM代表效验和,NC代表任意数据)。温度高字节的高4位代表温度正负,当高4位都是1时说明是负温度,当高4位都是0时是正温度,除去温度高字节的高4位后是12位的温度。分辨率0.1度,每个数字代表0.1摄氏度。当测量无效时返回的温度高位和低位数据都是0xff。

例如: 发送:0x11 0x00 0x00 0x11 返回:0x11 0x00 0xFA 0x0B 效果:返回的数据0xFA就是测量到的温度即温度为 25.0度

距离读取指令

*发送:0x22+度数+NC+SUM *返回:0x22+距离高+距离低+SUM

度数是控制舵机先旋转到一个度数后再进行测距。180度分为46个角度,每个角度4度,数字范围是十进制0到45,如果数字超过45电机将不动作。上电初始,舵机将旋转到当中即0度的位置。当指令是0时,舵机逆时针旋转到0度,当指令是45时,舵机顺时针旋转到180度。当测量完毕这时返回的数据是0x22+距离高+距离低+SUM。当测量无效时返回的距离高位和低位数据都是0xff。

例如: 发送:0x22 0x19 0x00 0x47 返回:0x22 0x00 0x64 0x86 效果:模块上的MOTO输出一个50Hz的方波,控制舵机转到100度(见参考表),返回距离低的数据为0x64,即距离为100cm。

舵机旋转角度参考表:

DEC 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
HEX 0 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
度数 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60
DEC 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
HEX 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
度数 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124
DEC 32 33 34 35 36 37 38 39 40 41 42 43 44 45
HEX 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D
度数 128 132 136 140 144 148 152 156 160 164 168 172 176 180

注意

模块上电后,并没有给舵机信号,如果上电后,给模块一个小于50us的脉冲,舵机回到初始位置,舵机的初始位置为0度,当然如果想要模块上电就到90度的位置,请给一个1100us的脉冲,是不是觉得我们这个设计很有爱,我们不做任何动作,想怎么做由你决定。

用串口读取距离命令或是通过触发模式控制舵机角度时,响应时间根据舵机的转动角度大小相关,最大响应时间为800ms左右(当舵机转动角度为180度时),因为供用户选择的控制角度为46个,所以舵机的转动时间也可大致均分为46份,舵机改变的角度越大,响应的时间也就越长。 |

内部EEPROM读取指令

*发送:0x33+地址+NC+SUM *返回:0x33+地址+数据+SUM。

发送读取指令后,返回的数据即内部EEPROM地址的数据。

内部EEPROM写入指令

*发送:0x44+地址+写数据+SUM *返回:0x44+地址+写数据+SUM

写地址范围包括0-127单元,其中地址0x00-0x05内存储的数据是模块使用的配置字,操作时需谨慎!可以通过读指令来校验数据是否被写入。写入成功返回0x44+地址+写数据+SUM。模块内部的EEPROM地址0x00到0x04用于配置模块参数。

  1. 0x00:比较距离低8位

  2. 0x01:比较距离高8位

  3. 0x02:测量模式(对模式寄存器写入0xaa自动测量模式,其他非0xaa数据都是PWM被动测量模式)

  4. 0x03:串口工作模式(写入数据0x00为TTL电平,也是默认工作方式哦,写入数据0x01为RS232电平,当然如果用户对0x03这个地址写入其他数据,会被修改为默认方式TTL电平)

  5. 0x04:自动测量时间间隔(最小测量时间间隔为70ms,最大为255ms,默认值为100ms,写入数据为八位16进制,最小单位为ms。例如写入6E,即为110ms)

  6. 0x05:设置测距灵敏度(写入数据范围为0x0a-0xc8(对应十进制为10-200),数值越小灵敏度越高,默认灵敏最高)

模式/参数设置方法

由于该模块有测距模式,电平选择等需要选择,因此这里将简单介绍相关的模式设定方法。

注意:URM37 V5.0的出厂设置为串口TTL电平、测量模式为PWM触发测量方式、比较距离为0、自动测量时间间隔为25ms,内部EEPROM内数据全部为0x00,EEPROM地址0x00~0x04内存的数据为系统保留配置字,用户需谨慎操作。 |

EEPROM各地址配置字节含义 关于模式设定,用户可以了解一下URM37内部EEPROM中,各存储单元中配置字节的含义(详见通信协议)。

地址 意义
0x00 比较距离高8位
0x01 比较距离低8位
0x02 测量模式(对模式寄存器写入0xaa自动测量模式,其他非0xaa数据都是PWM被动测量模式)
0x03 串口工作模式(写入数据0x00为TTL电平,也是默认工作方式哦,写入数据0x01为RS232电平,当然如果用户对0x03这个地址写入其他数据,会被修改为默认方式TTL电平)
0x04 自动测量时间间隔(最小测量时间间隔为70ms,最大为255ms,默认值为100ms,写入数据为八位16进制,最小单位为ms。例如写入6E,即为110ms)
0x05 测距灵敏度(写入数据范围为0x0a-0xc8(对应十进制为10-200),数值越小灵敏度越高,默认值为0x0a,灵敏度最高)

按键选择串口电平模式

要和模块通信,首先需要进行的就是串口电平的选择(TTL电平、RS232电平)。

URM37 V5.0模块串口模式修改按键

按下模块上的按键,指示灯亮,按住不动1s过后,设置成功,指示灯灭。松开按键,重新上电。即可更改串口输出模式。再次上电后指示灯出现一长一短闪则为TTL电平输出,一长两短闪为RS232电平

串口电平的选择,也可以通过对EEPROM地址0x03写入数据(见上表)。

warning_yellow.png 禁止在RS232工作模式下,将传感器接到TTL 适配器上,这样会造成器件损坏。反之亦然!

上位机软件选择测量模式

SEN0001_RS232模式_03.png

当你按照上图连接好模块后,就可以使用我们的“URM37 V3.2伴侣”对模块进行在线测试了,当然我们需要按照前面的按键设置串口电平方式改变一下串口的工作模式,按照现在的配图我需要串口工作在RS232电平模式下。

URM_37_V3.2_7.jpg

软件的使用极其简单:先保证电脑上没有其他软件占用串口,然后运行伴侣,先选择COM口,再点击“打开串口”,右边窗口选择探测功能,选择“16位温度读取”可以进行温度测量,选择“16位距离读取”可以进行距离测量,“控制指令”窗口同时显示将要发送的指令,点击“启动功能”便完成操作。此时,“返回数据”窗口中间两位显示的是16进制数据,软件下方状态栏内也会显示出温度及距离的10进制数据。该软件使用方便、数据直观。

如果你还购买了我们的专用舵机,便可以使用舵机控制部分。如图所示,在“舵机角度”窗口内选择要执行的角度,同时在选择“16位距离读取”,然后点击“启动功能”,舵机便旋转到相应的角度上,同时超声波测量该方向上障碍物的距离。由此URM37V4.0配合舵机就可以完成空间障碍物扫描功能。

测量模式的切换通过给内部EEPROM地址0x02写入0xaa的数据即切换到自动测量模式。串口发送数据 0x44 0x02 0xaa 0xf0 .

URM_37_V4.0_banlv.png

注意:测量模式的选择,也可以通过修改程序达到。具体见以下示例。 |

三种模式下的简单实验

触发模式

大家拿到模块后,可以直接使用触发模式和串口被动模式,所以首先我们就从触发模式开始入手。

触发模式下PWM脉宽输出

在触发控制模式下,外部控制COMP/TRIG端上产生一个低电平的触发脉冲信号启动一次距离测量操作,这个低电平脉冲宽度同时代表控制舵机转动的角度控制参数,将180度旋转角度分为46个角度控制参数,每个控制参数代表4度,数字范围是范围是0到45,脉冲每50US代表一个控制角度。当发出触发脉冲后,模块的MOTO脚产生舵机控制脉冲从而改变测量舵机的旋转度数,接下来ECHO端将测量到的距离数据以脉宽方式输出一个低电平脉冲,每50US代表1厘米,可以通过对这个低电平脉冲宽度的测量读取距离数据。当测量无效时将返回一个50000US的脉冲表示这次的测量是无效的。

将示例代码编译下载到Arduino板上,按照图示把超声波模块和Arduino连接就能够实现距离的测量。

SEN0001_触发模式接线图_04.png

演示代码


// # Editor     : roker
// # Date       : 05.03.2018

// # Product name: URM V5.0 ultrasonic sensor
// # Product SKU : SEN0001
// # Version     : 1.0

// # Description:
// # The Sketch for scanning 180 degree area 2-800cm detecting range
// # The sketch for using the URM37 PWM trigger pin mode from DFRobot
// #   and writes the values to the serialport
// # Connection:
// #       Vcc (Arduino)    -> Pin 1 VCC (URM V5.0)
// #       GND (Arduino)    -> Pin 2 GND (URM V5.0)
// #       Pin 3 (Arduino)  -> Pin 4 ECHO (URM V5.0)
// #       Pin 5 (Arduino)  -> Pin 6 COMP/TRIG (URM V5.0)

// # Working Mode: PWM trigger pin  mode.

int URECHO = 3;         // PWM Output 0-50000US,Every 50US represent 1cm
int URTRIG = 5;         // trigger pin

unsigned int DistanceMeasured = 0;

void setup()
{
  //Serial initialization
  Serial.begin(9600);                        // Sets the baud rate to 9600
  pinMode(URTRIG, OUTPUT);                   // A low pull on pin COMP/TRIG
  digitalWrite(URTRIG, HIGH);                // Set to HIGH
  pinMode(URECHO, INPUT);                    // Sending Enable PWM mode command
  delay(500);
  Serial.println("Init the sensor");

}
void loop()
{
  Serial.print("Distance=");
  digitalWrite(URTRIG, LOW);
  digitalWrite(URTRIG, HIGH);

  unsigned long LowLevelTime = pulseIn(URECHO, LOW) ;
  if (LowLevelTime >= 50000)              // the reading is invalid.
  {
    Serial.println("Invalid");
  }
  else
  {
    DistanceMeasured = LowLevelTime / 50;  // every 50us low level stands for 1cm
    Serial.print(DistanceMeasured);
    Serial.println("cm");
  }

  delay(200);
}

结果

Arduino 板发送给串口上位机显示距离信息,波特率选择9600baud

URM37V4.0_Serial.png

触发模式下模拟电压输出

我们能够实现最基本的测量后,就可以更深入使用我们模块上的更多功能,比如上面的谈到的模拟电压输出功能,当传感器检测到距离后(这里我们用的触发模式测量距离),会在模拟电压输出口(DAC_OUT)输出一个模拟电压值,此电压和测量距离成正比约4.125mV / cm,超出测量范围后输出电压为满电压3.3V。

将示例代码编译下载到Arduino板上,按照图示把超声波模块和Arduino连接就能够实现距离的测量。

SEN0001_模拟电压读取接线图_08.png

'演示代码

    // # Editor     : roker
    // # Date       : 05.03.2018

    // # Product name: URM V5.0 ultrasonic sensor
    // # Product SKU : SEN0001
    // # Version     : 1.0

    // # Description:
    // # The Sketch for scanning 180 degree area 2-800cm detecting range
    // # The sketch for using the URM37 PWM trigger pin mode from DFRobot
    // #   and writes the values to the serialport
    // # Connection:
    // #       Vcc (Arduino)    -> Pin 1 VCC (URM V5.0)
    // #       GND (Arduino)    -> Pin 2 GND (URM V5.0)
    // #       Pin 5 (Arduino)  -> Pin 6 COMP/TRIG (URM V5.0)
    // #       Pin A0 (Arduino) -> Pin 7 DAC (URM V5.0)

    int URTRIG = 5;         // trigger pin
    int sensorPin = A0;     // select the input pin for the potentiometer
    int sensorValue = 0;    // variable to store the value coming from the sensor

    unsigned int DistanceMeasured = 0;

    void setup()
    {
      //Serial initialization
      Serial.begin(9600);                        // Sets the baud rate to 9600
      pinMode(URTRIG, OUTPUT);                   // A low pull on pin COMP/TRIG
      digitalWrite(URTRIG, HIGH);                // Set to HIGH
      delay(500);
      Serial.println("Init the sensor");

    }
    void loop()
    {
      Serial.print("Distance=");
      digitalWrite(URTRIG, LOW);
      digitalWrite(URTRIG, HIGH);
      delay(200);
      sensorValue = analogRead(sensorPin);

      sensorValue = sensorValue * 1.1; //  (sensorValue * 5000 / 1024 ) / 4.125 = sensorValue * 1.1 , 计算ADC采集的电压值 ,再除以4.125mV /cm
      Serial.print(sensorValue);
      Serial.println("cm");

    }

注意:通过读取模拟电压输出值计算出来的距离值相对于其它方式读取的距离值误差较大。 |

自动测量模式

通过上位软件或者单片机对模块内部EEPROM 0x02地址写入数据0xaa即可切换到自动测量模式,对0x04地址写入一个8位的16进制数即可修改测量时间间隔。

模块每隔25MS(可设置)自动测量,将测量到的数据和比较值做比较,如果测量距离等于或者小于比较值,COMP/TRIG脚输出低电平。另外每启动一次测量,模块的PWM端将测量到的距离数据以脉宽方式输出一个低电平脉冲,每50us代表1厘米。设置好比较距离值后,可以简单的把模块当一个超声波开关使用。

将示例代码编译下载到Arduino板上,按照图示把超声波模块和Arduino连接就能够实现距离的测量。

注意:请先下载程序,再连接线路。因为UNO板下载程序时会占用TX/RX口,如果将arduino与SEN0001事先连接的话,将会导致程序下载失败。 |

SEN0001_自动测量模式接线图_05.png 演示代码


// # Editor     : roker
// # Date       : 05.03.2018

// # Product name: URM V5.0 ultrasonic sensor
// # Product SKU : SEN0001
// # Version     : 1.0

// # Description:
// # The sketch for using the URM37 autonomous  mode from DFRobot
// #   and writes the values to the serialport


// # Connection:
// #       Vcc (Arduino)      -> Pin 1 VCC (URM V5.0)
// #       GND (Arduino)      -> Pin 2 GND (URM V5.0)
// #       Pin 3 (Arduino)    -> Pin 4 ECHO (URM V5.0)
// #       Pin TX1 (Arduino)  -> Pin 8 RXD (URM V5.0)
// #       Pin RX0 (Arduino)  -> Pin 9 TXD (URM V5.0)
// # Working Mode:  Automatic measurement model.

int URECHO = 3; // PWM Output 0-50000US,Every 50US represent 1cm

unsigned int Distance = 0;
uint8_t AutomaticModelCmd[4] = {0x44, 0x02, 0xaa, 0xf0}; // distance measure command

void setup()
{
  Serial.begin(9600);           // Serial initialization
  delay(5000);                   // wait for sensor setup
  AutomaticModelSetup();        //Automatic measurement model set
}

void loop()
{
  AutomaticMeasurement();
  delay(100);
}


void AutomaticModelSetup(void)
{
  pinMode(URECHO, INPUT);
  for (int i = 0; i < 4; i++)
  {
    Serial.write(AutomaticModelCmd[i]);// Sending Automatic measurement model command
  }
}


void AutomaticMeasurement(void)
{
  unsigned long DistanceMeasured = pulseIn(URECHO, LOW);
  if (DistanceMeasured >= 50000) // the reading is invalid.
  {
    Serial.print("Invalid");
  }
  else
  {
    Distance = DistanceMeasured / 50;       // every 50us low level stands for 1cm
    Serial.print("Distance=");
    Serial.print(Distance);
    Serial.println("cm");
  }
}

结果

Arduino 板发送给串口上位机显示距离信息,波特率选择9600baud URM37V4.0_Serial.png

串口被动模式

串口被动测量模式一直存在,在第一或者第二模式下,通过串口发出的距离测量命令,串口将测量到的距离数据返回,命令中带的舵机旋转度参数使模块MOTO脚产生的舵机控制脉冲从而改变测量舵机的旋转度数。无论处于什么工作模式,我们都可以通过串口对超声波进行距离测量、温度测量、比较距离修改、自动测量时间间隔、串口工作方式(TTL或RS232,重启后生效)操作。 例如:

读取温度数据指令 0x11 0x00 0x00 0x11

读取距离数据指令 0x22 0x00 0x00 0x22

读取EEPROM数据指令 0x33 0x00 0x00 0x33

写入EEPROM数据指令 0x44 0x02 0x00 0x46

读取温度演示代码

    // # Editor     : roker
    // # Date       : 05.03.2018

    // # Product name: URM V5.0 ultrasonic sensor
    // # Product SKU : SEN0001
    // # Version     : 1.0

    // # Description:
    // # The sketch for using the URM37 Serial  mode from DFRobot
    // #   and writes the values to the serialport

    // # Connection:
    // #       Vcc (Arduino)      -> Pin 1 VCC (URM V5.0)
    // #       GND (Arduino)      -> Pin 2 GND (URM V5.0)
    // #       Pin TX1 (Arduino)  -> Pin 8 RXD (URM V5.0)
    // #       Pin RX0 (Arduino)  -> Pin 9 TXD (URM V5.0)
    // # Working Mode: Serial  Mode.

    uint8_t EnTempCmd[4] = {0x11, 0x00, 0x00, 0x11}; // temperature measure command
    uint8_t TempData[4];
    unsigned int TempValue = 0;
    void setup()
    {
      Serial.begin(9600);
      delay(100);
      Serial.println("Init the sensor");
    }
    void loop()
    {
      SerialCmd();
      delay(200);
    }
    void SerialCmd()
    {
      int i;
      for (i = 0; i < 4; i++) {
        Serial.write(EnTempCmd[i]);
      }
      while (Serial.available() > 0)  // if received data
      {
        for (i = 0; i < 4; i++) {
          TempData[i] = Serial.read();
        }
        TempValue = TempData[1] << 8;
        TempValue = TempValue + TempData[2];
        Serial.print("temperature : ");
        Serial.print(TempValue, DEC);
        Serial.println(" oC");
      }
    }

结果

波特率选择9600baud,串口接受到温度,这个温度被放大了10倍,现在的温度为28.1摄氏度。 URM37V4.0_Serial1.png

Mind+(基于Scratch3.0)图形化编程

该模式仅需连接传感器上“+5V”、“GND”、“ECHO”、“COMP/Trig”四根线到开发板Uno上。 1、下载及安装软件。下载地址:https://www.mindplus.cc 详细教程:Mind+基础wiki教程-软件下载安装 2、切换到“上传模式”。 详细教程:Mind+基础wiki教程-上传模式编程流程 3、“扩展”中选择“主控板”中的“Arduino Uno”,“传感器”中加载“超声波测距传感器”。 详细教程:Mind+基础wiki教程-加载扩展库流程 4、进行编程,程序如下图: 5、菜单“连接设备”,“上传到设备” 6、程序上传完毕后,打开串口即可看到数据输出。详细教程:Mind+基础wiki教程-串口打印

结果

打开串口监视器,将波特率调整到9600,移动物体靠近传感器接受口,可以在串口监视器观察到物体到传感器的具体距离值。

探测角度及灵敏度说明

超声波传感器的物理特性决定了其实际具有不规则的探测区域,因此超声波测距传感器的探测角度难以被准确的定义。我们分别使用了2种参考目标障碍物对多样本产品进行了测试,对应目标的参照检测区域如下图示:

疑难解答

  1. 如果用户在和Arduino连接的时候,出现无法使用它时,请首先检查一下当前串口电平的模式,有可能出现在使用TTL电平时,而我们的模块却工作在RS232电平。
  2. 由于超声波在空气中衰减很厉害(与距离d的平方成反比),同时声音在障碍物表面反射时会受很多因素 (如障碍物形状、方向、质地)的影响,因此超声波测量的距离是有限的。
  3. 本系统远距离测试被测物是一面墙,近距离测试被测物可以是一支笔。根据使用环境和被测物的质地的不同,将可能造成测量结果与提供的数据不符。差距不大,属于正常情况。
  4. 上述所提及的舵机为市面上普通型号舵机,可以旋转180度。如果使用特殊舵机,可能控制时序就有所不同,请使用者注意(舵机旋转角度参考表内数据参考使用)。
  5. 此款传感器的量程大,灵敏度很高,注意调整传感器的安装位置,避免测到地面等导致不良数据的情况。
  6. 如果遇到技术问题,请登陆到我们的售后论坛留言,我们会尽快解答您的问题。

更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖!

更多

DFshopping_car1.png DFRobot商城购买链接