Bluetooth Command Reception Problems

I am working on a project where I am building a GPS Car. At first I had the entire thing working but I decided to add a second gps for reliability issues. Ever since then, I have been unable to get it to respond to Bluetooth commands I send from a serial app on my phone. It does however send data via Bluetooth which I can read on my phone but the other way doesn't work. I need bluetooth commands to switch between waypoint lists, as well as set new waypoints based on the current location. Any help is appreciated.

Here is the new code:

#include <TinyGPS++.h>
#include <Wire.h>
#include <QMC5883LCompass.h>
#include <SoftwareSerial.h> // For the second GPS module
#include <Adafruit_GPS.h>

// Constants
static const uint32_t GPSBaud = 9600;
#define HEADING_TOLERANCE 5
#define WAYPOINT_DIST_TOLERANCE 1
#define stopwaypoint 5
#define MAX_WAYPOINTS 10
#define buttonPin 12

// GPS and Compass objects
SoftwareSerial GPS1_Serial(10, 11); // RX, TX for GPS1
TinyGPSPlus gps;
TinyGPSPlus gps1;
Adafruit_GPS GPS(&Serial3);
Adafruit_GPS GPS1(&GPS1_Serial);
QMC5883LCompass compass;

// GPS variables
float currentLat, currentLong;
float targetLat, targetLong;
int distanceToTarget, originalDistanceToTarget;
int current_waypoint = 0;

//compass variables
int targetHeading;              
int currentHeading;            
int headingError;               // signed (+/-) difference between targetHeading and currentHeading

// Waypoints
float waypointList[MAX_WAYPOINTS][2] = {
  {23.202905, 72.658213},
  {23.202849, 72.658091},
  {23.202746, 72.658156},
  {23.202841, 72.658310},
  {23.202839, 72.658197}
};

// Preset Waypoints
float presetWaypointList[MAX_WAYPOINTS][2] = {
  {23.201336, 72.660916},
  {23.201501, 72.660902}, 
  {23.201659, 72.660930}, 
  {23.201779, 72.660978},
  {23.201927, 72.661102}
  // Add more if needed
};

// Bluetooth command handling
String bluetoothCommand = "";
String inputString = "";
bool stringComplete = false;
int id = 0;
int mode;

String val[5];
int nprint = 0;
int aprint = 0;

bool useGPS1 = false;

void setup() {
  Serial.begin(9600);
  GPS1_Serial.begin(9600);
  Serial2.begin(9600); // Bluetooth
  Serial3.begin(9600); // GPS

  pinMode(buttonPin, INPUT_PULLUP);

  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPS.sendCommand(PGCMD_NOANTENNA);

  GPS1.begin(9600);
  GPS1.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS1.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPS1.sendCommand(PGCMD_NOANTENNA);

  compass.init();
  compass.setCalibration(-1056, 1358, -1380, 638, -1118, 0);
  
  Serial.println("Start");

  Serial.println(waypointList[0][0], 6);
  Serial.println(waypointList[0][1], 6);

  Serial.println(waypointList[1][0], 6);
  Serial.println(waypointList[1][1], 6);

  // Initialize target latitude and longitude
  targetLat = waypointList[0][0];
  targetLong = waypointList[0][1];
}

