Ultrasonic & GPS in one project

Hello, can anyone help me to solve my problem for my final project? My problem is I didn't get a consistent value for my ultrasonic sensor. Right now, I'm using 5 ultrasonic sensors and 1 shield GPS for my project. Hope you guys can help me. Thanks.
Here is my code:

#include <TinyGPS.h>
#include <SoftwareSerial.h>

SoftwareSerial GPS(52, 53);
TinyGPS shield;

float x2lat, x2lon;         // latitude and longitude to reach
float head, distance;        // calculation for gps
void gpshead();
float latitude, longitude, age; 

int trigger_left = A10; 
int echo_left = A11;

int trigger_front2 = A2;
int echo_front2 = A3;

int trigger_front1 = A4;
int echo_front1 = A5;

int trigger_front3 = A6;
int echo_front3 = A7;

int trigger_right = A8;
int echo_right = A9;

float frontSensor2, frontSensor1, frontSensor3, rightSensor, leftSensor;
long duration_front1, duration_front2, duration_front3, duration_left, duration_right;

void forward();
void Backward();
void Stop();
void rightturn();
void leftturn();

int pwm_motor_right = 6;              //pwm mottor right connect to AN2 at MDS10
int pwm_motor_left = 5;               //pwm mottor left connect to AN1 at MDS10
int dir_motor_right = 4;              //direction mottor right connect to DIG2 at MDS10
int dir_motor_left = 7;               //direction mottor left connect to DIG1 at MDS

int pwm_val = 0;



void setup() {

Serial.begin(9600);

GPS.begin(9600);

pinMode(trigger_front1, OUTPUT);
pinMode(echo_front1, INPUT);

pinMode(trigger_front2, OUTPUT);
pinMode(echo_front2, INPUT);

pinMode(trigger_front3, OUTPUT);
pinMode(echo_front3, INPUT);

pinMode(trigger_left, OUTPUT);
pinMode(echo_left, INPUT);

pinMode(trigger_right, OUTPUT);
pinMode(echo_right, INPUT);

pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);

}

void loop() {

gpshead();


digitalWrite(trigger_left, LOW); 
delayMicroseconds(2);
digitalWrite(trigger_left, HIGH);
delayMicroseconds(5);
digitalWrite(trigger_left, LOW);
duration_left = pulseIn(echo_left, HIGH);
leftSensor = (duration_left / 2) / 29.1;

digitalWrite(trigger_front2, LOW);
delayMicroseconds(2);
digitalWrite(trigger_front2, HIGH);
delayMicroseconds(5);
digitalWrite(trigger_front2, LOW);
duration_front2 = pulseIn(echo_front2, HIGH);
frontSensor2 = (duration_front2 / 2) / 29.1;

digitalWrite(trigger_right, LOW);
delayMicroseconds(2);
digitalWrite(trigger_right, HIGH);
delayMicroseconds(5);
digitalWrite(trigger_right, LOW);
duration_right = pulseIn(echo_right, HIGH);
rightSensor = (duration_right / 2) / 29.1;

digitalWrite(trigger_front1, LOW);
delayMicroseconds(2);
digitalWrite(trigger_front1, HIGH);
delayMicroseconds(5);
digitalWrite(trigger_front1, LOW);
duration_front1 = pulseIn(echo_front1, HIGH);
frontSensor1 = (duration_front1 / 2) / 29.1;

digitalWrite(trigger_front3, LOW);    
delayMicroseconds(2);
digitalWrite(trigger_front3, HIGH);
delayMicroseconds(5);
digitalWrite(trigger_front3, LOW);
duration_front3 = pulseIn(echo_front3, HIGH);
frontSensor3 = (duration_front3 / 2) / 29.1; 

Serial.println("--------------------------------------------------------------");
Serial.print("head: ");
Serial.print(head);
Serial.print(" distance: ");
Serial.println(distance);

Serial.print("  1:");
Serial.print(leftSensor); //left sensor
Serial.print("  2:");
Serial.print(frontSensor2); //front left sensor
Serial.print("  3:");
Serial.print(rightSensor); //right sensor
Serial.print("  4:");
Serial.print(frontSensor1); //center sensor
Serial.print("  5:");
Serial.print(frontSensor3); //front right sensor
Serial.println("");

}


