Display repeated twice and other problems

This is part of a larger program. For this part, an ultrasonic sensor's reading is taken and displayed on an LCD. As a test, I used the serial monitor. It works:

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

So the sensor is working, and it's wired correctly. Now for the LCD setup, I've tested other programs and they work. So the LCD is wired correctly. I think the issue is with the serial communication. But I don't know.

Problem1
Jumps to displaying "Range in mm:" when the switch is not high. So it should be at the home (welcome) screen, but instead jumps to the function. Why?

At the start it should display this:
Welcome.
Ready, make choice
by flipping switch
Flip back when done.

Problem2
"Range in mm:" is sometimes displayed twice. Every few seconds, the second (repeated part) disappears, and it looks like it's supposed to.

Problem3
In the serial monitor, the readings are incorrect. It may be reading something right, but it's so hard to tell because there is a huge (5-10 second) delay.

The LCD script is attached, and here:

/*
  Mega 2560 (Tools → Board)
*/
#include <LiquidCrystal.h>

const int contrast = 20;    // min. PWM value
const byte pinDigital = 44;   // Reads and displays range.
volatile int current_range_reading = -99;


LiquidCrystal lcd( 12, 13, 5, 4, 3, 7); // Arduino pins. Creates object.
    // LCD:GND,5V(RS=2 en=3 11 12 13 14) 16=GND

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.
                        // RX1 pin 19
// LCD code:
  pinMode(8,HIGH);  // LCD pin 15: backlight (anode)
  analogWrite(6,contrast); // PWM~ pins: 3,5,(6),9,10,11
  lcd.begin(20, 4);  // Creates LCD object.

// pinMode not needed for INPUT (default) operator
  pinMode(15, OUTPUT);
  pinMode(2, OUTPUT);
}


void loop() {
  delay(1500);          // For LCD screen to boot up.
  lcd.setCursor(0, 0);
  lcd.print("Welcome.");
  lcd.setCursor(0, 1);
  lcd.print("Ready, make choice");
  lcd.setCursor(0, 2);
  lcd.print("by flipping switch.");
  lcd.setCursor(0, 3);
  lcd.print("Flip back when done.");

// Analyze by flipping physical switch
  byte digitalSelection = digitalRead(pinDigital); // 44


// Analyze
  if(digitalSelection == HIGH)
    digitalR();
 
  else 
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    return;    
  } 
}    
//********************MAJOR**************************  FUNCTION DEFINITIONS
void digitalR(){
    lcd.clear();
    lcd.setCursor(0, 1);        // 2nd line
    lcd.print("Range in mm: ");
    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; // Convert each digit to human-readable integer format.
        int hundreds = (Serial1.read() - '0')*100;
        int tens = (Serial1.read() - '0')*10;
        int units = (Serial1.read() - '0');
        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!");
          lcd.setCursor(0, 1);        // 2nd line
          lcd.print("Range");
          lcd.setCursor(0, 2);
          lcd.print("             < 30 cm");
        }
        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!");
          lcd.setCursor(0, 1);        // 2nd line
          lcd.print("Range");
          lcd.setCursor(0, 2);
          lcd.print("             < 500cm");          
        }
        else
        {
          Serial.print("Range (mm): ");
          Serial.println(current_range_reading);
          lcd.print("Range in mm:");
          lcd.setCursor(0, 2);
          lcd.print("             ");          
        } 
      }
    else if( inByte == -1 ) // Just in case!  This shouldn't happen if Serial1.available() returns true.
    {
      Serial.println("RX buffer empty, wth?");
      return;
    }
  }
}

testRig.ino (3.32 KB)

From your first test reading the sensor without the lcd code all appears to work. Is that correct?

You have structured your sketch in such a way that it is constantly writing to the lcd. For example, you are writing a full welcome screen in the loop() and you may well be overwriting your expected results. In principle, you should write to the lcd only when there is a change to display.

Your problem #2 is probably because there are indeed two lcd print statements with exactly the repeated text.

Thanks. I put the welcome screen as else.

do you have a pullup resistor on the switch ?