void loop() {
  // Read data from both GPS modules
  while (Serial3.available() > 0) {
    if (gps.encode(Serial3.read())) {
      // Read data from GPS until no more data is available
    }
  }
  while (GPS1_Serial.available() > 0) {
    if (gps1.encode(GPS1_Serial.read())) {
      // Read data from GPS until no more data is available
    }
  }
  
  // Process GPS data
  processGPS();

  // Process Bluetooth commands continuously
  processBluetoothCommand();

  // Check if the button is pressed
  if (digitalRead(buttonPin) == LOW) {
    stopRobotAndSendStats();
  } else {
    // Proceed with navigation if GPS data is valid
    if (currentLong > 0 && targetLong > 0) {
      currentHeading = readCompass();
      calcDesiredTurn();
      move_robot();

      aprint++;
      if (aprint == 200) {
        aprint = 0;
        Serial2.print("wp "); Serial2.print(current_waypoint);
        Serial2.print("_ch "); Serial2.print(currentHeading);
        Serial2.print("_th "); Serial2.print(targetHeading);
        Serial2.print("_eh "); Serial2.print(headingError);
        Serial2.print("_di "); Serial2.print(distanceToTarget);
        Serial2.print("_st1 "); Serial2.print(gps.satellites.value(), 6);
        Serial2.print("_st2 "); Serial2.print(gps1.satellites.value(), 6);
        Serial2.print("_gn "); Serial2.print(useGPS1 ? 2 : 1);
        Serial2.println();
      }
    } else {
      // Print a message if GPS data is not valid
      Serial2.println("Check GPS");
    }
  }
}


void processGPS() {
  // Reset current coordinates
  currentLat = 0.00;
  currentLong = 0.00;

  // Check if GPS 1 is in use
  if (!useGPS1) {
    // If GPS 1 is not in use, try using it
    if (gps.location.isValid() && gps.satellites.value() >= 3) { // Adjust the minimum satellites as needed
      currentLat = gps.location.lat();
      currentLong = gps.location.lng();
      // Calculate distance and course to waypoint
      distanceToWaypoint();
      courseToWaypoint();
    }
    else {
      // If GPS 1 fails or has insufficient satellites, switch to GPS 2
      if (gps1.location.isValid() && gps1.satellites.value() >= 3) { // Adjust the minimum satellites as needed
        currentLat = gps1.location.lat();
        currentLong = gps1.location.lng();
        // Calculate distance and course to waypoint
        distanceToWaypoint();
        courseToWaypoint();
        useGPS1 = true; // Switch to GPS 2
      }
    }
  }
  else {
    // If GPS 1 is in use, try using it
    if (gps1.location.isValid() && gps1.satellites.value() >= 3) { // Adjust the minimum satellites as needed
      currentLat = gps1.location.lat();
      currentLong = gps1.location.lng();
      // Calculate distance and course to waypoint
      distanceToWaypoint();
      courseToWaypoint();
    }
    else {
      // If GPS 1 fails or has insufficient satellites, switch to GPS 2
      if (gps.location.isValid() && gps.satellites.value() >= 3) { // Adjust the minimum satellites as needed
        currentLat = gps.location.lat();
        currentLong = gps.location.lng();
        // Calculate distance and course to waypoint
        distanceToWaypoint();
        courseToWaypoint();
        useGPS1 = false; // Switch to GPS 1
      }
    }
  }
}


int distanceToWaypoint()
{
  float delta = radians(currentLong - targetLong);
  float sdlong = sin(delta);
  float cdlong = cos(delta);
  float lat1 = radians(currentLat);
  float lat2 = radians(targetLat);
  float slat1 = sin(lat1);
  float clat1 = cos(lat1);
  float slat2 = sin(lat2);
  float clat2 = cos(lat2);
  delta = (clat1 * slat2) - (slat1 * clat2 * cdlong);
  delta = sq(delta);
  delta += sq(clat2 * sdlong);
  delta = sqrt(delta);
  float denom = (slat1 * slat2) + (clat1 * clat2 * cdlong);
  delta = atan2(delta, denom);
  distanceToTarget =  delta * 6372795;

  // check to see if we have reached the current waypoint
  if (distanceToTarget <= WAYPOINT_DIST_TOLERANCE-1)
  {
    //berhenti();
    delay(stopwaypoint*1000);
    nextWaypoint();
  }
  return distanceToTarget;
}


int readCompass() {
  compass.read();
  return compass.getAzimuth();
}

int courseToWaypoint()
{
  float dlon = radians(targetLong - currentLong);
  float cLat = radians(currentLat);
  float tLat = radians(targetLat);
  float a1 = sin(dlon) * cos(tLat);
  float a2 = sin(cLat) * cos(tLat) * cos(dlon);
  a2 = cos(cLat) * sin(tLat) - a2;
  a2 = atan2(a1, a2);
  if (a2 < 0.0)
  {
    a2 += TWO_PI;
  }
  targetHeading = degrees(a2);
  return targetHeading;
}


