Autonomous Waypoint Navigation Senior Design Project

For my Senior Design Project, me and my team are trying to build an Autonomous Waypoint Navigation car. So far, we have been able to get the Bluetooth, SD card, and the l298n motor driver to work. but the GPS GT-U7 and QMC5883l compass is not working. I also think we need an ultrasonic sensor for a project like this.
This the GitHub to the code: https://github.com/TychicusJ/DRT23-/blob/537c548df2c7fbd86a9bfe0d8fff13a7222b1417/Waypoint_code.ino#L1
This is the code we are using:

#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <QMC5883LCompass.h>
#include <SPI.h>
#include <SD.h>
#include <L298NX2.h>
#include "BluetoothSerial.h"

/*
   This sketch demonstrates the normal use of a TinyGPS++(TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and using the 
   9600-baud serial GPS device hooked up on pins 36(rx) and 39(tx) and a QMC5883 Magnetic Compass
   connected to the SCL/SDA pins.
*/

const int chipSelect = 5; // pin for SD card module
static const int RXPin = 36, TXPin = 39; // RX and TX pins are reverse on the board RX goto 39 and TX goto 36 
static const uint32_t GPSBaud = 9600;

// Assign a Unique ID to the QMC5883 Compass Sensor
QMC5883LCompass compass;
TinyGPSPlus gps; // The TinyGPSPlus object
SoftwareSerial ss(RXPin, TXPin); // The serial connection to the GPS device

// Initializing waypoint constants and variables
#define MAX_WAYPOINTS 10 // maximum waypoints to be stored in the SD Card

int waypoint_counter = 0; // counts the number of waypoints stored
int current_waypoint = 0; // index of the current waypoint 
bool reached_waypoint = false; // flag for reaching the waypoint
float target_heading, current_heading; // target and current headings

//right side motor control
int L298N_IN1 = 27;
int L298N_IN2 = 16;

//left side motor control
int L298N_IN3 = 17;
int L298N_IN4 = 25;

BluetoothSerial SerialBT;
String buffer;

void setup()
{
  Serial.begin(115200);
  SerialBT.begin("DRT23"); //Bluetooth device name
  Serial.println("\nThe device started, now you can pair it with bluetooth!");
  ss.begin(GPSBaud);
  compass.init();

  Serial.println(F("Simple Test with TinyGPS++ and attached GT-U7 GPS module"));
  Serial.print(F("Testing TinyGPSPlus library v. "));
  Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println();

  // setup SD card
  if (!SD.begin(chipSelect)) {
    Serial.println("SD card failed or not present.");
  }
  else {
    Serial.println("SD card initialized.");
  }

  pinMode(L298N_IN1, OUTPUT);
  pinMode(L298N_IN2, OUTPUT);
  pinMode(L298N_IN3, OUTPUT);
  pinMode(L298N_IN4, OUTPUT);
  

}
  
  int previous_waypoint_counter = 0; // Previous count of Waypoints

  bool newWaypoint()
  {
    // Check if there are new waypoints in the SD card
    // Return true if there are new waypoints, false otherwise
    int current_waypoint_counter = 0; // Get the current count of waypoints

    // Open the file containing the waypoints
    File file = SD.open("waypoints.txt", FILE_READ);

    // If the file is opened successfully
    if (file)
    {
      // Count the number of lines (waypoints) in the file
      while (file.available())
      {
        if (file.read() == '\n')
        {
          current_waypoint_counter++;
        }
      }

      // close the file
      file.close();
    }

    // Compare the current count with the previous count
    bool hasNewWaypoints = (current_waypoint_counter > previous_waypoint_counter);

    // Update the previous count with the current count
    previous_waypoint_counter = current_waypoint_counter;

    return hasNewWaypoints;

  }


// The loop function is where the navigation code goes.
void loop()
{
  // checking to see if there are any new waypoints in the SD card. If there are, then read them from the array:
  if (newWaypoint())
  {
    waypoint_counter++;
    String waypoints[MAX_WAYPOINTS]; // Create an array to store the waypoints
    readWaypoints(waypoints); // Pass the array to the function
    Serial.print("Number of waypoints: "); // print the number of waypoints to serial Monitor
    Serial.println(waypoint_counter);
  }

  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0)
  {
    if (gps.encode(ss.read()))
    {
      displayGpsInfo();
    }
  }