void gpshead()
{
bool newData = false;
for ( unsigned long start = millis(); millis() - start < 1000;)
{
 while ( GPS.available() ) // if there is data coming from the GPS shield
 {
   char a = GPS.read(); // get the byte of data
   if (shield.encode(a)) // if there is valid GPS data...
     newData = true;
 }
}
if (newData)
{
 float latitude, longitude, age;
 float x2lat, x2lon;

 // Then call this function
 shield.f_get_position(&latitude, &longitude);
 Serial.println("--------------------------------------------------------------");
 Serial.print("Current Lat: ");
 Serial.print(latitude, 6);
 Serial.print(" Current Long: ");
 Serial.println(longitude, 6);

 x2lat = 2.928890;                //desired latitude
 x2lon = 101.767662;            //desired longitude

 Serial.println("--------------------------------------------------------------");
 Serial.print("Go to Lat: ");
 Serial.print(x2lat, 6);
 Serial.print(" Go to Long: ");
 Serial.println(x2lon, 6);
 longitude = radians(longitude);
 latitude = radians(latitude);
 x2lat = radians(x2lat);
 x2lon = radians(x2lon);

 head = atan2(sin(x2lon - longitude) * cos(x2lat), cos(latitude) * sin(x2lat) - sin(latitude) * cos(x2lat) * cos(x2lon - longitude));
 head = head * 180 / 3.1415926535;
 head -= 90;

 float dist_calc = 0;
 float diflat = 0;
 float diflon = 0;

 diflat = x2lat - latitude; //notice it must be done in radians
 diflon = (x2lon) - (longitude); //subtract and convert longitudes to radians
 distance = (sin(diflat / 2.0) * sin(diflat / 2.0));
 dist_calc = cos(latitude);
 dist_calc *= cos(x2lat);
 dist_calc *= sin(diflon / 2.0);
 dist_calc *= sin(diflon / 2.0);
 distance += dist_calc;
 distance = (2 * atan2(sqrt(distance), sqrt(1.0 - distance)));
 distance *= 6371000.00;



 if (head < 0)
 {
   head += 360;
 }
}
else
{
 head = 0;
 distance = 0;
}

}

Check your power supply is adequate.

Please edit your post and add the code tags you forgot.

Awol, I've edited my code. & already check my power supply, everything is okay because the power supply is from the USB port. I've got a consistent result for my GPS. But, not for the ultrasonic sensor. any ideas?

Please see reply #1

Emm.. What is code tags? Sorry, I'm still learning.

You just looked at a thread entitled "Code tags" - what did it tell you?

okey..done... :grinning:

Thanks.

What about the power supply?

For the power supply, I'm using the power supply from the USB port.

I've tested the ultrasonic code before I added GPS code and it's work perfect with a consistent value from ultrasonics and GPS shield. Then, after I combined all those codes, the ultrasonics give the inconsistent values. I don't know why.

Maybe the power supply is inadequate to run both the GPS and the ultrasonics.

the ultrasonics give the inconsistent values.

Post some examples.

Not related to your problem, but the following code seems unreasonable.
If the heading is negative, add 360.
Otherwise, the heading is zero and there is no distance left to travel.

 if (head < 0)
 {
   head += 360;
 }
}
else
{
 head = 0;
 distance = 0;
}

There are several problems here...

1) SoftwareSerial is interfering with the pulseIn timings. You have a Mega, so don't use SoftwareSerial. Instead, use one of the extra HardwareSerial ports, Serial1 (pins 18 & 19), Serial2 (pins 20 & 21), or Serial3 (pins 22 & 23). For example:

#define gps_port Serial1

void setup()
{
  Serial.begin( 9600 );

  gps_port.begin( 9600 );  // this is really Serial1, but we gave it an alternate name that means something

  pinMode(trigger_front1, OUTPUT);
     ...
}

