MaxBotics HRXL-MaxSonar-WR 7380 working code, mm-resolution ultrasonic ranging

The output is clean digital data, no analog calibration necessary. Handy for my research group, thought it might help others as well.

/*  
    HRXL MaxSonar WR TTY serial communication example sketch
    Ultrasonic rangefinding

    Original bits by Logan Park, Ph.D., in honor of his astonishingly beautiful wife.
    
    Pretty much everything else is...
    based on: http://www.maxbotix.com/documents/HRXL-MaxSonar-WR_Datasheet.pdf
    and on the Arduino Mega 2560 ADK: http://arduino.cc/en/Main/ArduinoBoardADK
    and on this handy ASCII chart: http://www.csgnetwork.com/asciiset.html
    and a bunch of posts on the Arduino forums.

    1. Connect pin 5 (tty/serial) of the ranging unit to pin 19 (Serial1 RX) on the Mega 2560. 
    2. Connect pin 6 of the ranging unit to any 5V supply on the Mega 2560.
    3. Connect pin 7 of the ranging unit to any GND on the Mega 2560.
 */


int current_range_reading = -99;

void setup() 
{
  Serial.begin(115200); // Set your computer's serial terminal baud rate to this.
  Serial1.begin(9600); // This is what the MaxBotics TTY sonar output needs.
}

void loop() 
{
  if (Serial1.available() > 5)  // Then at least one complete range, 6 characters long, is stored in the RX buffer.
  {
    int inByte = Serial1.read(); // Examine the first stored character and decide what to do.

    if( inByte == 82 ) // "R" character 
    {
      int thousands = (Serial1.read() - '0') * 1000; // Take and convert each range digit to human-readable integer format.
      int hundreds = (Serial1.read() - '0') * 100;
      int tens = (Serial1.read() - '0') * 10;
      int units = (Serial1.read() - '0') * 1;
      int cr = Serial1.read(); // Don't do anything with this, just clear it out of the buffer with the rest.
      
      // Assemble the digits into the range integer.
      current_range_reading = thousands + hundreds + tens + units;
      if(current_range_reading == 300) //This is the minimum reading for the HRXL MaxSonar WR 7380, not the actual distance
      {
        Serial.println("too close!");
      }
      else if(current_range_reading == 5000) //This is the max reading for the HRXL MaxSonar WR 7380, not the actual distance
      {
        Serial.println("too far!");
      }
      else
      {
        Serial.print("Range (mm): "); 
        Serial.println(String(current_range_reading));
      } 
    }
    else if( inByte == 13 ) // Carriage Return  character, oops! 
    {
      //Serial.println();
    }
    else if( inByte == -1 ) // Just in case!  This shouldn't happen if Serial1.available() returns true.
    {
      Serial.println("RX buffer empty, wth?");
      return;
    }
  }
  else
  {
    //Serial.print("RX buffer not ready");  // This is very spammy, uncomment at your own risk.
  }
}

Thank you for sharing,,

some minor points to improve your code

    if( inByte == 'R' )  // you can use that char to compare directly 
...
      if (current_range_reading <= 300) //This will catch other faulty readings too, they may not happen but makes the sketch more robust
      {
        Serial.println("too close!");
      }
      else if(current_range_reading >= 5000) //idem
      {
        Serial.println("too far!");
      }
      else
      {
        Serial.print("Range (mm): "); 
        Serial.println(current_range_reading);     // no need to convert to string
      }

The code assumes that when you have 6 or more chars in the buffer that it is a nice "Rxxxx\n", but what if the Arduino during startup missed the first (or two) char?

You need to adjust your code to wait until there is a 'R', and then wait for 5 chars etc.

Do you have a link to the datasheet of the sensor? People might be interested in that too.

I think you meant TTL. Second, that honorary mention seems...odd. Anyway, here's the whole thing:

/*  
    HRXL MaxSonar WR TTL serial communication example sketch
    Ultrasonic rangefinding

    Original bits by Logan Park, Ph.D., in honor of his astonishingly beautiful wife.
    
    Pretty much everything else is...
    based on: http://www.maxbotix.com/documents/HRXL-MaxSonar-WR_Datasheet.pdf
    and on the Arduino Mega 2560 ADK: http://arduino.cc/en/Main/ArduinoBoardADK
    and on this handy ASCII chart: http://www.csgnetwork.com/asciiset.html
    and a bunch of posts on the Arduino forums.

    1. Connect pin 5 (tty/serial) of the ranging unit to pin 19 (Serial1 RX) on the Mega 2560. 
    2. Connect pin 6 of the ranging unit to any 5V supply on the Mega 2560.
    3. Connect pin 7 of the ranging unit to any GND on the Mega 2560.
*/


int current_range_reading = -99;

void setup(){
  Serial.begin(115200); // IMPORTANT: Set your serial monitor to this.
  Serial1.begin(9600); // This is the baud rate needed for MaxBotics TTL sonar.
}

void loop(){
  if (Serial1.available() > 5)  // Then at least one complete range, 6 characters long, is stored in the RX buffer.
  {
    int inByte = Serial1.read(); // Examine the first stored character and decide what to do.

    if(inByte == 'R')
    {
      int thousands = (Serial1.read() - '0') * 1000; // Take and convert each range digit to human-readable integer format.
      int hundreds = (Serial1.read() - '0') * 100;
      int tens = (Serial1.read() - '0') * 10;
      int units = (Serial1.read() - '0') * 1;
      int cr = Serial1.read(); // Don't do anything with this, just clear it out of the buffer with the rest.
      
      // Assemble the digits into the range integer.
      current_range_reading = thousands + hundreds + tens + units;
      if(current_range_reading <= 300) //This is the minimum reading for the HRXL MaxSonar WR 7380, not the actual distance
        Serial.println("too close!");
      else if(current_range_reading >= 5000) //This is the max reading for the HRXL MaxSonar WR 7380, not the actual distance
        Serial.println("too far!");
      else
      {
        Serial.print("Range (mm): "); 
        Serial.println(current_range_reading);
      } 
    }
    else if( inByte == "\r" ) // Carriage Return  character, oops! 
    {
      //Serial.println();
    }
    else if( inByte == -1 ) // Just in case!  This shouldn't happen if Serial1.available() returns true.
    {
      Serial.println("RX buffer empty, wth?");
      return;
    }
  }
}