Pages: [1]   Go Down
Author Topic: Class to control the URM37 via serial  (Read 1186 times)
0 Members and 1 Guest are viewing this topic.
Florida
Offline Offline
Sr. Member
****
Karma: 4
Posts: 431
hookedup!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
1) Define a URM37Simple instance (i.e.   URM37Simple sensor1);
2) in setup() - call:
  sensor1.initSetup();
3) in the loop, get the distance using:
sensor1.getDistance()

Code:
/* 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);
}


Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8821
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The Arduino convention seems to be to call the initialization method ".begin()".  You might want to use that instead of ".initSetup()".
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Florida
Offline Offline
Sr. Member
****
Karma: 4
Posts: 431
hookedup!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the tip, I'll update that if/when moved to library form. 

I created a simple library but feel I should use it some before posting. 

I really do not like the duplicate functions.   I created this in a couple hours to create an interactive light bar.  I'll work out how to reference a pointer to the correct serial instance or at least break out duplicate function into a single routine before posting as a library.

Other feedback welcome.


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi marklar,

I am newbie in programming the Arduino. My knowledge about electronics is quite good but it is a long time ago when I do the last things in this field. So I have to learn some things new. Please excuse for my newbie questions.

I have an Arduion MEGA 2560 an the UMR37 V3.2 and I want to read the distance permanently. I am a little bit confused about the switch between TTL and serial. I thought that for using the MEGA I could switch the URM37 to serial an connect direct with the serial-TX/RX from the MEGA. But in the code is a note:

"* - Be sure to change the jumper on the URM37 to TTL ***"

Is this wright?

Thank you
Regards,
Gerd
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can you post a usage example?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,
I am new on this forum and don' t have an idea how to post my qestion, so
I will do it this way,
I have a sketh downloaded from www.jo3ri.be. its a tank level measurement.
The program works fine with a urm37 connected. My problem is that i want to use
the urm37 as a sensor with cable, appox 7m long. This gives probles to the program.
Is there a way to use a cable with a lenght of 7 m connected to an arduino
The cable i use 4x0,75 mm shielded.

Thanx peter 
Logged

Pages: [1]   Go Up
Jump to: