Local vs Global Var problem

Hello,
I've been toying around with this code obviously getting different sensors, a joystick and an LCD working and all playing nice together which is why some of it is commented out currently. The main block of code works properly and does not crash. However when I move the variable block of code into the loop function I get random crashes and the output to my LCD locks up and I have to restart the arduino (mega 2560).

Any clue as to why? I have a couple of other things I can do to the code to tidy it up, my whole reason for this post is to ask why it works to just define the variables once in the global section of code but I get some hangs when I put it in the loop. Is putting it in the loop a bad idea to begin with? Should I just be making functions to get this information for me and have it be returned to a working variable?

Any help would be awesome and thank you!

-Tweed

Variable block of code:

String range;
String a_x, a_y, a_z;
int x, y, z;
  
int joystick_x, joystick_y;
String j_x, j_y;

Main code:

#include "ulcd_144.h"
#include <Wire.h>
#include <ADXL345.h>

#define RANGE_FINDER_PIN      A0

#define JOYSTICK_HORZ_PIN     A8
#define JOYSTICK_VERT_PIN     A9

ADXL345 adxl;

String range;
String a_x, a_y, a_z;
int x, y, z;
  
int joystick_x, joystick_y;
String j_x, j_y;


void setup() {

  Serial2.begin(115200);  //set up serial port for lcd
  delay(500); //this delay is necessary to let the LCD start up
  init_lcd();  //initialize lcd
  init_motor_driver();  //initialize motor driver
  
  pinMode(RANGE_FINDER_PIN, INPUT);
  
  pinMode(JOYSTICK_HORZ_PIN, INPUT);
  pinMode(JOYSTICK_VERT_PIN, INPUT);
  
  /*
  //accelerometer setup code
  adxl.powerOn();
  
  adxl.setActivityThreshold(75);
  adxl.setInactivityThreshold(75);
  adxl.setTimeInactivity(10);
  
  adxl.setActivityX(1);
  adxl.setActivityY(1);
  adxl.setActivityZ(1);  
  
  adxl.setTapDetectionOnX(0);
  adxl.setTapDetectionOnY(0);  
  adxl.setTapDetectionOnZ(0);
  
  adxl.setTapThreshold(50);
  adxl.setTapDuration(15);
  adxl.setDoubleTapLatency(80);
  adxl.setDoubleTapWindow(200);
  
  adxl.setFreeFallThreshold(7);
  adxl.setFreeFallDuration(45);
  
  //adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT,  ADXL345_INT1_PIN );
  //adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT,  ADXL345_INT1_PIN );
  adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT,  ADXL345_INT1_PIN );
  //adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT,   ADXL345_INT1_PIN );
  //adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT,  ADXL345_INT1_PIN );
  
  //set interrupt actions
  //adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1);
  //adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1);
  adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT, 1);
  //adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT,  1);
  //adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1);
  */
 
}

void loop() {

 
  //adxl.readAccel(&x, &y, &z);
  
  range = String(get_range(RANGE_FINDER_PIN), DEC);
  
  //display range
  lcd_write_text("Range:     ", 1, 0, 0xFF, 0xFF, 0, 0);  
  lcd_write_text(range, 1, 0, 0xFF, 0xFF, 7, 0);  
  
   /*
   //display accelerometer readings
  a_x = String(x);
  a_y = String(y);
  a_z = String(z);
  lcd_write_text("x:                ", 1, 0, 0xFF, 0xFF, 0, 1);
  lcd_write_text(a_x, 1, 0, 0xFF, 0xFF, 3, 1);  
  lcd_write_text("y:                ", 1, 0, 0xFF, 0xFF, 0, 2);
  lcd_write_text(a_y, 1, 0, 0xFF, 0xFF, 3, 2);  
  lcd_write_text("z:                ", 1, 0, 0xFF, 0xFF, 0, 3);
  lcd_write_text(a_z, 1, 0, 0xFF, 0xFF, 3, 3);  
  */
  
  //display joystick values
  joystick_x = analogRead(JOYSTICK_HORZ_PIN);
  joystick_y = analogRead(JOYSTICK_VERT_PIN);
  
  j_x = String(joystick_x, DEC);
  j_y = String(joystick_y, DEC);
  
  lcd_write_text("j_x:                ", 1, 0, 0xFF, 0xFF, 0, 6);
  lcd_write_text(j_x, 1, 0, 0xFF, 0xFF, 5, 6);  
  lcd_write_text("j_y:                ", 1, 0, 0xFF, 0xFF, 0, 7);
  lcd_write_text(j_y, 1, 0, 0xFF, 0xFF, 5, 7);  


}  


int get_range(int range_pin) {
  int range;
  range = analogRead(range_pin) * 0.496;
  return range;
}

void lcd_write_text(String text, byte mode, int size, byte color_msb, byte color_lsb, byte x, byte y) {

  int i = 0;
  
  //set opaque (0x01) or transparent (0x00)
  Serial2.write(LCD_SET_TRANSPARENT);
  if (mode == 0){
    Serial2.write(byte(LCD_FONT_TRANSPARENT));
  }
  else
  {
    Serial2.write(byte(LCD_FONT_OPAQUE));
  }
  lcd_get_reply(); 
  delay(10);

  //set location x,y
  //set color(0xFFFF), 2 bytes
  Serial2.write(LCD_DRAW_TEXT_STRING);
  Serial2.write(byte(x));
  Serial2.write(byte(y));
  switch (size){
    case 0:
      Serial2.write(byte(LCD_FONT_SIZE_SMALL));
      break;
    case 1:
      Serial2.write(byte(LCD_FONT_SIZE_MEDIUM));
      break;
    case 2:
      Serial2.write(byte(LCD_FONT_SIZE_LARGE));
      break;
    default:
      Serial2.write(byte(LCD_FONT_SIZE_SMALL));
  }
  
  //set color, two bytes (16 bit color) sent seperately
  Serial2.write(byte(color_msb));
  Serial2.write(byte(color_lsb));
  
  //output text
  while(i < text.length()){
    Serial2.write(text.charAt(i));
    i++;
  }

  //send termination byte
  Serial2.write(byte(LCD_TERMINATION));
  lcd_get_reply();
}

byte lcd_get_reply(){
  byte response = LCD_ACK; //ACK
  while (!Serial2.available()){
    delayMicroseconds(150);
  }
  response = Serial2.read();
  delay(10);
  return response;
}

void init_lcd(){
  Serial2.write(0x55);  //Auto-Baud Signal
  delay(100);
}

void init_motor_driver(){

  // Initialize Motor Driver Serial Port (1)
  Serial1.begin(115200);
  
  delay(1000);
  // Set motor speed to 0
  Serial1.println("1F0");
  delay(10);
  Serial1.println("2F0");

}

void drive_forward(){
  
  Serial1.println("1F9");
  Serial1.println("2F9");
  
}

void drive_reverse(){
  
  Serial1.println("1R9");
  Serial1.println("2R9");
  
}

void drive_turn_right(){
  
  Serial1.println("1F9");
  Serial1.println("2R9");

}

void drive_turn_left(){
  
  Serial1.println("1R9");
  Serial1.println("2F9");

}

void drive_stop(){
  
  Serial1.println("1F0");
  Serial1.println("2F0");
  
}

This would be absolutely thrashing your memory.

a_x = String(x);
  a_y = String(y);
  a_z = String(z);

Also, when they are local vars, they are destroyed when loop returns, and re-created when loop is re-entered.

Using a static sized buffer of characters will improve performance and might solve your crash.
If you need persistent data, use global or static local variables.

Thank you very much for your help.

-Tweed