Control Motor via Xbee, GPS, Follow me robot

Hi

My apologies if this isn't the right subforum to ask this question, but I do think its a programming problem, not anything else - I might be wrong. If I should have posted this somewhere else, please let me know where and I will delete this thread and start new one in that subforum.

I'm working on a project where we have to make a trolley follow the user.
I'm using:
2 Xbee 802.15.4
2 Arduino Mega
2 PmodGPS
2 DC Motors
1 L298N Dual H-Bridge Motor Controller - power by external 9V battery

I've got the GPS data being transferred between the two arduinos, I've worked out the distance and I have worked out the bearing as well, all thanks to users from this forum.

Now that I'm getting this working, I tried to program it so that it runs the motor when its more than 5m apart. I've tried to make it work but due to my novice programming skills, it didn't. :frowning:
My thought process was that if the distance is more than 5m, the arduino should put the motor controller pin HIGH. If its not then all the pin would be set to LOW.
I tried creating a separate void declaration for controlling the pins. That didn't work. The last thing I tried was to just put the HIGH LOW code in the ShowParsedData loop. That obviously didn't work either.

Could anyone tell me what I'm doing wrong and how I could achieve this?

Please let me know if I've missed something, or if anyone wants more details.

N.B. If the some parts of the Rx code look out of place and/or stupid, I've been doing a trial and error to get it to work, so I've moved some stuff here and there, just to see what happens.

High Regards

Here's the transmitter code (getting GPS from the user - Working):

#include <NMEAGPS.h>

NMEAGPS gps;
gps_fix fix;

#define gpsPort Serial1

void setup()
{
  Serial.begin(9600);
  gpsPort.begin( 9600 );
  
//  Might be needed:
//
//  #define RSTpin    37 //pin 37, JE-08
//  pinMode(RST, OUTPUT);
//  digitalWrite(RST, LOW);
}

void loop()
{

  if (gps.available( gpsPort )) 
  {
    fix = gps.read();
    
    if (fix.valid.satellites) 
    {
      Serial.print( fix.satellites );
    }
    Serial.print(',');

    if (fix.valid.location)
      Serial.print( fix.latitude(), 6 );
      Serial.print(',');

    if (fix.valid.location)
      Serial.print( fix.longitude(), 6 );

    Serial.println();

  }
}

Here's the receiver (gets GPS data from user, compares it with its own, calculates distance and bearing, and should send signal to the motor controller which should run the two motors):

/*   16-03-2018
 *   Rx Motor move with GPS
 *  Untested
 * 
*/

//Include libraries
#include <NMEAGPS.h>      //Library to print in NMEA format i.e. XX.YYZZZZ or DD.MMSSSS

//Define serial ports
#define gpsPort Serial2   //GPS port using Tx/Rx port 2
#define fobPort Serial    //Incoming data from fob on port 0

//Define variables
NMEAGPS gps;
gps_fix trolley;

//Define parameters for receiving array
const size_t NUM_CHARS = 64;              //Size of array
char         receivedChars[ NUM_CHARS ];  //Array to store received characteristics
boolean      newData = false;

// variables to hold the parsed data
int                fobSat;
NeoGPS::Location_t fobLoc;
float              fobAlt;


//Define motor variables and connections
// Motor A
int enA = 9;
int in1 = 8;  //forward
int in2 = 7;  //backwards

// Motor B
int enB = 3;
int in3 = 5;  //left
int in4 = 4;  //right

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  gpsPort.begin( 9600 );
  Serial.println("Start");

  //Set motor control pins to output
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  // Start with motors disabled and direction forward
  // Motor A
  digitalWrite(enA, LOW);
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);

  // Motor B
  digitalWrite(enB, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);

}

void loop() {
  // put your main code here, to run repeatedly:
  //  Check for data from the Fob
  recvWithEndMarkers();
  if (newData)
  {
    parseFobData();
    showParsedData();
    newData = false;
  }

  // Check for data from the GPS
  if (gps.available( gpsPort ))
  {
    trolley = gps.read();   //Stores GPSR data as trolley
  }

}