void nextWaypoint()
{
  current_waypoint++;
  targetLat = waypointList[current_waypoint][0];
  targetLong = waypointList[current_waypoint][1];

  if ((targetLat == 0 && targetLong == 0))    // last waypoint reached?
  {
    //berhenti();
    Serial2.println("FINISH");
    while (1); //PRESS RESET BUTTON
  }
  else
  {
    processGPS();
    distanceToTarget = originalDistanceToTarget = distanceToWaypoint();
    courseToWaypoint();
  }
}


int error_output;
void calcDesiredTurn(void)
{
  headingError = targetHeading - currentHeading;  // calculate where we need to turn to head to destination

  // adjust for compass wrap
  if (headingError < -180)
    headingError  += 360;
  if (headingError > 180)
    headingError -= 360;


  // calculate which way to turn to intercept the targetHeading
  if (abs(headingError) <= HEADING_TOLERANCE)      // if within tolerance, don't turn
    error_output = 0;
  else if (headingError < 60 && headingError > -60)
  {
    error_output = headingError;
  }
  else if (headingError >= 60)
    error_output = 100;
  else if (headingError <= -60)
    error_output = -100;

}
float Kp, Kd;
void move_robot()
{
  if (error_output == 0)
  {
    //forward();
    Serial2.println("fwd");
  }
  else if (error_output < 60)
  {
    if (error_output < 0)
      //left();
      Serial2.println("lft");
    else
      //right();
      Serial2.println("rgt");
  }
  else if (error_output == 100)
  {
   //sharpright();
  }
  else if (error_output == -100)
  {
    //sharpleft();
  }
}

void processBluetoothCommand() {
    while (Serial2.available()) {
        char inChar = (char)Serial2.read();
        if (inChar == '\n') {
            // End of command, process it
            processCommand(bluetoothCommand);
            bluetoothCommand = ""; // Clear command for next one
        } else {
            // Append character to command
            bluetoothCommand += inChar;
        }
    }
}

void processCommand(String command) {
    if (command == "swp1") {
        waypointList[0][0] = currentLat;
        waypointList[0][1] = currentLong;
    } else if (command == "swp2") {
        waypointList[1][0] = currentLat;
        waypointList[1][1] = currentLong;
    } else if (command == "swp3") {
        waypointList[2][0] = currentLat;
        waypointList[2][1] = currentLong;
    } else if (command == "swp4") {
        waypointList[3][0] = currentLat;
        waypointList[3][1] = currentLong;
    } else if (command == "swp5") {
        waypointList[4][0] = currentLat;
        waypointList[4][1] = currentLong;
    } else if (command == "pswp") {
        for (int i = 0; i < MAX_WAYPOINTS; i++) {
            waypointList[i][0] = presetWaypointList[i][0];
            waypointList[i][1] = presetWaypointList[i][1];
        }
        Serial2.println("Waypoint list swapped to preset!");
    }
    // Add more command handling as needed
}

void serialEvent2() //bluetooth
{
    while (Serial2.available())
    {
        char inChar = (char)Serial2.read();
        if (inChar == '\n') // Assuming newline marks the end of a command
        {
            processBluetoothCommand();
            bluetoothCommand = ""; // Clear the command for the next one
        }
        else
        {
            bluetoothCommand += inChar;
        }
    }
}