void gpshead()
{
  while (gps_port.available()) {
     ...

2) You have written the program so that it must get GPS data within 1 second, then it must ping 5 different sensors, then it must print the results. While you are doing the last two things, the GPS shield continues to send data. Eventually it overflows (after 64ms) the input buffer, and the GPS parser will not get a complete sentence.

This is because The GPS device sends "sentences". If the whole sentence is not received correctly, the parser will reject it. gpshead will have to wait for the next sentence, but it may not arrive before 1 second has elapsed, and it returns from gpshead. Not only that, it may leave a partial sentence in the input buffer for the next time. It still won't parse correctly!

You really have to wait up to 3 seconds (i.e., 3000ms). This allows a partial sentence at the beginning to get rejected, then a second complete sentence will have up to 2 seconds to arrive. This will set newData = true, and you can get these GPS values. You could break out of the for/while loop at this point, instead of waiting the full 3 seconds:

void gpshead()
{
  bool          newData = false;
  unsigned long start   = millis();

  while ((millis() - start < 3000) && !newData)  // wait for data, up to 3 seconds
  {
    while ( gps_port.available() ) // if there is data coming from the GPS shield
    {
      char a = gps_port.read(); // get the byte of data
      if (gps.encode(a))
      {
        // if there is valid GPS data...
        newData = true;
        break; // out of the inner while loop
      }
    }
  }

  if (newData)
  {

There may be other problems in the distance/heading calculations... but not here:

    if (head < 0)
    {
      head += 360;
    }
  }
  else
  {
    head = 0;
    distance = 0;
  }

Because you did not use proper indentation, it looked like it was one if/else statement. It is actually an if statement (which is ok), and then the end of the if(newData) and its else clause. :stuck_out_tongue: I had to stare at that for a minute.

I would also suggest using my NeoGPS library, because it is faster, smaller, more accurate, and it includes distance and bearing calculations. Here's a NeoGPS version of your sketch:

#include <NMEAGPS.h>

// You're have a Mega, so use one of the extra HardwareSerial ports: Serial1, Serial2 or Serial3
#define gps_port Serial1
NMEAGPS gps;

NeoGPS::Location_t x2( (float) 2.928890, (float) 101.767662 );    // latitude and longitude to reach

float head, distance;        // calculation for gps
void gpshead();

int trigger_left = A10; 
int echo_left = A11;

int trigger_front2 = A2;
int echo_front2 = A3;

int trigger_front1 = A4;
int echo_front1 = A5;

int trigger_front3 = A6;
int echo_front3 = A7;

int trigger_right = A8;
int echo_right = A9;

float frontSensor2, frontSensor1, frontSensor3, rightSensor, leftSensor;
long duration_front1, duration_front2, duration_front3, duration_left, duration_right;

void forward();
void Backward();
void Stop();
void rightturn();
void leftturn();

int pwm_motor_right = 6;              //pwm mottor right connect to AN2 at MDS10
int pwm_motor_left = 5;               //pwm mottor left connect to AN1 at MDS10
int dir_motor_right = 4;              //direction mottor right connect to DIG2 at MDS10
int dir_motor_left = 7;               //direction mottor left connect to DIG1 at MDS

int pwm_val = 0;



void setup() {

  Serial.begin(9600);

  gps_port.begin(9600); // this is really Serial1

  pinMode(trigger_front1, OUTPUT);
  pinMode(echo_front1, INPUT);

  pinMode(trigger_front2, OUTPUT);
  pinMode(echo_front2, INPUT);

  pinMode(trigger_front3, OUTPUT);
  pinMode(echo_front3, INPUT);

  pinMode(trigger_left, OUTPUT);
  pinMode(echo_left, INPUT);

  pinMode(trigger_right, OUTPUT);
  pinMode(echo_right, INPUT);

  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);

} // setup

void loop() {

  gpshead();


  digitalWrite(trigger_left, LOW); 
  delayMicroseconds(2);
  digitalWrite(trigger_left, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigger_left, LOW);
  duration_left = pulseIn(echo_left, HIGH);
  leftSensor = (duration_left / 2) / 29.1;

  digitalWrite(trigger_front2, LOW);
  delayMicroseconds(2);
  digitalWrite(trigger_front2, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigger_front2, LOW);
  duration_front2 = pulseIn(echo_front2, HIGH);
  frontSensor2 = (duration_front2 / 2) / 29.1;

  digitalWrite(trigger_right, LOW);
  delayMicroseconds(2);
  digitalWrite(trigger_right, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigger_right, LOW);
  duration_right = pulseIn(echo_right, HIGH);
  rightSensor = (duration_right / 2) / 29.1;

  digitalWrite(trigger_front1, LOW);
  delayMicroseconds(2);
  digitalWrite(trigger_front1, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigger_front1, LOW);
  duration_front1 = pulseIn(echo_front1, HIGH);
  frontSensor1 = (duration_front1 / 2) / 29.1;

  digitalWrite(trigger_front3, LOW);    
  delayMicroseconds(2);
  digitalWrite(trigger_front3, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigger_front3, LOW);
  duration_front3 = pulseIn(echo_front3, HIGH);
  frontSensor3 = (duration_front3 / 2) / 29.1; 

  Serial.println("--------------------------------------------------------------");
  Serial.print("head: ");
  Serial.print(head);
  Serial.print(" distance: ");
  Serial.println(distance);

  Serial.print("  1:");
  Serial.print(leftSensor); //left sensor
  Serial.print("  2:");
  Serial.print(frontSensor2); //front left sensor
  Serial.print("  3:");
  Serial.print(rightSensor); //right sensor
  Serial.print("  4:");
  Serial.print(frontSensor1); //center sensor
  Serial.print("  5:");
  Serial.print(frontSensor3); //front right sensor
  Serial.println("");

} // loop


void gpshead()
{
  //  Assume we won't get any data
  head     = 0;
  distance = 0;

  bool          newData = false;
  unsigned long start   = millis();

  while ((millis() - start < 3000) && !newData)  // wait for data, up to 3 seconds
  {
    if ( gps.available( gps_port ) ) // if there is complete data coming from the GPS shield
    {
      gps_fix fix = gps.read(); // get the new GPS data in one big structure
      newData     = true;

      Serial.println("--------------------------------------------------------------");
      Serial.print("Current Lat: ");
      if (fix.valid.location)
        Serial.print( fix.latitude(), 6);
      else
        Serial.print( '?' );
      Serial.print(" Current Long: ");
      if (fix.valid.location)
        Serial.println( fix.longitude(), 6);
      else
        Serial.print( '?' );

      Serial.println("--------------------------------------------------------------");
      Serial.print("Go to Lat: ");
      Serial.print(x2.latF(), 6);
      Serial.print(" Go to Long: ");
      Serial.println(x2.lonF(), 6);

      if (fix.valid.location) {
        distance = fix.location.DistanceKm      ( x2 ) * 1000.0;
        head     = fix.location.BearingToDegrees( x2 );
      }
    }
  }

} // gpshead

The increased accuracy will give you better distance and bearing values for small movements. If you'd like to try it, it is available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries. Even if you don't use it, I would suggest reading the Troubleshooting page, because it describes some of the timing problems you are having.

Cheers,
/dev

I downloaded the NewPing library today (v1.8 ). It seems to work perfectly with my HC-SR04. I used the demo code from:

teckel12 / Arduino New Ping / wiki / Home — Bitbucket

There is also a demo code for 3 ultra sonic sensors.

If you combine this code with other code it is a good idea to edit NewPing.h in the library and set TIMER_ENABLED to false. This way the library will not use Timer2 and will not use interrupts (this is documented).

Hi, can anyone helps me for my final project. My objective is to move the robot from current location to the desired location. I'm using Arduino mega with expansion shield, 5 ultrasonic sensors, three-axis digital compass, and GPS shield. 1st problem is I can't get continuously data from GPS when the robot is moving. 2nd is my ultrasonic doesn't give the accurate data sometimes. Here is my coding. Hope you can help me.

#include <NMEAGPS.h>
#include <Wire.h>
#include <HMC5883L.h>
#include "math.h"
#include <NewPing.h>
#define gps_port Serial1
NMEAGPS gps;
#define address 0x1E //0011110b, I2C 7bit address of HMC5883
#include <LiquidCrystal.h>
LiquidCrystal lcd(11, 10, 2, 3, 8, 9);
float heading;              // compass
float head, distance;        // calculation for gps
void gpshead();
void comphead();


float x2lat, x2lon;         // latitude and longitude to reach
float x2lat1, x2lon1;         // latitude and longitude to

#define TRIGGERfront2_PIN  A2  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHOfront2_PIN     A3  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define TRIGGERfront1_PIN  A4
#define ECHOfront1_PIN     A5
#define TRIGGERleft_PIN    A10
#define ECHOleft_PIN      A11
#define TRIGGERright_PIN  A8
#define ECHOright_PIN     A9
#define TRIGGERfront3_PIN  A6
#define ECHOfront3_PIN     A7
#define MAX_DISTANCE 300 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar1(TRIGGERfront1_PIN, ECHOfront1_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
NewPing sonar2(TRIGGERfront2_PIN, ECHOfront2_PIN, MAX_DISTANCE);
NewPing sonarLeft(TRIGGERleft_PIN, ECHOleft_PIN, MAX_DISTANCE);
NewPing sonarRight(TRIGGERright_PIN, ECHOright_PIN, MAX_DISTANCE);
NewPing sonar3(TRIGGERfront3_PIN, ECHOfront3_PIN, MAX_DISTANCE);

float frontSensor2, frontSensor1, frontSensor3, rightSensor, leftSensor;

void forward();
void Backward();
void Stop();
void rightturn();
void leftturn();
void turn();

int pwm_motor_right = 6;              //pwm mottor right connect to AN2 at MDS10
int pwm_motor_left = 5;               //pwm mottor left connect to AN1 at MDS10
int dir_motor_right = 4;              //direction mottor right connect to DIG2 at MDS10
int dir_motor_left = 7;               //direction mottor left connect to DIG1 at MDS

int pwm_val = 0;

int f1 = 0;


void setup() {

  Serial.begin(9600);


  gps_port.begin(9600); // this is really Serial1
  Wire.begin();


  // Set operating mode to continuous
  Wire.beginTransmission(address);
  Wire.write(byte(0x02));
  Wire.write(byte(0x00));
  Wire.endTransmission();

  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);

  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("Hello");
  lcd.setCursor(0, 1);
  lcd.print("Push the button");
  Serial.println("Hello");

} // setup

