How to Fix Bluetooth Master to receive the data being sent by the slave

I have completed building a master-slave setup, fed the code to both systems but now the Arduino Bluetooth master is not showing the data being sent to it by the slave.
They have successfully been configured and they automatically connect upon power on.
The only problem is the master Bluetooth module displays incorrect data being sent to it.
I would love your ideas and directions
Here is my master’s Bluetooth code, the receiver.

boolean newData = true;
double latitude, longitude;
double lat, lng;
const byte maxDataLength = 100;
const byte numChars = 32;
char receivedChars[numChars];

boolean newdata = false;


void setup(){
Serial.begin(115200); // connect serial
Serial.println("");
Serial1.begin(9600); // BLUETOOTH MASTER



}
 
void loop (){
   recvWithStartEndMarkers();
    showNewData();
    
}
void showNewData() {
    if (newData) {
        Serial.print('<');
  Serial.print("latitude:");
   Serial.print(latitude, 7);
  Serial.print(','); // a comma
  Serial.print("longitude:");
  Serial.print(longitude, 7);
    Serial.println('>');
    //Serial.println(receivedChars);
    
  
    Serial.print('<');
    Serial.print("lat:");
   Serial.print(lat, 7);
  Serial.print(','); // a comma
   Serial.print("lng:");
   Serial.print(lng, 7);
    Serial.println('>');
    
   Serial.println(receivedChars);      
    }
   
        newdata = false;
}

void recvWithStartEndMarkers()
{
     static boolean recvInProgress = false;
     static byte ndx = 0;
     char startMarker = '<';
     char endMarker = '>';
     char rc;
 
     if (Serial3.available() > 0) 
     {
          rc = Serial3.read();
          if (recvInProgress == true) 
          {
               if (rc != endMarker) 
               {
                    receivedChars[ndx] = rc;
                    ndx++;
                    if (ndx > maxDataLength) { ndx = maxDataLength; }
               }
               else 
               {
                     receivedChars[ndx] = '\0'; // terminate the string
                     recvInProgress = false;
                     ndx = 0;
                     newData = true;
               }
          }
          else if (rc == startMarker) { recvInProgress = true; }
     }
 
}

also here is my Bluetooth slave code which is the sender.

#include <TinyGPS++.h>
TinyGPSPlus gps1;
TinyGPSPlus gps2;
double latitude, longitude;
double lat, lng;


void setup() {
  Serial.begin(115200);
  Serial.println("The GPS Received Signal:");
  Serial1.begin(9600); // connect gps sensor
  Serial2.begin(9600); // connect gps sensor
Serial3.begin(9600); //Bluetooth slave
}
long data;
void loop() {
  while (Serial1.available())
  {
    data = Serial1.read();
    if (gps1.encode(data) > 0)
    {
      latitude = (gps1.location.lat());
      longitude = (gps1.location.lng());
      Serial.print("latitude:");
      Serial.println(latitude, 7);
      Serial.print("longitude:");
      Serial.println(longitude, 7);
    
    }
  }

  while (Serial2.available())
  {
    data = Serial2.read();
    if (gps2.encode(data) > 0)
    {
      lat = (gps2.location.lat());
      lng = (gps2.location.lng());
      Serial.print("lat:");
      Serial.println(lat, 7);
      Serial.print("long:");
      Serial.println(lng, 7);
     
    }
    
  }
 
  Serial.print('<');
   Serial.print(latitude, 7);
   Serial.print(','); // a comma
   Serial.print(longitude, 7);
   Serial.println('>');
 
  Serial.print('<');
  Serial.print(lat, 7);
  Serial.print(','); // a comma
  Serial.print(lng, 7);
  Serial.println('>');
  delay(500); 
 
}

The attachment below is what is displayed on the serial monitor when I run the Bluetooth master code (the receiver)

Serial output is preferably shown inside code tags. This downloading is tiring.

Taking a short look I wonder….
The principals of a Master Slave communicartion is that the Master tells the Slave to send data. Is this the way Your proj is working? Slaves don’t send anything unless they are told to do it.

Railroader:
Serial output is preferably shown inside code tags. This downloading is tiring.

Taking a short look I wonder….
The principals of a Master Slave communicartion is that the Master tells the Slave to send data. Is this the way Your proj is working? Slaves don't send anything unless they are told to do it.

I didnt have that in mind

New games, new bets. Take a good look at the project from the system point of view and se what that will bring up.

Your codes don't make sense to me

Slave Code (the sender) says Serial3.begin(9600); //Bluetooth slave but I do not see where there is any output on Serial3.