// The directions for the motors 
  startCar();
  delay(1000);
  stopCar();
  delay(1000);
  leftTurn();
  delay(1000);
  rightTurn();
  delay(1000);

  if (SerialBT.available())
  {
    buffer = SerialBT.readStringUntil('\n');
    // Process the received data
    // ...
  }
}

void displayGpsInfo()
{
  //Prints the location if lat-lng information was recieved
  Serial.print(F("Location: "));
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  //Prints invalid if no information was recieved in regards to location.
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  //Prints the recieved GPS module date if it was decoded in a vaild response.
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    //Prints invalid oterwise.
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  // prints the recieved GPS Module time if it was decoded in a valid response.
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    //Print invalid oterwise.
    Serial.print(F("INVALID"));
  }

  Serial.println();
  displayCompassInfo();
}

void displayCompassInfo()
{
  // all function for compass
  int x, y, z, a, b;
  char myArray[3];

  compass.read();

  x = compass.getX();
  y = compass.getY();
  z = compass.getZ();

  a = compass.getAzimuth();

  b = compass.getBearing(a);

  compass.getDirection(myArray, a);

  Serial.print("X: ");
  Serial.print(x);

  Serial.print(" Y: ");
  Serial.print(y);

  Serial.print(" Z: ");
  Serial.print(z);

  Serial.print(" Azimuth: ");
  Serial.print(a);

  Serial.print(" Bearing: ");
  Serial.print(b);

  Serial.print(" Direction: ");
  Serial.print(myArray[0]);
  Serial.print(myArray[1]);
  Serial.print(myArray[2]);

  Serial.println();

  delay(1000);
}

// Place the code related to reading waypoints from SD card and checking for new waypoints here
// Implement the functions: newWaypoint() and readWaypoints() as per your requirements.
// Example function signatures:

void readWaypoints(String waypoints[])
{
  // Open the file containing the waypoints
  File myFile = SD.open("waypoints.txt", FILE_READ);

  // Check if the file is opened successfully
  if (myFile)
  {
    int index = 0; // Index for storing waypoints in the array

    // Read waypoints from the SD card and store them in the waypoints array
    while (myFile.available())
    {
      String buffer = myFile.readStringUntil('\n');
      waypoints[index] = buffer; // Store the waypoint in the array
      index++; // Increment the index for the next waypoint
    }

    myFile.close();
  }
}

// This is where the motors get the inputs for the directions for the motors.
void startCar(){
  digitalWrite(L298N_IN1, HIGH); //27,16,17,25
  digitalWrite(L298N_IN2, LOW);
  digitalWrite(L298N_IN3, HIGH);
  digitalWrite(L298N_IN4, LOW);
}
void stopCar(){
  digitalWrite(L298N_IN1, LOW);
  digitalWrite(L298N_IN2, LOW);
  digitalWrite(L298N_IN3, LOW);
  digitalWrite(L298N_IN4, LOW);
}
void leftTurn(){
  digitalWrite(L298N_IN1, LOW);
  digitalWrite(L298N_IN2, HIGH);
  digitalWrite(L298N_IN3, HIGH);
  digitalWrite(L298N_IN4, LOW);
}
void rightTurn(){
  digitalWrite(L298N_IN1, HIGH);
  digitalWrite(L298N_IN2, LOW);
  digitalWrite(L298N_IN3, LOW);
  digitalWrite(L298N_IN4, HIGH);
}

This is what it is tell us on the Serial Monitor:

clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00

mode:DIO, clock div:1

load:0x3fff0030,len:1184

load:0x40078000,len:13260

load:0x40080400,len:3028

entry 0x400805e4

The device started, now you can pair it with bluetooth!

Simple Test with TinyGPS++ and attached GT-U7 GPS module

Testing TinyGPSPlus library v. 1.0.2

SD card initialized.

The usual Arduino debugging approach is to put Serial.print statements at various places in the program, to see where it is stuck, and display values of selected variables. Check if the values make sense.