void loop() {


    Serial.println("Auto Mode");
    lcd.clear();
    lcd.print("Auto Mode");

    gpshead();
    delay(500);
    comphead();

    Serial.println("--------------------------------------------------------------");
    Serial.print("head: ");
    Serial.print(head);
    Serial.print(" heading: ");
    Serial.print(heading);
    Serial.print(" distance: ");
    Serial.println(distance);


    while (distance < 3)
    {
      Stop();
      Serial.println("Reach Destination");
      lcd.clear();
      lcd.print("Reach Destination");
      return;
    }

    while ((heading < head + 10) && (heading > head - 10))
    {
      forward();
      Serial.println(" forward ");

      bool          newData = false;
      unsigned long start   = millis();

      while ((millis() - start < 1000) && !newData)  // wait for data, up to 1 seconds
      {
        frontSensor1 = sonar1.ping_cm(); //front left sensor
        frontSensor2 = sonar2.ping_cm(); //front right sensor
        leftSensor = sonarLeft.ping_cm();
        rightSensor = sonarRight.ping_cm();
        frontSensor3 = sonar3.ping_cm();
      }

      if ( frontSensor1 < 30  )
      {
        Stop();
        Serial.println(" obst. detect ");
        delay(1000);
        Backward();
        delay(500);

        if (frontSensor3 > frontSensor2)
        {
          Serial.println(" turn right ");
          rightturn();
          delay(1000);
          forward();
          delay(1000);
          break;

        }

        if (frontSensor2 > frontSensor3)
        {
          Serial.println(" turn left ");
          leftturn();
          delay(1000);
          forward();
          delay(1000);
          break;
        }
      }
      if (rightSensor < 20)
      {
        Serial.println(" obst. right detect ");
        rightturn();
        delay(200);
      }
      if (leftSensor < 20)
      {
        Serial.println(" obst. left detect ");
        leftturn();
        delay(200);
      }

      comphead();

      while ((heading > head + 10) || (heading < head - 10))
      {
        Stop();
        delay(500);
        return;
      }
    }

    while ((heading > head + 10) || (heading < head - 10))
    {
      turn();

      delay(5);
      comphead();

      Serial.println("--------------------------------------------------------------");
      Serial.print("head: ");
      Serial.print(head);
      Serial.print(" heading: ");
      Serial.print(heading);
      Serial.print(" distance: ");
      Serial.println(distance);
      Serial.println(" turn ");

      while ((heading < head + 10) && (heading > head - 10))
      {
        Stop();
        delay(500);
        return;
      }

    }

}