void stopRobotAndSendStats() {
  //berhenti(); // Stop the robot
  Serial2.print("la "); Serial2.print(currentLat, 6);
  Serial2.print("_lo "); Serial2.print(currentLong, 6);
  Serial2.print("_la "); Serial2.print(targetLat, 6);
  Serial2.print("_lo "); Serial2.print(targetLong, 6);
  Serial2.print("_ch "); Serial2.print(readCompass());
  Serial2.print("_st1 "); Serial2.print(gps.satellites.value(), 6);
  Serial2.print("_st2 "); Serial2.print(gps1.satellites.value(), 6);
  Serial2.print("_gn "); Serial2.print(useGPS1 ? 2 : 1);
  Serial2.println();

  Serial.print("la "); Serial.print(currentLat, 6);
  Serial.print("_lo "); Serial.print(currentLong, 6);
  Serial.print("_la "); Serial.print(targetLat, 6);
  Serial.print("_lo "); Serial.print(targetLong, 6);
  Serial.print("_ch "); Serial.print(readCompass());
  Serial.print("_st1 "); Serial.print(gps.satellites.value(), 6);
  Serial.print("_st2 "); Serial.print(gps1.satellites.value(), 6);
  Serial.print("_gn "); Serial.print(useGPS1 ? 2 : 1);
  Serial.println();
  delay(1000);
}

And the old one:

#include <TinyGPS++.h>

static const uint32_t GPSBaud = 9600;
TinyGPSPlus gps;

// Compass navigation
#include <Wire.h>
#include <QMC5883LCompass.h>
QMC5883LCompass compass;
int targetHeading;              
int currentHeading;            
int headingError;               // signed (+/-) difference between targetHeading and currentHeading

#define HEADING_TOLERANCE 5     // tolerance +/- (in degrees) within which we don't attempt to turn to intercept targetHeading

#include "math.h"
#include <Adafruit_GPS.h>
Adafruit_GPS GPS(&Serial3);
float currentLat,
      currentLong;

int distanceToTarget,            // current distance to target (current waypoint)
    originalDistanceToTarget;    // distance to original waypoing when we started navigating to it

#define WAYPOINT_DIST_TOLERANE  1   //tolerance in meters to waypoint; once within this tolerance, will advance to the next waypoint
#define stopwaypoint 5                  //second
int current_waypoint = 0;

float waypointList[10][2] = {
  { 23.202905, 72.658213},
  { 23.202849, 72.658091}, 
  { 23.202746, 72.658156}, 
  { 23.202841, 72.658310},
  { 23.202839, 72.658197},
};

float presetWaypointList[10][2] = {
  { 23.201336, 72.660916},
  { 23.201501, 72.660902}, 
  { 23.201659, 72.660930}, 
  { 23.201779, 72.660978},
  { 23.201927, 72.661102},
  // ... you can continue for up to 10 waypoints
};

float targetLat = waypointList[0][0];
float targetLong = waypointList[0][1];

const int IR1 = 8;
const int IR2 = 9;

long duration;
int distance;

String bluetoothCommand = ""; // to accumulate characters from Bluetooth

void setup()
{
  Serial.begin(9600);         //Debug
  Serial3.begin(9600);       //GPS
  Serial2.begin(9600);        //Bluetooth

  pinMode(12, INPUT_PULLUP);
  setup_motor();
  
  GPS.begin(9600);                                // 9600 NMEA default speed
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);     // turns on RMC and GGA (fix data)
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);       // 1 Hz update rate
  GPS.sendCommand(PGCMD_NOANTENNA);                // turn off antenna status info
  delay(1000);

  compass.init();
  compass.setCalibration(-1215, 1033, -1236, 1112, -890, 0);
  
  pinMode(IR1, INPUT); 
  pinMode(IR2, INPUT); 

  Serial.println("Start");

  Serial.println(waypointList[0][0], 6);
  Serial.println(waypointList[0][1], 6);

  Serial.println(waypointList[1][0], 6);
  Serial.println(waypointList[1][1], 6);

}

String inputString = "";
String inputdata = "";
bool stringComplete = false;
int id = 0;
int mode;

String val[5];
int nprint = 0;
int aprint = 0;