//Defines parsing parameters, such as when to start and when to stop parsing
void recvWithEndMarkers()
{
  static size_t index     = 0;
  const char    endMarker = '\n';

  while (fobPort.available() && !newData)
  {
    char rc = fobPort.read();
    //Serial.print(rc); // for debugging
    if (rc != endMarker)
    {
      if (index < NUM_CHARS - 1)
      {
        receivedChars[ index++ ] = rc;
      }
    }
    else
    {
      receivedChars[index] = '\0'; // terminate the string
      index                = 0;    // reset for next time
      newData              = true;
    }
  }
}

//============

void parseFobData() // split the data into its parts
{
  //Incoming data from fob
  char *field;

  field  = strtok( receivedChars, "," ); //Starts from beginning, splits when sees comma
  fobSat = atoi( field );                //Number of satellites the fob is connected to

  field = strtok( nullptr, "," );        //Continues where left off i.e first comma then stops at the next
  fobLoc.latF( atof( field ) );          //Fob's current latitude

  field = strtok( nullptr, "," );
  fobLoc.lonF( atof( field ) );          //Fob's current longitude
}

void showParsedData()     //Shows all parsed data collected above and stores as different variables.
{
  Serial.print("Fob Sats: ");
  Serial.println( fobSat );
  Serial.print("Fob Lat: ");
  Serial.println( fobLoc.latF(), 6 );
  Serial.print("Fob Lon: ");
  Serial.println( fobLoc.lonF(), 6 );

  Serial.print("Trolley Sats: ");
  if (trolley.valid.satellites)
  {
    Serial.print( trolley.satellites );           //Number of satellites the trolley is connected to
  }
  Serial.println();

  Serial.print("Trolley Lat: ");                  //trolley's current latitude
  if (trolley.valid.location)
  {
    Serial.print( trolley.location.latF(), 6 );
  }
  Serial.println();

  Serial.print("Trolley Lon: ");
  if (trolley.valid.location)
  {
    Serial.print( trolley.location.lonF(), 6 );    //Trolley's current longitude
  }
  Serial.println();
  Serial.print("Distance: ");
  if (trolley.valid.location) {
    float distance = trolley.location.DistanceKm( fobLoc ); //measures the distance as a float of 6 decimal points
    distance = distance*1000;
    Serial.print( distance, 6 );

    if (distance > 5.000000)
  {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
  }
  if ( distance < 5.000000)
  {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
  }

  } else {
    Serial.print( '?' );
  }
  Serial.println();
  Serial.print("Bearing: ");
  if (trolley.valid.location)
  {
    float bearing = trolley.location.BearingToDegrees( fobLoc ); //measures direction
    Serial.print( bearing, 6 );
  }
  else {
    Serial.println( '?' );
  }
  Serial.println(); // extra blank line
  Serial.println(); // extra blank line

  

}

Here's my serial monitor display:

Fob Sats: 4
Fob Lat: 43.383045
Fob Lon: -2.478903
Trolley Sats: 5
Trolley Lat: 43.383033
Trolley Lon: -2.478810
Distance: 6.252509
Bearing: 278.768463

bump

I think you need to connect the grounds of the Arduino and the 9V. If you have it set up as on your image try putting a jumper wire between the ground rails on each side of the breadboard.

Hey thanks a lot for your reply.

Yes, the fritzing image is accurate I made it after setting it up and its mainly for me to remember the wiring.

I did as you suggested but no response from the motors. I know the motors and the motor controller works because I've tested them with their basic codes and what not.

This is the serial monitor result, meaning the distance is more than 5m so it should work, logically:

Fob Sats: 4
Fob Lat: 43.383605
Fob Lon: -2.479598
Trolley Sats: 4
Trolley Lat: 43.383026
Trolley Lon: -2.479818
Distance: 66.096450
Bearing: 12.722241

In the code that I posted above, I've put