void gpshead()
{

  //  Assume we won't get any data
  head     = 0;
  distance = 0;

  if (f1 == 0)
  {
    Serial.println("Please enter Latitude ");        //Prompt User for input
    while (Serial.available() == 0)  {

    }
    x2lat1 = Serial.parseFloat();                    //Read user input into x2lat1

    Serial.println("Please enter Longitude ");      //Prompt User for input
    while (Serial.available() == 0)  {

    }
    x2lon1 = Serial.parseFloat();              //Read user input into x2lon2
    f1++;
  }
  x2lat = x2lat1;
  x2lon = x2lon1;

  NeoGPS::Location_t x2( (float) x2lat, (float) x2lon );    // latitude and longitude to reach

  bool          newData = false;
  unsigned long start   = millis();

  while ((millis() - start < 3000) && !newData)  // wait for data, up to 3 seconds
  {
    if ( gps.available( gps_port ) ) // if there is complete data coming from the GPS shield
    {
      gps_fix fix = gps.read(); // get the new GPS data in one big structure
      newData     = true;

      Serial.println("--------------------------------------------------------------");
      Serial.print("Current Lat: ");
      if (fix.valid.location)
        Serial.print( fix.latitude(), 6);
      else
        Serial.print( '?' );
      Serial.print(" Current Long: ");
      if (fix.valid.location)
        Serial.println( fix.longitude(), 6);
      else
        Serial.print( '?' );

      Serial.println("--------------------------------------------------------------");
      Serial.print("Go to Lat: ");
      Serial.print(x2lat, 6);
      Serial.print(" Go to Long: ");
      Serial.println(x2lon, 6);

      if (fix.valid.location) {
        distance = fix.location.DistanceKm      ( x2 ) * 1000.0;
        head     = fix.location.BearingToDegrees( x2 );
        //head -= 90;
      }
    }
  }
} // gpshead