Already been done....several ,,,,,,,,,,,, Inav is just one.

What type arduino are you using?

Software serial is going to be a pain with everything else that is going on, use hardware serial if at all possible.

All those delays will wreak havoc with the serial communications.

The WeMos D1 R32 os the microcontroller being used.

We was Initially trying to print all of that over bluetooth, but that way may be better thank you.

So it will be best not to use Bluetooth of at all possible?

This is what the Serial Monitor is showing me now.
Location: INVALID Date/Time: INVALID INVALID
X: -1413 Y: 7968 Z: 5850 Azimuth: 100 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -1416 Y: 7973 Z: 5857 Azimuth: 100 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -1397 Y: 7973 Z: 5867 Azimuth: 99 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -1397 Y: 7987 Z: 5867 Azimuth: 99 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -1340 Y: 8143 Z: 5767 Azimuth: 99 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -1335 Y: 8217 Z: 5732 Azimuth: 99 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -1555 Y: 8427 Z: 5785 Azimuth: 100 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -1712 Y: 8461 Z: 5767 Azimuth: 101 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -1716 Y: 8455 Z: 5767 Azimuth: 101 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -1716 Y: 8452 Z: 5755 Azimuth: 101 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -1726 Y: 8445 Z: 5755 Azimuth: 101 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -1710 Y: 8457 Z: 5760 Azimuth: 101 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -2542 Y: 7655 Z: 5330 Azimuth: 108 Bearing: 4 Direction: E
Location: INVALID Date/Time: INVALID INVALID
X: -3591 Y: 7081 Z: 5777 Azimuth: 116 Bearing: 5 Direction: ESE
Location: INVALID Date/Time: INVALID INVALID
X: -3623 Y: 7160 Z: 5657 Azimuth: 116 Bearing: 5 Direction: ESE
Location: INVALID Date/Time: INVALID INVALID
X: -3602 Y: 7108 Z: 5635 Azimuth: 116 Bearing: 5 Direction: ESE
Location: INVALID Date/Time: INVALID INVALID
X: -3591 Y: 7141 Z: 5622 Azimuth: 116 Bearing: 5 Direction: ESE
Location: INVALID Date/Time: INVALID INVALID
X: -3477 Y: 6656 Z: 4947 Azimuth: 117 Bearing: 5 Direction: ESE
Location: INVALID Date/Time: INVALID INVALID
X: -3476 Y: 6653 Z: 4962 Azimuth: 117 Bearing: 5 Direction: ESE
Location: INVALID Date/Time: INVALID INVALID
X: -3471 Y: 6643 Z: 4967 Azimuth: 117 Bearing: 5 Direction: ESE
Location: INVALID Date/Time: INVALID INVALID
X: -3473 Y: 6658 Z: 4967 Azimuth: 117 Bearing: 5 Direction: ESE
Location: INVALID Date/Time: INVALID INVALID
X: -3477 Y: 6643 Z: 4967 Azimuth: 117 Bearing: 5 Direction: ESE
Location: INVALID Date/Time: INVALID INVALID
X: -3471 Y: 6662 Z: 4975 Azimuth: 117 Bearing: 5 Direction: ESE

The issues I am having now is getting it to read my waypoints, get waypoints, nothing going to Bluetooth and Motor are just running not waiting to get the waypoint before they start.

Here is the code I am working with:

#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <QMC5883LCompass.h>
#include <SPI.h>
#include <SD.h>
#include <L298NX2.h>
#include <BluetoothSerial.h>

/*
   This sketch demonstrates the normal use of a TinyGPS++(TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and using the 
   9600-baud serial GPS device hooked up on pins 36(rx) and 39(tx) and a QMC5883 Magnetic Compass
   connected to the SCL/SDA pins.
*/

const int chipSelect = 5; // for sd card module
static const int RXPin = 36, TXPin = 39; // RX and TX pins are reverse on the board RX goto 39 and TX goto 36 
static const uint32_t GPSBaud = 9600;

// Assign a Unique ID to the QMC5883 Compass Sensor
QMC5883LCompass compass;
TinyGPSPlus gps; // The TinyGPSPlus object
SoftwareSerial ss(RXPin, TXPin); // The serial connection to the GPS device

