0°

(四)URM37V4.0超声波测距传感器—Arduino超声波传感器

外观简介产品参数技术说明引脚说明 URM37 V4.0模块正面管脚使用教程用户购买到URM37 V4.0模块后,那么恭喜你,你获得了史上最强的超声波测距模块,功能强大到超乎你的想象,首先我们要了解这个模块的基本功能,测距的模式有三种:

外观

Arduino超声波传感器-URM37V4.0超声波测距传感器

简介

  • URM37 V3.2上已经很好的实现了超声波开关量、串口(TTL和RS232电平可选)、脉冲输出功能、模块还可以控制一个舵机的旋转组成一个空间超声波扫描仪。为了方便客户使用模块,在出厂时可以根据客户需要配置其相应的参数,也可以根据客户具体需求定制软件,使他成为一个专用的模块。
  • 在此基础上我们对功能进行了升级。
  • 当前版本URM37 V4.0具有更好的智能功能,机械尺寸与引脚接口以及通信命令兼容V3.2,在V3.2基础上做了如下更改:
  • 串口电平选择由原来的跳针方式改为通过按键设置,用户可以轻松的选择TTL电平输出或是RS232电平输出(重启之后模式生效)。
  • 修改了测距算法,使测量盲区减小,精度提高。
  • 具有模拟电压输出功能,电压和测量距离正比。
  • 宽电压支持+3.3V-5.0V。
  • 具有电源接反保护功能。
  • 自动测量时间间隔可修改。
  • 修改舵机控制角度为0-180,兼容市面大部分舵机。
  • 测量时长为100ms。

产品参数

  • 工作电源:+3.3V~+5.0V
  • 工作电流:<20mA
  • 工作温度范围 :-10℃~+70℃
  • 超声波距离测量:
  • 最大测量距离―500cm
  • 最小测量距离―5cm
  • 分辨率-1cm
  • 精度-1%
  • 模块尺寸22mm × 51 mm
  • 模块重量:约25g
  • 超声波一次测量时间为100ms

技术说明

  • 由于使用了更好的测距处理方法,使测量距离更远更稳定,在测量上完全兼容V3.2,但是我们可以做到在0.3-3M的距离上稳定2mm的精度,如果有需要可以和公司联系定制。
  • 模块使用RS232串口通讯可靠性更高,同时可以通过电脑串口采集数据,编写通讯程序非常的便捷。
  • 串口电平工作方式是TTL还是RS232选择方式为按键设置或者软件设置(重启之后模式生效)。
  • 模块可以通过脉宽输出的方式将测量数据输出,这样使模块使用更简单。
  • 模块可以预先设定一个比较值,在自动测量模式下,测量距离小于这个值后管脚COMP/Trig输出一个低电平,这样模块能够方便的作为一个超声波接近开关使用。
  • 模块提供一个舵机控制功能,在非自动测量模式下,可以和一个舵机组组成一个180度测量组件用于机器人扫描0~180度范围障碍物。
  • 模块内带温度补偿电路提高测量的精度。
  • 模块内带123字节内部EEPROM,可以用于系统记录一些调电不丢失的系统参数。
  • 模块内带一个温度测量部件,可以通过通讯口读出分辨率0.1摄氏度的环境温度数据。
  • 具有电源接反保护功能。
  • 自动测量时间间隔可修改。
  • 具有模拟电压输出功能,电压和测量距离成正比。

引脚说明

Arduino超声波传感器-URM37V4.0超声波测距传感器

URM37 V4.0模块正面管脚

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

使用教程

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

模式/参数设置方法

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

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

EEPROM各地址配置字节含义

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

Arduino超声波传感器-URM37V4.0超声波测距传感器

按键选择串口电平模式

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

Arduino超声波传感器-URM37V4.0超声波测距传感器

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

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

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

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

上位机软件选择测量模式

Arduino超声波传感器-URM37V4.0超声波测距传感器

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

Arduino超声波传感器-URM37V4.0超声波测距传感器

  • 软件的使用极其简单:
  • 先保证电脑上没有其他软件占用串口,然后运行伴侣,先选择COM口,再点击“打开串口”,右边窗口选择探测功能,选择“16位温度读取”可以进行温度测量,选择“16位距离读取”可以进行距离测量,“控制指令”窗口同时显示将要发送的指令,点击“启动功能”便完成操作。此时,“返回数据”窗口中间两位显示的是16进制数据,软件下方状态栏内也会显示出温度及距离的10进制数据。该软件使用方便、数据直观。
  • 如果你还购买了我们的专用舵机,便可以使用舵机控制部分。如图所示,在“舵机角度”窗口内选择要执行的角度,同时在选择“16位距离读取”,然后点击“启动功能”,舵机便旋转到相应的角度上,同时超声波测量该方向上障碍物的距离。由此URM37V4.0配合舵机就可以完成空间障碍物扫描功能。
  • 测量模式的切换通过给内部EEPROM地址0x02写入0xaa的数据即切换到自动测量模式。串口发送数据 0x44 0x02 0xaa 0xf0 .

Arduino超声波传感器-URM37V4.0超声波测距传感器

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

三种模式下的简单实验

  • PWM触发模式

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

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

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

Arduino超声波传感器-URM37V4.0超声波测距传感器

演示代码

// # Editor     : ZRH from DFRobot
// # Date       : 29.08.2014

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

// # Description:
// # The Sketch for scanning 180 degree area 3-500cm 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 V4.0)
// #       GND (Arduino)    -> Pin 2 GND (URM V4.0)
// #       Pin 3 (Arduino)  -> Pin 4 ECHO (URM V4.0)
// #       Pin 5 (Arduino)  -> Pin 6 COMP/TRIG (URM V4.0)
// #       Pin A0 (Arduino) -> Pin 7 DAC (URM V4.0)
// # Working Mode: PWM trigger pin  mode.