void comphead()
{

  int x, y, z;
  Wire.beginTransmission(address);
  Wire.write(0x03);       // Send request to X MSB register
  Wire.endTransmission();

  Wire.requestFrom(address, 6);    // Request 6 bytes; 2 bytes per axis
  if (6 <= Wire.available())
  { // If 6 bytes available
    x = Wire.read() << 8; //X msb
    x |= Wire.read(); //X lsb
    z = Wire.read() << 8; //Z msb
    z |= Wire.read(); //Z lsb
    y = Wire.read() << 8; //Y msb
    y |= Wire.read(); //Y lsb
  }

  float heading1 = atan2(y, x);
  float declinationAngle = 0.016667;
  heading1 += declinationAngle;
  if (heading1 < 0) heading1 += 2 * PI;

  if (heading1 > 2 * PI) heading1 -= 2 * PI;
  heading1 = heading1 * 180 / M_PI;

  heading = heading1;

} //comphead

void ultrasonic()
{
  bool          newData = false;
  unsigned long start   = millis();

  while ((millis() - start < 1000) && !newData)  // wait for data, up to 1 seconds
  {
    frontSensor1 = sonar1.ping_cm(); //front left sensor
    frontSensor2 = sonar2.ping_cm(); //front right sensor
    leftSensor = sonarLeft.ping_cm();
    rightSensor = sonarRight.ping_cm();
    frontSensor3 = sonar3.ping_cm();
  }
}

Whenever I do a project, I get the individual bits of code or sensors working first.

Have you tested individually that the code for these is actually working;

Ultrasonic Distance measurement ?

GPS ?

Compass ?

Topics merged.
Do not cross-post, cross-posting wastes time.

Yes, I already test it. everything is okay. But, when I've combined all these modules, its not okay. I dont know why.

1st problem is I can't get continuously data from GPS when the robot is moving.

Why does that matter?

You have delays in lots of places. Your program is structured to do exactly one thing at a time, and then it does the next thing. This is called "blocking".

If you want to be able to get GPS data continuously (and check the heading continuously, and move continuosuly), you will have to use the "Blink Without delay" and "Multiple Things" technique (see the General Design section here).