void loop()
{
  int sensorVal = digitalRead(12);

  while (Serial3.available() > 0)
    if (gps.encode(Serial3.read()))
      processGPS();


  if (stringComplete)
  {
    Serial.println(inputString);
    int n = 0;
    for (int i = 0; i < 30; i++)
    {
      if (inputString[i] == 0)
      {
        n++;
        if (n == 4)
          break;
      }
      else
      {
        val[n] += inputString[i];
      }
    }

    if (val[1] == "1")
    {
      targetLat = val[2].toFloat();
      targetLong = val[3].toFloat();
    }


    inputString = "";
    val[1] = "";
    val[2] = "";
    val[3] = "";
    stringComplete = false;
  }


  if (sensorVal == LOW)
  {
    berhenti();
    //    Serial.print("la "); Serial.print(currentLat, 6);
    //    Serial.print("_lo "); Serial.print(currentLong, 6);
    //    Serial.print("_la "); Serial.print(targetLat, 6);
    //    Serial.print("_lo "); Serial.print(targetLong, 6);
    //    Serial.println();
    nprint++;
    if (nprint == 10000)
    {
      nprint = 0;

      Serial2.print("la "); Serial2.print(currentLat, 6);
      Serial2.print("_lo "); Serial2.print(currentLong, 6);
      Serial2.print("_la "); Serial2.print(targetLat, 6);
      Serial2.print("_lo "); Serial2.print(targetLong, 6);
      Serial2.print("_ch "); Serial2.print(currentHeading);
      Serial2.print("_st "); Serial2.print(gps.satellites.value(), 6);
      Serial2.println();
    }   
    processBluetoothCommand();
  }
  else if (sensorVal == HIGH)
  {  
  // if(IR1==HIGH && IR2==HIGH){ 
    if (currentLong > -1 && targetLong > -1)
    {

      currentHeading = readCompass();
      calcDesiredTurn();
      move_robot();

      //      Serial.print("_ch "); Serial.print(currentHeading);
      //      Serial.print("_th "); Serial.print(targetHeading);
      //      Serial.print("_eh "); Serial.print(headingError);
      //      Serial.print("_di "); Serial.print(distanceToTarget);
      //      Serial.println();


      aprint++;
      if (aprint == 200 )
      {
        aprint = 0;
        Serial2.print("wp "); Serial2.print(current_waypoint);
        Serial2.print("_ch "); Serial2.print(currentHeading);
        Serial2.print("_th "); Serial2.print(targetHeading);
        Serial2.print("_eh "); Serial2.print(headingError);
        Serial2.print("_di "); Serial2.print(distanceToTarget);
        Serial2.println();
      }

    }
    else
    {
      berhenti();
      Serial2.println("Check GPS");
    }
    /*}
    else{
      berhenti();
      Serial2.println("Obstacle Detected");
    }*/
  }
}

void processGPS()
{
  if (gps.location.isValid())
  {
    currentLat = gps.location.lat();
    currentLong = gps.location.lng();

    // update the course and distance to waypoint based on our new position
    distanceToWaypoint();
    courseToWaypoint();
  }
}

// returns course in degrees (North=0, West=270) from position 1 to position 2,
// both specified as signed decimal-degrees latitude and longitude.
// Because Earth is no exact sphere, calculated course may be off by a tiny fraction.
// copied from TinyGPS library
int courseToWaypoint()
{
  float dlon = radians(targetLong - currentLong);
  float cLat = radians(currentLat);
  float tLat = radians(targetLat);
  float a1 = sin(dlon) * cos(tLat);
  float a2 = sin(cLat) * cos(tLat) * cos(dlon);
  a2 = cos(cLat) * sin(tLat) - a2;
  a2 = atan2(a1, a2);
  if (a2 < 0.0)
  {
    a2 += TWO_PI;
  }
  targetHeading = degrees(a2);
  return targetHeading;
}