// Initializing waypoint constants and variables
#define MAX_WAYPOINTS 10 // maximum waypoints to be stored in the SD Card

int waypoint_counter = 0; // counts the number of waypoints stored
int current_waypoint = 0; // index of the current waypoint 
bool reached_waypoint = false; // flag for reaching the waypoint
float target_heading, current_heading; // target and current headings

//right side motor control
int L298N_IN1 = 27;
int L298N_IN2 = 16;

//left side motor control
int L298N_IN3 = 17;
int L298N_IN4 = 25;

BluetoothSerial SerialBT;
String buffer;

void setup()
{
  Serial.begin(115200);
  SerialBT.begin("DRT23"); //Bluetooth device name
  Serial.println("\nThe device started, now you can pair it with bluetooth!");
  ss.begin(GPSBaud);
  compass.init();

  Serial.println(F("Simple Test with TinyGPS++ and attached GT-U7 GPS module"));
  Serial.print(F("Testing TinyGPSPlus library v. "));
  Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println();

  // setup SD card
  if (!SD.begin(chipSelect)) {
    Serial.println("SD card failed or not present.");
  }
  else {
    Serial.println("SD card initialized.");
  }

  pinMode(L298N_IN1, OUTPUT);
  pinMode(L298N_IN2, OUTPUT);
  pinMode(L298N_IN3, OUTPUT);
  pinMode(L298N_IN4, OUTPUT);
  

}
  
  int previous_waypoint_counter = 0; // Previous count of Waypoints

  bool newWaypoint()
  {
    // Check if there are new waypoints in the SD card
    // Return true if there are new waypoints, false otherwise
    int current_waypoint_counter = 0; // Get the current count of waypoints

    // Open the file containing the waypoints
    File file = SD.open("waypoints.txt", FILE_READ);

    // If the file is opened successfully
    if (file)
    {
      // Count the number of lines (waypoints) in the file
      while (file.available())
      {
        if (file.read() == '\n')
        {
          current_waypoint_counter++;
        }
      }

      // close the file
      file.close();
    }

    // Compare the current count with the previous count
    bool hasNewWaypoints = (current_waypoint_counter > previous_waypoint_counter);

    // Update the previous count with the current count
    previous_waypoint_counter = current_waypoint_counter;

    return hasNewWaypoints;

  }


// The loop function is where the navigation code goes.
void loop()
{
  // checking to see if there are any new waypoints in the SD card. If there are, then read them from the array:
  if (newWaypoint())
  {
    waypoint_counter++;
    String waypoints[MAX_WAYPOINTS]; // Create an array to store the waypoints
    readWaypoints(waypoints); // Pass the array to the function
    Serial.print("Number of waypoints: "); // print the number of waypoints to serial Monitor
    Serial.println(waypoint_counter);
  }

  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0)
  {
    if (gps.encode(ss.read()))
    {
      displayGpsInfo();
    }
  }

// The directions for the motors 
  startCar();
  delay(1000);
  stopCar();
  delay(1000);
  leftTurn();
  delay(1000);
  rightTurn();
  delay(1000);

  if (SerialBT.available())
  {
    buffer = SerialBT.readStringUntil('\n');
    // Process the received data
    // ...
  }
}

void displayGpsInfo()
{
  //Prints the location if lat-lng information was recieved
  Serial.print(F("Location: "));
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  //Prints invalid if no information was recieved in regards to location.
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  //Prints the recieved GPS module date if it was decoded in a vaild response.
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    //Prints invalid oterwise.
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  // prints the recieved GPS Module time if it was decoded in a valid response.
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    //Print invalid oterwise.
    Serial.print(F("INVALID"));
  }

  Serial.println();
  displayCompassInfo();
}