if (trolley.valid.location) {
    float distance = trolley.location.DistanceKm( fobLoc ); //measures the distance as a float of 6 decimal points
    distance = distance*1000;
    Serial.print( distance, 6 );

    if (distance > 5.000000)
  {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
  }
  if ( distance < 5.000000)
  {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
  }

in the showParsedData loop. I feel that thats not where its supposed to be, but I could be wrong.
Any other suggestion?

High Regards

bump

Bump

Isn't it a bit optimistic to expect five metre accuracy with GPS? (Assuming you're not using DGPS)

GrooveFlotilla:
Isn't it a bit optimistic to expect five metre accuracy with GPS? (Assuming you're not using DGPS)

Maybe, but that's alright, I can change it and work around it. I'll be alright with even 10 m, but that won't matter until the I can make the motors move.

In the code that I posted above, I've put

But you didn't show us where you put it.

GrooveFlotilla:
But you didn't show us where you put it.

Sorry for being unclear. I put this code:

if (trolley.valid.location) {
    float distance = trolley.location.DistanceKm( fobLoc ); //measures the distance as a float of 6 decimal points
    distance = distance*1000;
    Serial.print( distance, 6 );

    if (distance > 5.000000)
  {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
  }
  if ( distance < 5.000000)
  {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
  }

in this part of the code.

void showParsedData()     //Shows all parsed data collected above and stores as different variables.
{
  Serial.print("Fob Sats: ");
  Serial.println( fobSat );
  Serial.print("Fob Lat: ");
  Serial.println( fobLoc.latF(), 6 );
  Serial.print("Fob Lon: ");
  Serial.println( fobLoc.lonF(), 6 );

  Serial.print("Trolley Sats: ");
  if (trolley.valid.satellites)
  {
    Serial.print( trolley.satellites );           //Number of satellites the trolley is connected to
  }
  Serial.println();

  Serial.print("Trolley Lat: ");                  //trolley's current latitude
  if (trolley.valid.location)
  {
    Serial.print( trolley.location.latF(), 6 );
  }
  Serial.println();

  Serial.print("Trolley Lon: ");
  if (trolley.valid.location)
  {
    Serial.print( trolley.location.lonF(), 6 );    //Trolley's current longitude
  }
  Serial.println();
  Serial.print("Distance: ");
 if (trolley.valid.location) {
    float distance = trolley.location.DistanceKm( fobLoc ); //measures the distance as a float of 6 decimal points
    distance = distance*1000;
    Serial.print( distance, 6 );

    if (distance > 5.000000)
  {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
  }
  if ( distance < 5.000000)
  {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
  }

  } else {
    Serial.print( '?' );
  }
  Serial.println();
  Serial.print("Bearing: ");
  if (trolley.valid.location)
  {
    float bearing = trolley.location.BearingToDegrees( fobLoc ); //measures direction
    Serial.print( bearing, 6 );
  }
  else {
    Serial.println( '?' );
  }
  Serial.println(); // extra blank line
  Serial.println(); // extra blank line

  

}

Hope that's clear, a bit difficult to explain. I don't think it fits there, but I'm actually unsure where it will go. I tried making a separate declaration like void moveTrolley() but that didn't work either.

Are you saying that the motors don't turn on if the distance is greater than five?
That would seem to be a wiring problem, not coding.
Do you have a simple foolproof test program to switch the motors on/off/reverse?

GrooveFlotilla:
Are you saying that the motors don't turn on if the distance is greater than five?

Yes exactly. The distance from the GPS that i'm getting is around 20 meters, sometimes goes as low as 6 m. So logically, the motors should turn on as soon as the arduino calculates the distance.

GrooveFlotilla:
Do you have a simple foolproof test program to switch the motors on/off/reverse?

Yes, I've tested the motors with two different code, but I only have one of them on me. I was able to control the motor with a joystick which was connected to the arduino. I was doing this because at a later point, I want to be also able to control the motors with the joysticks, but wirelessly using XBee. I wasn't able to make progress with that, but this isn't one of the main objectives, its extra work.

Here's the code that I used, but at this point I powered it with the arduino, not the battery.

/*  
  L298N Motor Control Demonstration with Joystick
  L298N-Motor-Control-Demo-Joystick.ino
  Demonstrates use of Joystick control with Arduino and L298N Motor Controller
  
  DroneBot Workshop 2017
  http://dronebotworkshop.com
*/
  
// Motor A

int enA = 9;
int in1 = 8;
int in2 = 7;

// Motor B

int enB = 3;
int in3 = 5;
int in4 = 4;

// Joystick Input

int joyVert = A0; // Vertical  
int joyHorz = A1; // Horizontal

// Motor Speed Values - Start at zero

int MotorSpeed1 = 0;
int MotorSpeed2 = 0;

// Joystick Values - Start at 512 (middle position)

int joyposVert = 512;
int joyposHorz = 512;  


void setup()

{

  // Set all the motor control pins to outputs

  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
   
  // Start with motors disabled and direction forward
  
  // Motor A
  
  digitalWrite(enA, LOW);
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  
  // Motor B
  
  digitalWrite(enB, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  
}

void loop() {

  // Read the Joystick X and Y positions

  joyposVert = analogRead(joyVert); 
  joyposHorz = analogRead(joyHorz);

  // Determine if this is a forward or backward motion
  // Do this by reading the Verticle Value
  // Apply results to MotorSpeed and to Direction

  if (joyposVert < 460)
  {
    // This is Backward

    // Set Motor A backward

    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);

    // Set Motor B backward

    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);

    //Determine Motor Speeds

    // As we are going backwards we need to reverse readings

    joyposVert = joyposVert - 460; // This produces a negative number
    joyposVert = joyposVert * -1;  // Make the number positive

    MotorSpeed1 = map(joyposVert, 0, 460, 0, 255);
    MotorSpeed2 = map(joyposVert, 0, 460, 0, 255);

  }
  else if (joyposVert > 564)
  {
    // This is Forward

    // Set Motor A forward

    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);

    // Set Motor B forward

    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);

    //Determine Motor Speeds

    MotorSpeed1 = map(joyposVert, 564, 1023, 0, 255);
    MotorSpeed2 = map(joyposVert, 564, 1023, 0, 255); 

  }
  else
  {
    // This is Stopped

    MotorSpeed1 = 0;
    MotorSpeed2 = 0; 

  }
  
  // Now do the steering
  // The Horizontal position will "weigh" the motor speed
  // Values for each motor

  if (joyposHorz < 460)
  {
    // Move Left

    // As we are going left we need to reverse readings

    joyposHorz = joyposHorz - 460; // This produces a negative number
    joyposHorz = joyposHorz * -1;  // Make the number positive

    // Map the number to a value of 255 maximum

    joyposHorz = map(joyposHorz, 0, 460, 0, 255);
        

    MotorSpeed1 = MotorSpeed1 - joyposHorz;
    MotorSpeed2 = MotorSpeed2 + joyposHorz;

    // Don't exceed range of 0-255 for motor speeds

    if (MotorSpeed1 < 0)MotorSpeed1 = 0;
    if (MotorSpeed2 > 255)MotorSpeed2 = 255;

  }
  else if (joyposHorz > 564)
  {
    // Move Right

    // Map the number to a value of 255 maximum

    joyposHorz = map(joyposHorz, 564, 1023, 0, 255);
        

    MotorSpeed1 = MotorSpeed1 + joyposHorz;
    MotorSpeed2 = MotorSpeed2 - joyposHorz;

    // Don't exceed range of 0-255 for motor speeds

    if (MotorSpeed1 > 255)MotorSpeed1 = 255;
    if (MotorSpeed2 < 0)MotorSpeed2 = 0;      

  }


  // Adjust to prevent "buzzing" at very low speed

  if (MotorSpeed1 < 8)MotorSpeed1 = 0;
  if (MotorSpeed2 < 8)MotorSpeed2 = 0;

  // Set the motor speeds

  analogWrite(enA, MotorSpeed1);
  analogWrite(enB, MotorSpeed2);

}