You have most of the pieces for that kind of program. To change program styles from the current linear style (do this, delay, do that, ...) to a continuous style (check this, check that, do that, check this...) each piece would get guarded by a non-blocking if statement:

void checkThis()
{
  if (we're doing this and (millis() - time we started this >= how long we should to this) {
    we're doing this = false;

    start doing that;

    we're doing that = true;
    time we started doing that = millis();
  }
}

... and your main loop would change to:

void loop()
{
  checkThis();
  checkThat();
  checkGPS();
}

With that program structure, the GPS could be continuously read like this:

void checkGPS()
{
  if ( gps.available( gps_port ) ) { // if there is complete data coming from the GPS shield
    gps_fix fix = gps.read(); // get the new GPS data in one big structure
    newData     = true;
       ...
    if (fix.valid.location) {
      distance = fix.location.DistanceKm      ( x2 ) * 1000.0;
      head     = fix.location.BearingToDegrees( x2 );
    }
  }
} // checkGPS

This updates [b]head[/b] any time a new GPS fix is available, continuously. But you can't delay inside the other routines.

For example, when an obstacle is detected:

      if ( frontSensor1 < 30  )
      {
        Stop();
        Serial.println(" obst. detect ");
        delay(1000);
        Backward();
        delay(500);
        if (frontSensor3 > frontSensor2)
        {
          Serial.println(" turn right ");
          rightturn();
          delay(1000);
          forward();
          delay(1000);
          break;

        }

        if (frontSensor2 > frontSensor3)
        {
          Serial.println(" turn left ");
          leftturn();
          delay(1000);
          forward();
          delay(1000);
          break;
        }

... it cannot do anything else. The GPS characters (and everything else) are being ignored while the program is blocked at a delay. You would have to change this section to something like:

void checkObstacles()
{
  if (movingForward && (millis() - movingForwardTime >= 1000)) {

    // Check for obstacles once per second

    frontSensor1 = sonar1.ping_cm(); //front left sensor <--- Are you sure?  Maybe front center?
    frontSensor2 = sonar2.ping_cm(); //front right sensor
    frontSensor3 = sonar3.ping_cm();          // <-- front left?
    leftSensor   = sonarLeft.ping_cm();
    rightSensor  = sonarRight.ping_cm();

    //  Use sensor readings to drive around obstacle
    //     Just keep moving forward if there are no obstacles.

    if (frontSensor1 < 30) {
      movingForward = false;

      Stop();
      Serial.println(" obst. front detect ");

      avoidingFront = true;
      avoidingFrontTime = millis();

    } else if (rightSensor < 20)
      movingForward = false;

      Serial.println(" obst. right detect ");
      rightturn();

      turningToAvoid = true;
      turningToAvoidTime = millis();
      turnDuration = 200;

    } else if (leftSensor < 20)
      movingForward = false;

      Serial.println(" obst. left detect ");
      leftturn();

      turningToAvoid = true;
      turningToAvoidTime = millis();
      turnDuration     = 200;

    } else {
      movingForwardTime = millis(); // all clear, keep going for another second
    }
  }

  // Turning to avoid something?

  if (avoidingFront && (millis() - avoidingFrontTime >= 1000)) {
    avoidingFront = false;

    Backward();

    backingUp = true;
    backingUpTime = millis();
  }

  if (backingUp && (millis() - backingUpTime >= 500)) {
    backingUp = false;

    if (frontSensor3 > frontSensor2) {
      Serial.println(" turn right ");
      rightturn();

    } else { // frontSensor2 >= frontSensor3
      Serial.println(" turn left ");
      leftturn();
    }

    turningToAvoid = true;
    turningToAvoidTime = millis();
    turnDuration = 1000;
  }

  if (turningToAvoid && (millis() - turningToAvoidTime >= turnDuration)) {
    turningToAvoid = false;

    forward();

    movingForward = true;
    movingForwardTime = millis()
  }

}

There are no delays. Instead, if statements check the millis() clock, and when enough time has elapsed, it does the next thing. This function could get called hundreds of times, and it will do nothing but check the time. Occasionally, it does something. Then it starts the next thing and remembers when it started.

Unless you restructure your program, you can't do two things at the same time.

Cheers,
/dev