void displayCompassInfo()
{
  // all function for compass
  int x, y, z, a, b;
  char myArray[3];

  compass.read();

  x = compass.getX();
  y = compass.getY();
  z = compass.getZ();

  a = compass.getAzimuth();

  b = compass.getBearing(a);

  compass.getDirection(myArray, a);

  Serial.print("X: ");
  Serial.print(x);

  Serial.print(" Y: ");
  Serial.print(y);

  Serial.print(" Z: ");
  Serial.print(z);

  Serial.print(" Azimuth: ");
  Serial.print(a);

  Serial.print(" Bearing: ");
  Serial.print(b);

  Serial.print(" Direction: ");
  Serial.print(myArray[0]);
  Serial.print(myArray[1]);
  Serial.print(myArray[2]);

  Serial.println();

  delay(1000);
}

// Place the code related to reading waypoints from SD card and checking for new waypoints here
// Implement the functions: newWaypoint() and readWaypoints() as per your requirements.
// Example function signatures:

void readWaypoints(String waypoints[])
{
  // Open the file containing the waypoints
  File myFile = SD.open("waypoints.txt", FILE_READ);

  // Check if the file is opened successfully
  if (myFile)
  {
    int index = 0; // Index for storing waypoints in the array

    // Read waypoints from the SD card and store them in the waypoints array
    while (myFile.available())
    {
      String buffer = myFile.readStringUntil('\n');
      waypoints[index] = buffer; // Store the waypoint in the array
      index++; // Increment the index for the next waypoint
    }

    myFile.close();
  }
}

// This is where the motors get the inputs for the directions for the motors.
void startCar(){
  digitalWrite(L298N_IN1, HIGH); //27,16,17,25
  digitalWrite(L298N_IN2, LOW);
  digitalWrite(L298N_IN3, HIGH);
  digitalWrite(L298N_IN4, LOW);
}
void stopCar(){
  digitalWrite(L298N_IN1, LOW);
  digitalWrite(L298N_IN2, LOW);
  digitalWrite(L298N_IN3, LOW);
  digitalWrite(L298N_IN4, LOW);
}
void leftTurn(){
  digitalWrite(L298N_IN1, LOW);
  digitalWrite(L298N_IN2, HIGH);
  digitalWrite(L298N_IN3, HIGH);
  digitalWrite(L298N_IN4, LOW);
}
void rightTurn(){
  digitalWrite(L298N_IN1, HIGH);
  digitalWrite(L298N_IN2, LOW);
  digitalWrite(L298N_IN3, LOW);
  digitalWrite(L298N_IN4, HIGH);
}

With that many issues, you need to start over and get each part of the project working independently.

Fix the errors one by one, then combine the parts to make up the working package.

That what I was think about doing, and just rebuild the code.

I have rebuilt the code now it is working, now I am trying to if the code could be done better.
Also, I have a power supply issue with the motors and L298N motor driver trying to take all the power from GPS and compass.

Here is the code.

// DRT23- Autonomous Waypoint Navigation Car
// Arthur: Demetria Labat, Rony Akhter, & Tychicus Johnson
// Created 13 September 2023

#include <Wire.h> // Used by I2C and QMC5883L compass
#include <QMC5883LCompass.h>  // Library for the compass
#include <SoftwareSerial.h>  // Software Serial for Serial Communications
#include <TinyGPSPlus.h> // Tiny GPS Plus Library - Download from http://arduiniana.org/libraries/tinygpsplus/

/*
   This sketch demonstrates the normal use of a TinyGPS++(TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and using the 
   9600-baud serial GPS device hooked up on pins 36(rx) and 39(tx) and a QMC5883 Magnetic Compass
   connected to the SCL/SDA pins.
*/

static const int RXPin = 36, TXPin = 39; // RX and TX pins are reverse on the board RX goto 39 and TX goto 36 
static const uint32_t GPSBaud = 9600; // Baud rate for GPS communication

// Assign a Unique ID to the QMC5883 Compass Sensor
QMC5883LCompass compass; // QMC5883L Compass object
TinyGPSPlus gps; // The TinyGPSPlus object
SoftwareSerial ss(RXPin, TXPin); // The serial connection to the GPS device

// setting up the value longitude, latitude, bearing, and heading
float latc,logc; // Current latitude and longitude
float latd=32.2994318,logd=-90.2126861; // Destination latitude and longitude
float bearing; // Bearing angle between current and destination points
float heading; // Compass heading