bump

Definetly not good form to repeatadly bump your post to the top of the list.

Why do you think its more important than other peoples posts ?

srnet:
Definetly not good form to repeatadly bump your post to the top of the list.

Why do you think its more important than other peoples posts ?

You're right, I will refrain from doing that too often. Apologies.

In the code that works, you control the direction and speed of the motors. In the code that doesn't, you control the direction. I wonder what would happen if you set the speed to something other than stopped?

in1, in2, in3, etc. are really dumb names for Arduino outputs.

PaulS:
In the code that works, you control the direction and speed of the motors. In the code that doesn't, you control the direction. I wonder what would happen if you set the speed to something other than stopped?

in1, in2, in3, etc. are really dumb names for Arduino outputs.

Thanks for your reply Paul, I tried what you said, and it didn't work sadly. This is what I tried:

if (trolley.valid.location) {
    float distance = trolley.location.DistanceKm( fobLoc ); //measures the distance as a float of 6 decimal points
    distance = distance*1000;
    Serial.print( distance, 6 );

    if (distance > 5.000000)
  {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);

    analogWrite(enA, 200);
  }

The code that works, the motors start making a buzzing sound, and once you spin the motor manually, it starts moving. I just tried it again.

When I tried the code above, and the other codes I posted for gps controlled motor, it doesn't even buzz. Distance is greater than 5m, it should be moving.