Master Code uses receiveWithStartEndMarkers() on Serial3 but there is no Serial3.begin().

Railroader:
The principals of a Master Slave communicartion is that the Master tells the Slave to send data. Is this the way Your proj is working? Slaves don't send anything unless they are told to do it.

The master/slave relationship is only a matter for connection. Once the connection is made, it doesn't matter which is which, and the receiver won't get anything if it doesn't listen. In the above, what was the slave is the sender, and that is quite OK.

Really? How will it work out if several slaves starts talking at the same time? I've always used the principle that the master asks the slaves, one by one, to send their messages.

Nick_Pyner:
The master/slave relationship is only a matter for connection. Once the connection is made, it doesn't matter which is which, and the receiver won't get anything if it doesn't listen. In the above, what was the slave is the sender, and that is quite OK.

So in this case what would be your suggestion now that I've specified that the slave sends and the master receives, but the communication ain't occurring.

cattledog:
Your codes don’t make sense to me

Slave Code (the sender) says Serial3.begin(9600); //Bluetooth slave but I do not see where there is any output on Serial3.

Master Code uses receiveWithStartEndMarkers() on Serial3 but there is no Serial3.begin().

Still ive changed the sender output part but no results doesnt send

#include <TinyGPS++.h>
TinyGPSPlus gps1;
TinyGPSPlus gps2;
double latitude, longitude;
double lat, lng;

int potValue;
#define trigPin  11
#define echoPin  12
#define buzzer  7
void setup() {
 Serial.begin(115200);
  Serial.println("The GPS Received Signal:");
  Serial1.begin(9600); // connect gps sensor
  Serial2.begin(9600); // connect gps sensor
Serial3.begin(9600); //Bluetooth slave

pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(buzzer, OUTPUT);

}
long data;
void loop() {
   
  while (Serial1.available())
  {
    data = Serial1.read();
    if (gps1.encode(data) > 0)
    {
      latitude = (gps1.location.lat());
      longitude = (gps1.location.lng());
      Serial.print("latitude:");
      Serial.println(latitude, 7);
      Serial.print("longitude:");
      Serial.println(longitude, 7);
    
    }
  }

  while (Serial2.available())
  {
    data = Serial2.read();
    if (gps2.encode(data) > 0)
    {
      lat = (gps2.location.lat());
      lng = (gps2.location.lng());
      Serial.print("lat:");
      Serial.println(lat, 7);
      Serial.print("long:");
      Serial.println(lng, 7);
     
    }
    
  }
 long duration, distance;
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(1000);
  digitalWrite(trigPin, LOW);
  duration=pulseIn(echoPin, HIGH);
  distance =(duration/2)/29.1;
  Serial.print(distance);
  Serial.println("CM");
  delay(10);
  potValue =distance;
potValue =map(potValue, 0, 1023, 0, 180);

 
   if((distance>=20) && (distance<=100))
 {
   digitalWrite(buzzer, HIGH);
  delay(100); 
  Serial.println('distance'); 
 }

 else if((distance>200))
 {

   digitalWrite(buzzer,LOW);
     Serial3.print('<');
   Serial3.print(latitude, 7);
   Serial3.print(','); // a comma
   Serial3.print(longitude, 7);
   Serial3.print('>');
 
  Serial3.print('<');
  Serial3.print(lat, 7);
  Serial3.print(','); // a comma
  Serial3.print(lng, 7);
  Serial3.print('>');
  delay(500); 
 
}
else if((distance<=20))
{
  digitalWrite(buzzer, LOW);
  delay(100); 
  Serial.println('distance'); 
}
}

Railroader:
Really? How will it work out if several slaves starts talking at the same time?

All but one will be contemptuously ignored.

What Arduino boards are you using - do you have a Mega for the master and another Mega for the slave?

Referring to the code in Reply #8, why are you sending two separate message right on top of each other

    Serial3.print('<');
   Serial3.print(latitude, 7);
   Serial3.print(','); // a comma
   Serial3.print(longitude, 7);
   Serial3.print('>');
 
  Serial3.print('<');
  Serial3.print(lat, 7);
  Serial3.print(','); // a comma
  Serial3.print(lng, 7);
  Serial3.print('>');
  delay(500);

It would be much better to send a single message <7,0,7,7> and allow time for the master to process it.

In the master code in your Original Post this does not make sense as most of the printing has nothing to do with the received data.