// Initializing Motors
// Motor A connections
int enA = 2; // speed control pin for left side
int in1 = 27; // left front motor
int in2 = 16; // left rear motor
// Motor B connections
int enB = 4; // speed control pin for right side
int in3 = 17; // right front motor
int in4 = 25; // right rear motor

void setup() 
{
  Wire.begin(); // Initialize I2C communication
  Serial.begin(115200); // Initialize serial communication with the computer
  ss.begin(GPSBaud); // Initialize serial communication with the GPS device
  compass.init(); // Initialize the compass sensor

// 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);

}

void loop() 
{

  headingcal(); // Call function to read compass heading
    delay(200);
  gpsdata();    // Call function to read GPS data
    delay(200);
  gpsheading(); // Call function to calculate GPS heading
    delay(200);
  steering();   // Call function to control motors based on heading
    delay(200);

}

// GPS data retrieval function
void gpsdata()
{
  smartDelay(1000); // Wait for GPS data to stabilize
  unsigned long start;
  double lat_val, lng_val, alt_m_val;
  bool loc_valid, alt_valid;
  lat_val = gps.location.lat();
  loc_valid = gps.location.isValid();
  lng_val = gps.location.lng();
  alt_m_val = gps.altitude.meters();
  alt_valid = gps.altitude.isValid();

  if (!loc_valid)
    {
      Serial.print("Latitude : ");
      Serial.println("*****"); // Print placeholder for invalid latitude
      Serial.print("Longitude : ");
      Serial.println("*****"); // Print placeholder for invalid longitude
      delay(100);
    }

  else
    {
      Serial.println("GPS READING: ");
      // DegMinSec(lat_val);
      Serial.print("Latitude in Decimal Degrees : ");
      Serial.println(gps.location.lat(), 6); // Print latitude with 6 decimal places

      // DegMinSec(lng_val); 
      Serial.print("Longitude in Decimal Degrees : ");
      Serial.println(gps.location.lng(), 6); // Print longitude with 6 decimal places
      delay(100);
    }

  latc = lat_val;
  logc = lng_val;
}

// Smart delay function to wait for GPS data
static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do
    {
      while (ss.available()) 
      gps.encode(ss.read());
    } while (millis() - start < ms);
}

// GPS heading calculation function
void gpsheading()
{
  float x, y, deltalog, deltalat;
  deltalog = logd - logc;
  deltalat = latd - latc;

  x = cos (latd) * sin(deltalog);
  y=(cos(latc) * sin(latd)) -(sin(latc) *c os(latd) * cos(deltalog));
  
  bearing = (atan2(x, y)) * (180 / 3.14);
  Serial.print("bearing: ");
  Serial.println(bearing);

  float a,d,c;
  a = (((sin(deltalat / 2))) * (sin(deltalat / 2))) + ((cos(latc)) * (cos(latd)) * (((sin(deltalog / 2))) *(sin(deltalog / 2)))  );
  c = 2*(atan2(sqrt(a), sqrt(1 - a)));
  d = 6371 * c; 
  //Serial.println(d);
}

// Compass heading calculation function
void headingcal()
{
  int x, y, z;
  char myArray[3];
	compass.read(); // Read data from the compass sensor
  x = compass.getX();
  y = compass.getY();
  z = compass.getZ();
  delay(100);

  heading=atan2(x, y) / 0.0174532925;
  if(heading < 0) 
    {
      heading += 360;
    }
  
  heading = 360 - heading; // N=0/360, E=90, S=180, W=270
  Serial.print("heading: ");
  Serial.println(heading);  
}

// Motor control functions
void steering()
{
  float finalv;
  finalv = heading / bearing;
  Serial.print("finalv: ");
  Serial.println(finalv);
    
  if(finalv>=0&&finalv<=1)
    {
      forward();  // Move forward
    }

  else if(finalv >1 && finalv <=8)
    {
      left(); // Turn left
    }

  else if(finalv <=13 && finalv >=8)
    {
      right();  // Turn right
    }

  else if(logd==logc && latc==latd)
    {
      stop1();  // Stop if destination is reached
    }
}

// Motor control functions for different directions
void forward()
{
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);
  digitalWrite(in3,HIGH);
  digitalWrite(in4,LOW);
}