PaulS:
in1, in2, in3, etc. are really dumb names for Arduino outputs.

Also, those are the names of the pins on motor controller. Might be stupid, but I can tell which connection is which from that.

This is an updated version of my previous code. I haven't done much but I've connected a compass, and I'm getting the compass reading and what not.:

//Include libraries
#include <NMEAGPS.h>      //Library to print in NMEA format i.e. XX.YYZZZZ or DD.MMSSSS
#include <Wire.h>         //I2C
#include <Adafruit_Sensor.h>
#include <Adafruit_LSM303_U.h>

//Define serial ports
#define gpsPort Serial2   //GPS port using Tx/Rx port 2
#define fobPort Serial    //Incoming data from fob on port 0

//Define variables
NMEAGPS gps;
gps_fix trolley;
Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(12345); /* Assign a unique ID to this sensor at the same time */

//Define parameters for receiving array
const size_t NUM_CHARS = 64;              //Size of array
char         receivedChars[ NUM_CHARS ];  //Array to store received characteristics
boolean      newData = false;

// variables to hold the parsed data
int                fobSat;
NeoGPS::Location_t fobLoc;
float              heading;
float              distance;
float              bearing;

//Define motor variables and connections
// Motor A
int enA = 9;
int in1 = 8;  //forward
int in2 = 7;  //backwards

// Motor B
int enB = 3;
int in3 = 5;  //left
int in4 = 4;  //right

//Set motor speed
int MotorSpeed1 = 0;
int MotorSpeed2 = 0;

void setup()
{
  Serial.begin(9600);
  gpsPort.begin( 9600 );
  Serial.println("Start");

  //Set motor control pins to output
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  /*/ Start with motors disabled and direction forward
  // Motor A
  digitalWrite(enA, LOW);
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);

  // Motor B
  digitalWrite(enB, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);*/

  /* Initialise the sensor */
  if (!mag.begin())
  {
    /* There was a problem detecting the LSM303 ... check your connections */
    Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
    while (1);
  }
}

void loop()
{
  //  Check for data from the Fob
  recvWithEndMarkers();
  if (newData)
  {
    parseFobData();
    showParsedData();
    newData = false;
  }

  // Check for data from the GPS
  if (gps.available( gpsPort ))
  {
    trolley = gps.read();   //Stores GPSR data as trolley
  }

}