void showNewData() {
    if (newData) {
        Serial.print('<');
  Serial.print("latitude:");
   Serial.print(latitude, 7);
  Serial.print(','); // a comma
  Serial.print("longitude:");
  Serial.print(longitude, 7);
    Serial.println('>');
    //Serial.println(receivedChars);
    
  
    Serial.print('<');
    Serial.print("lat:");
   Serial.print(lat, 7);
  Serial.print(','); // a comma
   Serial.print("lng:");
   Serial.print(lng, 7);
    Serial.println('>');
    
   Serial.println(receivedChars);      
    }
   
        newdata = false;
}

…R

alexmunala:
So in this case what would be your suggestion now that I've specified that the slave sends and the master receives, but the communication ain't occurring.

Specification and actual happening are two very different things.

The first thing you need to do is confirm that the Bluetooth connection has been made. There is nothing to suggest you have actually achieved this. If you are unsure about Bluetooth, you can connect the Arduinos by wire, using the pins where Blueteeth were, and prove your code is kosher.

In the immortal words of a guru around here, "Bluetooth is just serial without wires". Once you have proven your code, you can connect Bluetooth with no change.

You need to respond to reply#4

What Arduino boards are you using - do you have a Mega for the master and another Mega for the slave?

I am using Arduino Mega for both master and slave.

It would be much better to send a single message <7,0,7,7> and allow time for the master to process it.

Saying so means that I should have a delay between the intervals?.

but I do not see where there is any output on Serial3.

Master Code uses receiveWithStartEndMarkers() on Serial3 but there is no Serial3.begin().

I have noted after changes you mentioned, the communication occurs between the two Bluetooth modules and the data is being sent.
But a little more problem comes in that, I can’t identify which data is which to be used for different purposes.
How can I add identifiers so that each specific data can be used correctly where it is supposed to.
These two coordinates are to be used as destination and waypoint. The Bluetooth master just receives them in numerical form and it is confusing and impossible to identify which one is destination coordinates and which one is waypoint.

Here is my Master(receiver) code after the changes.

boolean newData = true;
double latitude, longitude;
double lat, lng;
const byte maxDataLength = 100;
const byte numChars = 32;
char receivedChars[numChars];

boolean newdata = false;


void setup(){
Serial.begin(115200); // connect serial
Serial.println("");
Serial1.begin(9600); // BLUETOOTH MASTER



}
 
void loop (){
   recvWithStartEndMarkers();
    showNewData();
    
}
void showNewData() {
    if (newData) {
      Serial.println(receivedChars);
    
  delay(1000);
   
       Serial.println(receivedChars);      
    }
   
        newdata = false;
}

void recvWithStartEndMarkers()
{
     static boolean recvInProgress = false;
     static byte ndx = 0;
     char startMarker = '<';
     char endMarker = '>';
     char rc;
 
     if (Serial1.available() > 0) 
     {
          rc = Serial1.read();
          if (recvInProgress == true) 
          {
               if (rc != endMarker) 
               {
                    receivedChars[ndx] = rc;
                    ndx++;
                    if (ndx > maxDataLength) { ndx = maxDataLength; }
               }
               else 
               {
                     receivedChars[ndx] = '\0'; // terminate the string
                     recvInProgress = false;
                     ndx = 0;
                     newData = true;
               }
          }
          else if (rc == startMarker) { recvInProgress = true; }
     }
 
}

my Slave (sender) code is below

#include <TinyGPS++.h>
TinyGPSPlus gps1;
TinyGPSPlus gps2;
double latitude, longitude;
double lat, lng;

int potValue;
#define trigPin  11
#define echoPin  12
#define buzzer  7
void setup() {
 Serial.begin(115200);
  Serial.println("The GPS Received Signal:");
  Serial1.begin(9600); // connect gps sensor
  Serial2.begin(9600); // connect gps sensor
Serial3.begin(9600); //Bluetooth slave

pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(buzzer, OUTPUT);

}
long data;
void loop() {
   
  while (Serial1.available())
  {
    data = Serial1.read();
    if (gps1.encode(data) > 0)
    {
      latitude = (gps1.location.lat());
      longitude = (gps1.location.lng());
      Serial.print("latitude:");
      Serial.println(latitude, 7);
      Serial.print("longitude:");
      Serial.println(longitude, 7);
    
    }
  }

  while (Serial2.available())
  {
    data = Serial2.read();
    if (gps2.encode(data) > 0)
    {
      lat = (gps2.location.lat());
      lng = (gps2.location.lng());
      Serial.print("lat:");
      Serial.println(lat, 7);
      Serial.print("long:");
      Serial.println(lng, 7);
     
    }
    
  }
 long duration, distance;
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(1000);
  digitalWrite(trigPin, LOW);
  duration=pulseIn(echoPin, HIGH);
  distance =(duration/2)/29.1;
  Serial.print(distance);
  Serial.println("CM");
  delay(10);
  potValue =distance;
potValue =map(potValue, 0, 1023, 0, 180);

 
   if((distance>=20) && (distance<=100))
 {
   digitalWrite(buzzer, HIGH);
  delay(100); 
  Serial.println('distance'); 
 }

 else if((distance>200))
 {

   digitalWrite(buzzer,LOW);
     Serial3.print('<');
   Serial3.print(latitude, 7);
   Serial3.print(','); // a comma
   Serial3.print(longitude, 7);
   Serial3.print('>');
    delay(1000);
    
  Serial3.print('<');
  Serial3.print(lat, 7);
  Serial3.print(','); // a comma
  Serial3.print(lng, 7);
  Serial3.print('>');
   
 
}
else if((distance<=20))
{
  digitalWrite(buzzer, LOW);
  delay(100); 
  Serial.println('distance'); 
}
}

