mm resoultion reading from Maxbotix HRLV

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
rjdelbulk
 
Posts: 11
Joined: Sat Jan 04, 2014 11:54 am

mm resoultion reading from Maxbotix HRLV

Post by rjdelbulk »

Does anyone out there know how to get a mm resolution reading from a HRLV unit ?
I found this thread:
http://forum.arduino.cc/index.php?topic=114808.0

... and am using the included code for serial input, however this returns cm resolution.
The documentation for the HRLV units indicate mm resolution is possible, but I have been unable to find an example out there.

Any help greatly appreciated.

Here is the code from the thread I reference above:

Code: Select all

/* test function to Parse data from MaxSonar serial data
 and return integer */

#include <SoftwareSerial.h>

#define txPin 3                                            //define pins used for software serial for sonar
#define rxPin 2

SoftwareSerial sonarSerial(rxPin, txPin, true);            //define serial port for recieving data, output from maxSonar is inverted requiring true to be set.



boolean stringComplete = false;

void setup()
{
  Serial.begin(9600);                                      //start serial port for display
  sonarSerial.begin(9600);                                 //start serial port for maxSonar
  delay(500);                                              //wait for everything to initialize

}

void loop()
{
  int range = EZread();
  if(stringComplete)
  {
    stringComplete = false;                                //reset sringComplete ready for next reading

    Serial.print("Range ");
    Serial.println(range);
    //delay(500);                                          //delay for debugging
  }
}


int EZread() 
{
  int result;
  char inData[4];                                          //char array to read data into
  int index = 0;


  sonarSerial.flush();                                     // Clear cache ready for next reading

  while (stringComplete == false) {
    //Serial.print("reading ");    //debug line

      if (sonarSerial.available())
    {
      char rByte = sonarSerial.read();                     //read serial input for "R" to mark start of data
      if(rByte == 'R')
      {
        //Serial.println("rByte set");
        while (index < 3)                                  //read next three character for range from sensor
        {
          if (sonarSerial.available())
          {
            inData[index] = sonarSerial.read(); 
            //Serial.println(inData[index]);               //Debug line

            index++;                                       // Increment where to write next
          }  
        }
        inData[index] = 0x00;                              //add a padding byte at end for atoi() function
      }

      rByte = 0;                                           //reset the rByte ready for next reading

      index = 0;                                           // Reset index ready for next reading
      stringComplete = true;                               // Set completion of read to true
      result = atoi(inData);                               // Changes string data into an integer for use
    }
  }

  return result;
}

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: mm resoultion reading from Maxbotix HRLV

Post by adafruit_support_mike »

The code doesn't seem to match the information in the datasheet: http://www.maxbotix.com/documents/HRLV- ... asheet.pdf

According to the datasheet, the serial output (on pin 5) is an 'R' followed by four ASCII characters which represent the range in millimeters, followed by an ASCII 13 (a carriage return). The code looks for the 'R' then reads three characters. Losing that last digit will cost you one order of magnitude in resolution.. from mm to cm.

User avatar
rjdelbulk
 
Posts: 11
Joined: Sat Jan 04, 2014 11:54 am

Re: mm resoultion reading from Maxbotix HRLV

Post by rjdelbulk »

Ahhhh..yes. Thanks!
This code was originally written (i think) for the LV-xx series as opposed to the HRLV-xx series.

So first I simply changed:

Code: Select all

while (index < 3)                                  //read next three character for range from sensor
to:

Code: Select all

while (index < 4)                                  //read next three character for range from sensor
And it seems to work.

But then I noticed this line:

Code: Select all

char inData[4];                                          //char array to read data into
Seems like that need to be changed to :

Code: Select all

char inData[5];                                          //char array to read data into
Which I did.
They both seem to return the same results (with or without the second change).

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: mm resoultion reading from Maxbotix HRLV

Post by adafruit_support_mike »

Do use a five-character array.

C indicates the end of a string by setting the last byte to zero. It's called a 'sentinel' value. You need to explicitly allocate space for it though. The routines that copy strings from one chunk of memory to another usually don't know how large your buffer is, they just keep copying until they're told to stop. If a routine goes past the end of the space you've allocated, you get what's called a 'buffer overrun error', which can cause all sorts of trouble.

The problem is that the next byte past the buffer you've allocated might be used by some other variable. If your code looks like this:

Code: Select all

char *buffer[ 4 ];
const uint16_t importantValue = 0xABCD;
the actual bytes stored memory might look like this:

Code: Select all

0: [ 0x00 ]  // buffer[ 0 ]
1: [ 0x00 ]  // buffer[ 1 ]
2: [ 0x00 ]  // buffer[ 2 ]
3: [ 0x00 ]  // buffer[ 3 ]
4: [ 0xAB ]  // top half of importantValue
5: [ 0xCD ]  // bottom half of importantValue
If you then call a routine that wants to write the string "1234" into 'buffer', the memory will end up looking like this:

Code: Select all

0: [ 0x31 ]  // buffer[ 0 ]  (ASCII for '1')
1: [ 0x32 ]  // buffer[ 1 ]  (ASCII for '2')
2: [ 0x33 ]  // buffer[ 2 ]  (ASCII for '3')
3: [ 0x34 ]  // buffer[ 3 ]  (ASCII for '4')
4: [ 0x00 ]  // string sentinel, (the code still thinks this the top half of 'importantValue')
5: [ 0xCD ]  // bottom half of importantValue
So now all your code that uses 'importantValue' suddenly sees 0x00CD rather than 0xABCD, even though your code says it should be impossible to change that value.

User avatar
rjdelbulk
 
Posts: 11
Joined: Sat Jan 04, 2014 11:54 am

Re: mm resoultion reading from Maxbotix HRLV

Post by rjdelbulk »

Thanks Mike,
That is a really helpful and informative reply for a newbie like myself.
I certainly qualify as a 'hack' at this point, but posts like yours help in gaining an actual understanding.

One more quick question... What is the Tx Pin 3 (transmit/trigger I assume) pin used for in this example?
I did not connect anything to pin 3 yet it appears to work fine.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: mm resoultion reading from Maxbotix HRLV

Post by adafruit_support_mike »

TX stands for 'transmit' and RX stands for 'receive'. Together, the two signals make up a 'serial connection' or 'UART'.

In this case, you aren't using the TX line, but it's easier to describe what's happening as 'one half of a serial connection' than to handle the signals some other way.

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Arduino products from Adafruit”