I recently got a DFRobot URM37 sensor and created a class to use it (going in library once solid). Your feedback is greatly appreciated.
Link to sensor:
http://www.dfrobot.com/index.php?route=product/search&filter_name=urm37
Notes about class / library...
This is BETA 1 of the class/library but tested on 328 and mega board. There is duplicate code in there to handle mega .. but if your board is not a mega .. it won't even compile in so it won't use any extra footprint.
In the process up updating code from www.yerobot.com, I removed the usage of extra pins outside the serial pins and made it work with Serial1/2/3 in the mega boards too (nice because you can upload without disconnecting the sensor from tx/rx).
In it's simplest form .. the usage is 123.
- Define a URM37Simple instance (i.e. URM37Simple sensor1);
- in setup() - call:
sensor1.initSetup(); - in the loop, get the distance using:
sensor1.getDistance()
/* Ultrasound Sensor Class
*- Based on code from www.yerobot.com
* - edits include removing the power and enable from pons - directly to VCC grid
* - Removed some of the variables to save memory, including hard coding the commands to send
* - Be sure to change the jumper on the URM37 to TTL ***
*------------------
To Use:
Create an instance of the URM37Simple class
In setup - call <YOURNAME>.initSetup()
In loop - call <YOURNAME>.getDistance() to force a reading on distance - return value is distance in cm
*------------------
* URM V3.2 ultrasonic sensor TTL connection with Arduino
* Reads values (0-300) from an ultrasound sensor (3m sensor)
* VCC 5v -> Pin 1 VCC (URM V3.2)
* GND (Arduino) -> Pin 2 GND (URM V3.2)
* VCC 5v -> Pin 7 (URM V3.2)
* Pin 0 (Arduino) -> Pin 9 (URM V3.2)
* Pin 1 (Arduino) -> Pin 8 (URM V3.2)
*/
#define SERIAL_MODE_DEFAULT 0
#define SERIAL_MODE_MEGA_1 1
#define SERIAL_MODE_MEGA_2 2
#define SERIAL_MODE_MEGA_3 3
class URM37Simple {
public:
byte serialMode;
int distance;
URM37Simple(byte theSerialMode) {
serialMode = theSerialMode;
};
URM37Simple() {
serialMode = SERIAL_MODE_DEFAULT;
};
~URM37Simple() {
};
int getDistance(){
//-- if a mega - then chose the serial port in use
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560)
switch (serialMode){
case SERIAL_MODE_DEFAULT : return getDistanceFromDefault();
case SERIAL_MODE_MEGA_1 : return getDistanceFrom1();
case SERIAL_MODE_MEGA_2 : return getDistanceFrom2();
case SERIAL_MODE_MEGA_3 : return getDistanceFrom3();
}
//-- should never happen - but just in case return default;
return getDistanceFromDefault();
#else
//-- Not a mega so no computation required in this compile
return getDistanceFromDefault();
#endif
}
int getDistanceFromDefault(){
Serial.print(0x22,BYTE);
Serial.print(0x0,BYTE);
Serial.print(0x0,BYTE);
Serial.print(0x22,BYTE);
while(true)
{
if(Serial.available()>3)
{
int header=Serial.read(); //0x22
int highbyte=Serial.read();
int lowbyte=Serial.read();
int sum=Serial.read();//sum
if(highbyte==255)
{
distance=0; //if highbyte =255 , the reading is invalid.
}
else
{
distance = highbyte*255+lowbyte;
}
return distance;
}
delayMicroseconds(10);
}
}
//--- only if this is a mega do we need these functions
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560)
int getDistanceFrom1(){
Serial1.print(0x22,BYTE);
Serial1.print(0x0,BYTE);
Serial1.print(0x0,BYTE);
Serial1.print(0x22,BYTE);
while(true)
{
if(Serial1.available()>3)
{
int header=Serial1.read(); //0x22
int highbyte=Serial1.read();
int lowbyte=Serial1.read();
int sum=Serial1.read();//sum
if(highbyte==255)
{
distance=0; //if highbyte =255 , the reading is invalid.
}
else
{
distance = highbyte*255+lowbyte;
}
return distance;
}
delayMicroseconds(10);
}
}
int getDistanceFrom2(){
Serial2.print(0x22,BYTE);
Serial2.print(0x0,BYTE);
Serial2.print(0x0,BYTE);
Serial2.print(0x22,BYTE);
while(true)
{
if(Serial2.available()>3)
{
int header=Serial2.read(); //0x22
int highbyte=Serial2.read();
int lowbyte=Serial2.read();
int sum=Serial2.read();//sum
if(highbyte==255)
{
distance=0; //if highbyte =255 , the reading is invalid.
}
else
{
distance = highbyte*255+lowbyte;
}
return distance;
}
delayMicroseconds(10);
}
}
int getDistanceFrom3(){
Serial3.print(0x22,BYTE);
Serial3.print(0x0,BYTE);
Serial3.print(0x0,BYTE);
Serial3.print(0x22,BYTE);
while(true)
{
if(Serial3.available()>3)
{
int header=Serial3.read(); //0x22
int highbyte=Serial3.read();
int lowbyte=Serial3.read();
int sum=Serial3.read();//sum
if(highbyte==255)
{
distance=0; //if highbyte =255 , the reading is invalid.
}
else
{
distance = highbyte*255+lowbyte;
}
return distance;
}
delayMicroseconds(10);
}
}
#endif
void initSetup(){
distance = 0;
switch (serialMode){
case 0 :
Serial.begin(9600);
break;
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560)
// serial ports with with Arduino Mega only
case 1 :
Serial1.begin(9600);
break;
case 2 :
Serial2.begin(9600);
break;
case 3 :
Serial3.begin(9600);
break;
#endif
}
delay(200); //Give sensor some time to start up --Added By crystal from Singapo, Thanks Crystal.
}
};
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560)
URM37Simple sensor1 = URM37Simple(1);
#else
URM37Simple sensor1;
#endif
void setup() {
sensor1.initSetup();
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560)
if (sensor1.serialMode > 0 ){
//-- if we are not using default serial - then init so we can talk via the monitor
Serial.begin(9600);
}
#endif
}
void loop()
{
Serial.println(sensor1.getDistance());
delay(50);
}