void right()
{
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);
  digitalWrite(in3,LOW);
  digitalWrite(in4,HIGH);
}

void left()
{
  digitalWrite(in1,LOW);
  digitalWrite(in2,HIGH);
  digitalWrite(in3,HIGH);
  digitalWrite(in4,LOW);
}

void back()
{
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);
  digitalWrite(in3,HIGH);
  digitalWrite(in4,LOW);
}
void stop1()
{
  digitalWrite(in1,LOW);
  digitalWrite(in2,LOW);
  digitalWrite(in3,LOW);
  digitalWrite(in4,LOW);
}

This is what the Serial Monitor is giving me.
DRT23 rebuilded data log.txt (2.7 KB)

What Serial Monitor show when gps is detected

GPS READING:
Latitude in Decimal Degrees : 32.298096
Longitude in Decimal Degrees : -90.212453
bearing: -6.21
finalv: -16.96
heading: 105.24
GPS READING:
Latitude in Decimal Degrees : 32.298096
Longitude in Decimal Degrees : -90.212453
bearing: -6.21
finalv: -16.95
heading: 111.22
GPS READING:
Latitude in Decimal Degrees : 32.298096
Longitude in Decimal Degrees : -90.212453
bearing: -6.21
finalv: -17.91
heading: 100.99
GPS READING:
Latitude in Decimal Degrees : 32.298139
Longitude in Decimal Degrees : -90.212618
bearing: -1.93
finalv: -52.31
heading: 99.96
GPS READING:
Latitude in Decimal Degrees : 32.298126
Longitude in Decimal Degrees : -90.212622
bearing: -1.70
finalv: -58.76
heading: 99.88
GPS READING:
Latitude in Decimal Degrees : 32.298126
Longitude in Decimal Degrees : -90.212622
bearing: -1.70
finalv: -58.72
heading: 100.05
GPS READING:
Latitude in Decimal Degrees : 32.298126
Longitude in Decimal Degrees : -90.212622
bearing: -1.70
finalv: -58.82
heading: 99.46
GPS READING:
Latitude in Decimal Degrees : 32.298126
Longitude in Decimal Degrees : -90.212622
bearing: -1.70
finalv: -58.47
heading: 100.10
GPS READING:
Latitude in Decimal Degrees : 32.298126
Longitude in Decimal Degrees : -90.212622
bearing: -1.70
finalv: -58.85
heading: 99.85
GPS READING:
Latitude in Decimal Degrees : 32.299114
Longitude in Decimal Degrees : -90.212812
bearing: 14.58
finalv: 7.06
heading: 102.80
GPS READING:
Latitude in Decimal Degrees : 32.299003
Longitude in Decimal Degrees : -90.212772
bearing: 7.11
finalv: 14.46
heading: 103.16
GPS READING:
Latitude in Decimal Degrees : 32.298962
Longitude in Decimal Degrees : -90.212756
bearing: 5.31
finalv: 19.44
heading: 102.99
GPS READING:
Latitude in Decimal Degrees : 32.299007
Longitude in Decimal Degrees : -90.212757
bearing: 6.52
finalv: 15.79
heading: 102.29
GPS READING:
Latitude in Decimal Degrees : 32.299042
Longitude in Decimal Degrees : -90.212770
bearing: 7.80
finalv: 13.12
heading: 102.59
GPS READING:
Latitude in Decimal Degrees : 32.299042
Longitude in Decimal Degrees : -90.212770
bearing: 7.80
finalv: 13.16
heading: 103.11

What Serial Monitor show when gps is not detected

heading: 337.95
Latitude : *****
Longitud : *****
bearing: -32.62
finalv: -10.36
heading: 13.24
Latitude : *****
Longitud : *****
bearing: -32.62
finalv: -0.41
heading: 104.95
Latitude : *****
Longitud : *****
bearing: -32.62
finalv: -3.22
heading: 105.10
Latitude : *****
Longitud : *****
bearing: -32.62
finalv: -3.22
heading: 105.58
Latitude : *****
Longitud : *****
bearing: -32.62
finalv: -3.24

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.