Please check the screenshot below of what I get when the data is received on the Master end

But a little more problem comes in that, I can't identify which data is which to be used for different purposes.
How can I add identifiers so that each specific data can be used correctly where it is supposed to.

You can send one message with the start/end markers and all the data. Then parse the data from it since you know the order in which it was written.

Alternatively you can send two messages, but you will need another data field for message identifier which tells you what the message data is.

I think it is easier to deal with the single message.

alexmunala:
Please check the screenshot below of what I get when the data is received on the Master end

Please don't post pictures of text. Just copy and paste the text. This point was already made in Reply #1

...R

This, from your master code, is not going to work

void showNewData() {
    if (newData) {
      Serial.println(receivedChars);
    
  delay(1000);
   
       Serial.println(receivedChars);      
    }
   
        newdata = false;
}

Just keep it simple - like this

void showNewData() {
if (newData) {
      Serial.println(receivedChars);
      newdata = false;
}

...R

Robin2:
Just keep it simple - like this

void showNewData() {

if (newData) {
      Serial.println(receivedChars);
      newdata = false;
}




...R

Okay…noted

So I added my code to the main code for the GPS guided robot. The slave transmits the data, and the master successfully receives the data. The problem is, the GPS on the robot car isn’t working, no data of the coordinates are being displayed on the serial monitor despite the Neo-6M having got a Fix.
I would appreciate your input, corrections, and comments on what might be the problem.
Below is my code.

// Imports
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
#include <Servo.h>
#include <TinyGPS++.h>
//#include <TinyGPS.h>
// You must then add your 'Declination Angle' to the compass, which is the 'Error' of the magnetic field in your location.
// Find yours here: http://www.magnetic-declination.com/
// Mine is: 23° 4' E (Positive),
#define DECLINATION_ANGLE +0.34f


#define COMPASS_OFFSET 0.35f


#define GPS_UPDATE_INTERVAL 1000


#define GPS_WAYPOINT_TIMEOUT 25

// Struct to combine our coordinates into one struct for ease of use
struct GeoLoc {
  float lat;
  float lon;
};
boolean newData = true;
//double latitude, longitude;
//double lat, lng;
const byte maxDataLength = 100;
const byte numChars = 32;
char receivedChars[numChars];

boolean newdata = false;

float lat;
float  lon;
// GPS
//TinyGPS gps;
TinyGPSPlus gps;


// servomotor
Servo myservo;

bool enabled = true;


/* Compass */
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
long data;
GeoLoc checkGPS() {
  Serial.println("Reading onboard GPS: ");
  Serial2.begin(9600); // connect gps sensor
 
 while (Serial2.available())
  {
    data = Serial2.read();
    if (gps.encode(data) > 0)
    {
      lat = (gps.location.lat());
      lon = (gps.location.lng());
      
      GeoLoc aircraftLoc;
  aircraftLoc.lat = lat;
  aircraftLoc.lon = lon;
  
      Serial.print("latitude:");
      Serial.println(lat, 7);
      Serial.print("longitude:");
      Serial.println(lon, 7);
    
    }
  } 
}

void displayCompassDetails(void)
{
  sensor_t sensor;
  mag.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" uT");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" uT");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" uT");
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

#ifndef DEGTORAD
#define DEGTORAD 0.0174532925199432957f
#define RADTODEG 57.295779513082320876f
#endif