#define  Measure  1     //Mode select
int URECHO = 3;         // PWM Output 0-25000US,Every 50US represent 1cm
int URTRIG = 5;         // PWM 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 
  pinMode(URECHO, INPUT);                    // Sending Enable PWM mode command
  delay(500);
  Serial.println("Init the sensor");

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

void PWM_Mode()                              // a low pull on pin COMP/TRIG  triggering a sensor reading
{ 
  Serial.print("Distance Measured=");
  digitalWrite(URTRIG, LOW);
  digitalWrite(URTRIG, HIGH);               // reading Pin PWM will output pulses  
  if( Measure)
  {
    unsigned long LowLevelTime = pulseIn(URECHO, LOW) ;
    if(LowLevelTime>=30000)                 // the reading is invalid.
    {
      Serial.print("Invalid");
    }
    else{
    DistanceMeasured = LowLevelTime /50;   // every 50us low level stands for 1cm
    Serial.print(DistanceMeasured);
    Serial.println("cm");
  }

  }
  else {
    sensorValue = analogRead(sensorPin); 
    if(sensorValue<=10)                   // the reading is invalid.
    {
      Serial.print("Invalid");
    }
    else {
    sensorValue = sensorValue*0.718;      
    Serial.print(sensorValue);
    Serial.println("cm");
    }
  } 
}

结果

Arduino 板发送给串口上位机显示距离信息

Arduino超声波传感器-URM37V4.0超声波测距传感器

波特率选择9600

上面的代码中我们并没有严格要求检测到无效数据时的时间是50000us,我们只要是大于30000us(5.1米)的时间就可以了。

我们能够实现最基本的测量后,就可以更深入使用我们模块上的更多功能,比如上面的谈到的模拟电压输出功能。输出的电压和测量距离成正比6.8mV/cm,超出测量范围后输出电压为0,以及测量0-180度空间上的测量。将上面我们的样例代码中的#define Measure 1 改为#define Measure 0 就能够通过模拟电压读取出测量距离,在这里我们就省略配图了,之后我们就可以继续学习第二种模式了。

注意:PWM触发控制模式可以将多个模块数据线并联使用。

自动测量模式

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

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

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

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

Arduino超声波传感器-URM37V4.0超声波测距传感器

演示代码

// # Editor    :Zrh from DFRobot
// # Data      :29.08.2014
// # Product name:ultrasonic scanner 
// # 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 V4.0)
// #       GND (Arduino)      -> Pin 2 GND (URM V4.0)
// #       Pin 3 (Arduino)    -> Pin 4 ECHO (URM V4.0)
// #       Pin TX1 (Arduino)  -> Pin 8 RXD (URM V4.0)
// #       Pin RX0 (Arduino)  -> Pin 9 TXD (URM V4.0)
// # Working Mode: autonomous  mode.

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

unsigned int Distance=0;
uint8_t EnPwmCmd[4]={0x44,0x02,0xaa,0xf0};    // distance measure command
 
void setup(){                                 // Serial initialization
  Serial.begin(9600);                         // Sets the baud rate to 9600
  AutonomousMode_Setup();
}
 
void loop()
{
 AutonomousMode();
 delay(100);
}                      //PWM mode setup function
 
void AutonomousMode_Setup(){ 
  pinMode(URECHO, INPUT);                      // Sending Enable PWM mode command
  for(int i=0;i<4;i++){
      Serial.write(EnPwmCmd[i]);
   } 
}
void AutonomousMode(){                              
    unsigned long DistanceMeasured=pulseIn(URECHO,LOW);
    if(DistanceMeasured>=30000){              // 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 板发送给串口上位机显示距离信息

Arduino超声波传感器-URM37V4.0超声波测距传感器

波特率选择9600baud

串口被动模式

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

例如:

  • 读取温度数据指令 0x11 0x00 0x00 0x11
  • 读取距离数据指令 0x22 0x00 0x00 0x22
  • 读取EEPROM数据指令 0x33 0x00 0x00 0x33
  • 写入EEPROM数据指令 0x44 0x02 0x00 0x46

演示代码

// # Editor     : ZRH from DFRobot
// # Date       : 29.08.2014

// # Product name: URM V4.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 V4.0)
// #       GND (Arduino)      -> Pin 2 GND (URM V4.0)
// #       Pin TX1 (Arduino)  -> Pin 8 RXD (URM V4.0)
// #       Pin RX0 (Arduino)  -> Pin 9 TXD (URM V4.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)  //如果串口接收到任何数据
    {
       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");
    }
}

结果

串口接受到温度,这个温度被放大了10倍,现在的温度为28.1摄氏度。

Arduino超声波传感器-URM37V4.0超声波测距传感器

波特率选择9600baud

通讯协议

模块串口波特率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。

舵机旋转角度参考表:

Arduino超声波传感器-URM37V4.0超声波测距传感器

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

内部EEPROM读取指令

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

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

内部EEPROM写入指令

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

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

  • 0x00:比较距离低8位
  • 0x01:比较距离高8位
  • 0x02:测量模式(对模式寄存器写入0xaa自动测量模式,其他非0xaa数据都是PWM被动测量模式)
  • 0x03:串口工作模式(写入数据0x00为TTL电平,也是默认工作方式哦,写入数据0x01为RS232电平,当然如果用户对0x03这个地址写入其他数据,会被修改为默认方式TTL电平)
  • 0x04:自动测量时间间隔(默认最小间隔为25ms,写入数据为八位16进制,最小单位为ms,例如写入64,即为100ms)

疑难解答

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

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论