// returns distance in meters between two positions, both specified
// as signed decimal-degrees latitude and longitude. Uses great-circle
// distance computation for hypothetical sphere of radius 6372795 meters.
// Because Earth is no exact sphere, rounding errors may be up to 0.5%.
// copied from TinyGPS library
int distanceToWaypoint()
{
  float delta = radians(currentLong - targetLong);
  float sdlong = sin(delta);
  float cdlong = cos(delta);
  float lat1 = radians(currentLat);
  float lat2 = radians(targetLat);
  float slat1 = sin(lat1);
  float clat1 = cos(lat1);
  float slat2 = sin(lat2);
  float clat2 = cos(lat2);
  delta = (clat1 * slat2) - (slat1 * clat2 * cdlong);
  delta = sq(delta);
  delta += sq(clat2 * sdlong);
  delta = sqrt(delta);
  float denom = (slat1 * slat2) + (clat1 * clat2 * cdlong);
  delta = atan2(delta, denom);
  distanceToTarget =  delta * 6372795;

  // check to see if we have reached the current waypoint
  if (distanceToTarget <= WAYPOINT_DIST_TOLERANE-1)
  {
    berhenti();
    delay(stopwaypoint*1000);
    nextWaypoint();
  }
  return distanceToTarget;
}


int readCompass()
{
  compass.read();
  int a;
  a = compass.getAzimuth();
  return (a);
}

void nextWaypoint()
{
  current_waypoint++;
  targetLat = waypointList[current_waypoint][0];
  targetLong = waypointList[current_waypoint][1];

  if ((targetLat == 0 && targetLong == 0))    // last waypoint reached?
  {
    berhenti();
    Serial2.println("FINISH");
    while (1); //PRESS RESET BUTTON
  }
  else
  {
    processGPS();
    distanceToTarget = originalDistanceToTarget = distanceToWaypoint();
    courseToWaypoint();
  }
}


int error_output;
void calcDesiredTurn(void)
{
  headingError = targetHeading - currentHeading;  // calculate where we need to turn to head to destination

  // adjust for compass wrap
  if (headingError < -180)
    headingError  += 360;
  if (headingError > 180)
    headingError -= 360;


  // calculate which way to turn to intercept the targetHeading
  if (abs(headingError) <= HEADING_TOLERANCE)      // if within tolerance, don't turn
    error_output = 0;
  else if (headingError < 60 && headingError > -60)
  {
    error_output = headingError;
  }
  else if (headingError >= 60)
    error_output = 100;
  else if (headingError <= -60)
    error_output = -100;

}
float Kp, Kd;
void move_robot()
{
  if (error_output == 0)
  {
    forward();
  }
  else if (error_output < 60)
  {
    if (error_output < 0)
      left();
    else
      right();
  }
  else if (error_output == 100)
  {
   sharpright();
  }
  else if (error_output == -100)
  {
    sharpleft();
  }
}

void processBluetoothCommand()
{
    if (bluetoothCommand == "swp1")
    {
        waypointList[0][0] = currentLat;
        waypointList[0][1] = currentLong;
    }
    else if (bluetoothCommand == "swp2")
    {
        waypointList[1][0] = currentLat;
        waypointList[1][1] = currentLong;
    }
    else if (bluetoothCommand == "swp3")
    {
        waypointList[2][0] = currentLat;
        waypointList[2][1] = currentLong;
    }        
    else if (bluetoothCommand == "swp4")
    {
        waypointList[3][0] = currentLat;
        waypointList[3][1] = currentLong;
    }
    else if (bluetoothCommand == "swp5")
    {
        waypointList[4][0] = currentLat;
        waypointList[4][1] = currentLong;
    }
    else if (bluetoothCommand == "pswp")
    {
        for (int i = 0; i < 10; i++)
        {
            waypointList[i][0] = presetWaypointList[i][0];
            waypointList[i][1] = presetWaypointList[i][1];
        }
        Serial2.println("Waypoint list swapped to preset!");
    }
 targetLat = waypointList[0][0];
 targetLong = waypointList[0][1];
}

void serialEvent2() //bluetooth
{
    while (Serial2.available())
    {
        char inChar = (char)Serial2.read();
        if (inChar == '\n') // Assuming newline marks the end of a command
        {
            processBluetoothCommand();
            bluetoothCommand = ""; // Clear the command for the next one
        }
        else
        {
            bluetoothCommand += inChar;
        }
    }
}

Which Arduino board are you using ?

Hi, I am using the Arduino Mega

Then why do you want/need to use SoftwareSerial ?