//Defines parsing parameters, such as when to start and when to stop parsing
void recvWithEndMarkers()
{
  static size_t index     = 0;
  const char    endMarker = '\n';

  while (fobPort.available() && !newData)
  {
    char rc = fobPort.read();
    //Serial.print(rc); // for debugging
    if (rc != endMarker)
    {
      if (index < NUM_CHARS - 1)
      {
        receivedChars[ index++ ] = rc;
      }
    }
    else
    {
      receivedChars[index] = '\0'; // terminate the string
      index                = 0;    // reset for next time
      newData              = true;
    }
  }
}

//============

void parseFobData() // split the data into its parts
{
  //Incoming data from fob
  char *field;

  field  = strtok( receivedChars, "," ); //Starts from beginning, splits when sees comma
  fobSat = atoi( field );                //Number of satellites the fob is connected to

  field = strtok( nullptr, "," );        //Continues where left off i.e first comma then stops at the next
  fobLoc.latF( atof( field ) );          //Fob's current latitude

  field = strtok( nullptr, "," );
  fobLoc.lonF( atof( field ) );          //Fob's current longitude
}

void showParsedData()     //Shows all parsed data collected above and stores as different variables.
{
    /* Get a new sensor event */
  sensors_event_t event;
  mag.getEvent(&event);

  float Pi = 3.14159;

  // Calculate the angle of the vector y,x
  float heading = (atan2(event.magnetic.y, event.magnetic.x) * 180) / Pi;

  // Normalize to 0-360
  if (heading < 0)
  {
    heading = 360 + heading;
  }
  Serial.print("Fob Sats: ");
  Serial.println( fobSat );
  Serial.print("Fob Lat: ");
  Serial.println( fobLoc.latF(), 6 );
  Serial.print("Fob Lon: ");
  Serial.println( fobLoc.lonF(), 6 );

  Serial.print("Trolley Sats: ");
  if (trolley.valid.satellites)
  {
    Serial.print( trolley.satellites );           //Number of satellites the trolley is connected to
  }
  Serial.println();

  Serial.print("Trolley Lat: ");                  //trolley's current latitude
  if (trolley.valid.location)
  {
    Serial.print( trolley.location.latF(), 6 );
  }
  Serial.println();

  Serial.print("Trolley Lon: ");
  if (trolley.valid.location)
  {
    Serial.print( trolley.location.lonF(), 6 );    //Trolley's current longitude
  }
  Serial.println();
  Serial.print("Trolley Heading: ");
  Serial.println(heading);
  Serial.print("Distance: ");
  if (trolley.valid.location) {
    float distance = trolley.location.DistanceKm( fobLoc ); //measures the distance as a float of 6 decimal points
    distance = distance*1000;
    Serial.print( distance, 6 );

  } 
  else 
  {
    Serial.print( '?' );
  }
  Serial.println();
  Serial.print("Bearing: ");
  if (trolley.valid.location)
  {
    float bearing = trolley.location.BearingToDegrees( fobLoc ); //measures direction
    Serial.println( bearing, 6 );
    
  }
  else 
  {
    Serial.print( '?' );
  }
  Serial.println(); // extra blank line
  if (trolley.valid.location)
  {
  if (heading == bearing && distance > 5.000000)
  {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
    analogWrite(enA, 200); 
  }
  if (heading == bearing && distance < 5.000000)
  {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
  }
  if (heading != bearing && distance > 5.000000)
  {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    analogWrite(enA, 200);

  }
}
}

Now for this code, I had to declare float distance, float heading and float bearing in the start of the code, because if I didn't, then I got the error:

'bearing' was not declared in this scope
** if (heading == bearing && distance > 5.000000)**
** ^**
RxCompassMotor15_03_18:224: error: 'distance' was not declared in this scope
** if (heading == bearing && distance > 5.000000)**

Can anyone tell me why I can't use bearing and distance when its in the same void showParsedData() declaration?

Thanks

Can anyone tell me why I can't use bearing and distance when its in the same void showParsedData() declaration?

Because you had them declared in the wrong scope.