float geoBearing(struct GeoLoc &a, struct GeoLoc &b) {
  float y = sin(b.lon - a.lon) * cos(b.lat);
  float x = cos(a.lat) * sin(b.lat) - sin(a.lat) * cos(b.lat) * cos(b.lon - a.lon);
  return atan2(y, x) * RADTODEG;
}

float geoDistance(struct GeoLoc &a, struct GeoLoc &b) {
  const float R = 6371000; // radius of earth in metres
  float p1 = a.lat * DEGTORAD;
  float p2 = b.lat * DEGTORAD;
  float dp = (b.lat - a.lat) * DEGTORAD;
  float dl = (b.lon - a.lon) * DEGTORAD;

  float x = sin(dp / 2) * sin(dp / 2) + cos(p1) * cos(p2) * sin(dl / 2) * sin(dl / 2);
  float y = 2 * atan2(sqrt(x), sqrt(1 - x));

  // returns distance in meters
  return R * y;
}

float geoHeading()
{
  /* Get a new sensor event */
  sensors_event_t event;
  mag.getEvent(&event);


  float heading = atan2(event.magnetic.y, event.magnetic.x);

  // Offset
  heading -= DECLINATION_ANGLE;
  heading -= COMPASS_OFFSET;


  if (heading < 0)
    heading += 2 * PI;


  if (heading > 2 * PI)
    heading -= 2 * PI;


  float headingDegrees = heading * 180 / M_PI;

  // Map to -180 - 180
  while (headingDegrees < -180) headingDegrees += 360;
  while (headingDegrees >  180) headingDegrees -= 360;

  return headingDegrees;
}



void controlservo(int direction)
{
  int headingAngle;
  float headingDegrees;
  headingAngle = headingDegrees;
  if (headingAngle == 0) {
    myservo.write(87);
  }
  else if (headingAngle == headingDegrees) {
    myservo.write(headingDegrees);
  }
}



void driveTo(struct GeoLoc &loc, int timeout)
{
  Serial2.read();
  GeoLoc aircraftLoc = checkGPS();
  Serial1.read();

  if (aircraftLoc.lat != 0 && aircraftLoc.lon != 0 && enabled) {
    float distance = 0;
    //Start move loop here
    do {
      Serial2.read();
      aircraftLoc = checkGPS();
      Serial1.read();

      distance = geoDistance(aircraftLoc, loc);
      float bearing = geoBearing(aircraftLoc, loc) - geoHeading();

      Serial.print("Distance: ");
      Serial.println(distance);

      Serial.print("Bearing: ");
      Serial.println(geoBearing(aircraftLoc, loc));

      Serial.print("Heading: ");
      Serial.println(geoHeading());


    }
    while (distance > 1.0 && enabled && timeout > 0);


  }
}

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

  /* Display some basic information on this sensor */
  displayCompassDetails();
}

void setup()
{
  // Attaching servo
  myservo.attach(13);



  //Debugging via serial
  Serial.begin(115200);

  // Compass
  setupCompass();

  //GPS
  Serial2.begin(9600);
  
  //Bluetooth
 
  Serial1.begin(9600);
  Serial.println("ATcommand");  //ATcommand Start



}
void loop (){
   recvWithStartEndMarkers();
    showNewData();
   
}
void showNewData() {
    if (newData) {
      Serial.println(receivedChars);
   
      
    }
   
        newdata = false;
}

void recvWithStartEndMarkers()
{
     static boolean recvInProgress = false;
     static byte ndx = 0;
     char startMarker = '<';
     char endMarker = '>';
     char rc;
 
     if (Serial1.available() > 0)
     {
          rc = Serial1.read();
          if (recvInProgress == true)
          {
               if (rc != endMarker)
               {
                    receivedChars[ndx] = rc;
                    ndx++;
                    if (ndx > maxDataLength) { ndx = maxDataLength; }
               }
               else
               {
                     receivedChars[ndx] = '\0'; // terminate the string
                     recvInProgress = false;
                     ndx = 0;
                     newData = true;
               }
          }
          else if (rc == startMarker) { recvInProgress = true; }
     }
 
}

At this stage I am very confused about what is happening where.

Is the code in Reply #18 for the slave (I presume that is what you are calling the robot) or is it for the master? When you have master and slave codes you really need to post both of them every time.

Is the GPS attached to the slave? What serial port is it connected to? How do you know its data is not being received? And do you mean the slave can't see the GPS data or the master can't see the GPS data?

A List showing what everything is connected to on both master and slave would be very useful.

Keep in mind that you are thinking about this and working on it for hours. We only drop in occasionally for a few minutes at a time. We only know what you tell us. We can't see your workbench.

...R