Actually i want to add another layer of redundancy by having a second arduino mega onboard which will talk to this one and take over in case this fails.

I will leave aside questions about how the first Mega decides which GPS data is valid and how the second one knows that the first one has failed

What do your Serial.print() debug lines tell you is happening in the sketch ? For instance, does it actually receive any Bluetooth commands ?

Hi, the serial 2 is the bluetooth module. i get data about the current location, heading, number of sats, etc on both serial as well as bluetooth. it does send the data to bluetooth correctly however recieving data from bluetooth doesent work, i think it may have some problem in the processgpscommands() function but i could be wrong

Hi,
Actually all the ports are used up, the main serial is for comms with the laptop, the serial 1 is for communication with the second arduino (or atleast i plan to use it for that) the serial 2 is for bluetooth and serial 3 is for gps 1 so for gps 2 (backup) i had to use softserial.

You don't have such a function so I imagine that you mean the processGPS() function

I have not looked at in detail but seeing these 2 lines of code, are you sure that the logic is correct ?

                useGPS1 = true;  // Switch to GPS 2
...

                useGPS1 = false;  // Switch to GPS 1

In any case, that should not affect reception of Bluetooth data

What do you mean by both ?
What data from Bluetooth do you see printed ?

i am so sorry i meant processbluetoothcommand() function

I mean both the serial for computer as well as serial 2 for Bluetooth

You need to decide where you are going to read the data from Serial2 as you appear to be trying to do it in 2 places

Personally have always thought that serialEvent() functions were a waste of time

In any case, assuming that the Bluetooth command is received and stored in the bluetoothCommand variable and that you don't set it back to "" in the wrong place, where do you actually do anything with its value ? Certainly not in the likely sounding processBluetoothCommand() function

yea i noticed now that there is 2 different places reading the command. I will be honest i had ChatGPT look at the code first so it did this thing.

The intention is to send it to the processcommand() function and then do the respective function (either setting a waypoint or swapping lists)

My advice would be not to use the serialEvent() functions. Using them just tends to confuse things and they do nothing that you can't do by polling for serial data in your own function.

could you mabey suggest a code block to do so?

To do what ?

I guess to replace the entire serial function thing.

That is what your processBluetoothCommand() does, or would if you called it from loop()

A couple of suggestions

  • change the name of the function to something like getBluetoothCommand()
  • don't reset the bluetoothCommand variable to "" where you do otherwise reading the command will have been a waste of time
1 Like

Ok thanks for the suggestions I will try these and then let you know ASAP.

Good news!
this did the trick and now it works as expected. For anyone else, this is the code that worked:

void processBluetoothCommand() {
    while (Serial2.available()) {
        char inChar = (char)Serial2.read();
        if (inChar == '\n') {
            // End of command, process it
            processCommand(bluetoothCommand);
            bluetoothCommand = ""; // Clear command for next one
        } else {
            // Append character to command
            bluetoothCommand += inChar;
        }
    }
}

void processCommand(String command) {
    if (command.startsWith("swp")) {
        int waypointIndex = command.substring(3).toInt();
        if (waypointIndex >= 1 && waypointIndex <= MAX_WAYPOINTS) {
            waypointList[waypointIndex - 1][0] = currentLat;
            waypointList[waypointIndex - 1][1] = currentLong;
            Serial2.println("Waypoint " + String(waypointIndex) + " set to current location!");
            targetLat = waypointList[current_waypoint][0];
            targetLong = waypointList[current_waypoint][1];
        } else {
            Serial2.println("Invalid waypoint number!");
        }
    } else if (command == "pswp") {
        for (int i = 0; i < MAX_WAYPOINTS; i++) {
            waypointList[i][0] = presetWaypointList[i][0];
            waypointList[i][1] = presetWaypointList[i][1];
        }
        targetLat = waypointList[current_waypoint][0];
        targetLong = waypointList[current_waypoint][1];
        Serial2.println("Waypoint list swapped to preset!");
    }
    // Add more command handling as needed
}

To make it even more useful I suggest that you post the full working sketch