Sending GPS data to mobile via bluetooth

Hello guys, I am quite new top programming but I need the following project to work so I was wondering if anyone can help.
I am trying to receive the coordinates to my phone using the blueterm app, I want it to send me an error message is the gps shield can not receive the coordinates. I have also added in a bit about boundaries so I will be notified when the device goes too far.

I have my circuit correctly set up and I can see a clear connection between my BlueSmirf Bluetooth shield and the Blueterm app.
Here is my code, its not correctly annotated yet.

#include <TinyGPS.h>

//This program is designed to send gps coordinates to a mobile phone via bluetooth,
//it should show some sort of indication when the gps sheild con not receive any coordinates
//and when the device travels outside a certain boundary.

#include <SoftwareSerial.h> // import the serial library

TinyGPS gps;

SoftwareSerial ss
(10, 11); // RX, TX

void setup() {
// this is the main code that will run once
Serial.begin(115200);

}

void loop()
{
// this is the main code that will run repeatedly
delay(5000);
if (Serial.available()){

bool newData = false;
unsigned long chars;
unsigned short sentences, failed;

// For one second we parse GPS data and report some key values
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (ss.available())
{
char c = ss.read();
Serial.write(c); // uncomment this line if you want to see the GPS data flowing
if (gps.encode(c)) // Did a new valid sentence come in?
newData = true;
}
}
//displays the coordinates
if (newData)
{
float flat, flon;
unsigned long age;
gps.f_get_position(&flat, &flon, &age);
Serial.print("LAT=");
Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
Serial.print(" LON=");
Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
Serial.print(" SAT=");
Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
Serial.print(" PREC=");
Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
if

// Sets the boundries
(flat > 53.471623);
Serial.print("Lost Connection - High!");
(flon > -2.240617);
Serial.print("Lost Connection - Right!");
(flat < 53.471555);
Serial.print("Lost Connection - Low!");
(flon < -2.241046);
Serial.print("Lost Connection - Left!");

}
//displays an error when the gpd shield can not receive the coordinates
gps.stats(&chars, &sentences, &failed);
Serial.print(" CHARS=");
Serial.print(chars);
Serial.print(" SENTENCES=");
Serial.print(sentences);
Serial.print(" CSUM ERR=");
Serial.println(failed);
if (chars == 0)
Serial.println("** No satellites connected **");

}

}

Thank You
Roy

Hi Roy

Can you modify your post so the code is in code tags - use the "#" button above the smileys. It makes it much easier for people to read. :slight_smile:

And most importantly, have you tried compiling and running the program? What happens? What help exactly are you looking for?

For example, I guess it won't compile because the following part of your code, at least, has problems.

    if
    
    // Sets the boundries
      (flat > 53.471623);
      Serial.print("Lost Connection - High!");
      (flon > -2.240617);
      Serial.print("Lost Connection - Right!");
      (flat < 53.471555);
      Serial.print("Lost Connection - Low!");
      (flon < -2.241046);
      Serial.print("Lost Connection - Left!");
      
}

If you search in the Reference section of this website for information about the "if" statement, you should find some examples that could help you to fix this part. I think I understand what you are trying to do, but the code isn't valid as it stands.

One other question for now. You are using a GPS library and software serial to communicate between the Arduino and the GPS. Have you got any example sketches that came with the libraries that will let you test if the link to the GPS is working ok, for example by printing out the data it sends to the serial monitor (i.e. keep the bluetooth to your phone out of the equation for now)?

Regards

Ray

Hackscribble:
Hi Ray

Thank you for your reply

Can you modify your post so the code is in code tags - use the "#" button above the smileys. It makes it much easier for people to read. :slight_smile:

  • I don't understand what '#' button does sorry?

And most importantly, have you tried compiling and running the program? What happens? What help exactly are you looking for?

  • I have compiled and uploaded my code with no problems and i can connect to the Bluetooth modem from my phone but nothing is displayed or printed. A guy told me that i have declared the hardware part of the serial but not the software but i am not sure what this means?

For example, I guess it won't compile because the following part of your code, at least, has problems.

  • I have a previous piece of code from befour i added the boundaries but now i'm still getting the same problem, what may sound confusing is that i once had it working but then don't remember changing any of the code for it to stop working.

If you search in the Reference section of this website for information about the "if" statement, you should find some examples that could help you to fix this part. I think I understand what you are trying to do, but the code isn't valid as it stands.

One other question for now. You are using a GPS library and software serial to communicate between the Arduino and the GPS. Have you got any example sketches that came with the libraries that will let you test if the link to the GPS is working ok, for example by printing out the data it sends to the serial monitor (i.e. keep the bluetooth to your phone out of the equation for now)?

  • Yes i am but at the beginning of my project i already checked those connections and there was no problems, i then managed to merge my two pieces of code and information was displayed on my phone, i then left my code for 3 week and came back and it stopped displaying information to my phone.

Regards

Roy

Hi Roy

About the code tags, when you type in your post on the forum, there are buttons above the text box you are typing in. One of them has a "#" sign on it.

If you press this, it generates a couple of tags in the text: "code" and "/code" in square brackets.

If you type your code between these, it looks like this, which is much easier to handle.

for (uint8_t i = 0; i < 100; i++)
{
    Serial.println(i);
}

Roy

I'll take another look at the code later.

But I have to correct what I said earlier. The if statement with the boundaries DOES compile but I still feel it won't do what you want it to do. I'll post some ideas on it later (got to go out).

Just to understand what you're saying about an earlier version. Before you added the boundaries, the program worked. Now it doesn't even if you remove the boundary code?

Can you post the version which used to work?

All the best

Ray

Hi Roy

Here is my attempt at reworking the boundary part of the code to do what I infer you want to do.

// Sets the boundaries
if (flat > 53.471623)
{
      Serial.print("Lost Connection - High!");
}
else if (flat < 53.471555)
{
      Serial.print("Lost Connection - Low!");
}

if (flon > -2.240617)
{
      Serial.print("Lost Connection - Right!");
}
else if (flon < -2.241046)
{
      Serial.print("Lost Connection - Left!");
 }

So if either flat or flon (or both) are outside the small ranges, you get an error message.

How does that look?

Ray

Hi Roy

Looking at this other part of the code, I think I see what it is doing, but it is unusual to use the for loop this way.

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

There is also a possibility that, if data comes in on software serial fast and long enough, the while loop would not finish when you think it should, and you get stuck inside the for loop forever, or at least longer than one second.

A different way to structure it is this. I'm assuming that as soon as newData becomes true, you want to move on to the rest of the program. You don't have to gather a full one second's worth of data if you get a valid sentence before then?

unsigned endLoopTime = millis() + 1000;  // Spend up to 1,000 ms in the loop
// newData previously set to false in your program

while ( (millis() < endLoopTime) && (!newData) )
{
    if (ss.available())
    {
         char c = ss.read();
         Serial.write(c); // uncomment this line if you want to see the GPS data flowing
         if (gps.encode(c)) // Did a new valid sentence come in?
             newData = true;
    }
  }

Might also help to make a call to Software Serial's begin method in setup to set the baud rate.

Hope this helps,

Brad

Hello Ray, thank you so much for your time, its really appreciated.

Here is my previous code without the Boundaries:

#include <TinyGPS.h>

// This program shown how to control arduino from PC Via Bluetooth
 // Connect ...
 // arduino>>bluetooth
 // D11   >>>  Rx
 // D10   >>>  Tx
 

 // you will need arduino 1.0.1 or higher to run this sketch

 #include <SoftwareSerial.h>// import the serial library

TinyGPS gps;

 SoftwareSerial ss
 (10, 11); // RX, TX



 void setup() {
   // put your setup code here, to run once:
   Serial.begin(115200);
   
   
 }

 void loop() 
{
   // put your main code here, to run repeatedly:
    //Serial.println("To receive bluetooth coordinates, press 1");
    delay(5000);
    if (Serial.available()){
   
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData)
  {
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
    Serial.print("LAT=");
    Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
    Serial.print(" LON=");
    Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
    Serial.print(" SAT=");
    Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
    Serial.print(" PREC=");
    Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
  }
 
  gps.stats(&chars, &sentences, &failed);
  Serial.print(" CHARS=");
  Serial.print(chars);
  Serial.print(" SENTENCES=");
  Serial.print(sentences);
  Serial.print(" CSUM ERR=");
  Serial.println(failed);
  if (chars == 0)
    Serial.println("** No satellites connected **");
 
    }
    
}

I have just added your modification to the above code and still doesn't seem to write anything to the display.
Here is modified code:

#include <TinyGPS.h>

// This program shown how to control arduino from PC Via Bluetooth
 // Connect ...
 // arduino>>bluetooth
 // D11   >>>  Rx
 // D10   >>>  Tx
 

 // you will need arduino 1.0.1 or higher to run this sketch

 #include <SoftwareSerial.h>// import the serial library

TinyGPS gps;

 SoftwareSerial ss
 (10, 11); // RX, TX



 void setup() {
   // put your setup code here, to run once:
   Serial.begin(115200);
   
   
 }

 void loop() 
{
   // put your main code here, to run repeatedly:
    //Serial.println("To receive bluetooth coordinates, press 1");
    delay(5000);
    if (Serial.available()){
   
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

 unsigned endLoopTime = millis() + 1000;  // Spend up to 1,000 ms in the loop
// newData previously set to false in your program

while ( (millis() < endLoopTime) && (!newData) )
{
    if (ss.available())
    {
         char c = ss.read();
         Serial.write(c); // uncomment this line if you want to see the GPS data flowing
         if (gps.encode(c)) // Did a new valid sentence come in?
             newData = true;
    }
  }  

  if (newData)
  {
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
    Serial.print("LAT=");
    Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
    Serial.print(" LON=");
    Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
    Serial.print(" SAT=");
    Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
    Serial.print(" PREC=");
    Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
  }
 
  gps.stats(&chars, &sentences, &failed);
  Serial.print(" CHARS=");
  Serial.print(chars);
  Serial.print(" SENTENCES=");
  Serial.print(sentences);
  Serial.print(" CSUM ERR=");
  Serial.println(failed);
  if (chars == 0)
    Serial.println("** No satellites connected **");
 
    }
    
}

Your modification to the boundaries makes more sense thank you, i did just add that part too but i got an error 'expected '{' befour 'if' ' but we can surely sort that out after we get the rest of the code to work again.

That the second person to comment about the software serial, is that a possible cause for the problem?
and thank you brad.

Brad's definitely right. Here is some code from the SoftwareSerial example sketch.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup()  
{
 ...
  // set the data rate for the SoftwareSerial port
  mySerial.begin(4800);
  mySerial.println("Hello, world?");
}

You should add (in your case) "ss.begin(nnnn)" with the appropriate baud rate for talking to the GPS.

Cheers

Ray

Your logic for the boundaries there seems conceptually flawed to me, if you "lost the connection" ( as your printouts say ), your device is probably just going to tell you the same location you were at ( Manchester ? ) that you were at when the device last had a connection. If the GPS position wanders outside your imaginary quasi-rectangle, that probably means that your car or plane or whatever it is, is lost, not your GPS connection.

Thanks guys,
i have just retried a basic connection from the arduino to bluetooth
with the sample code and that has not worked either so im starting to think that
the bluetooth modem i am using does not have the Tx and Rx working propper.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup()  
{

  // set the data rate for the SoftwareSerial port
  mySerial.begin(115200);
  mySerial.println("Hello, world?");
}

void loop() // run over and over
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}

but on the other hand, i do get a connection and it shows up green, but i just cant get it to
display anything. i have also tried using someone elses phone but still no luck :frowning:

I am really running out of options, i could do with it working befour the end of tonight so i can
get evidence for my report.

Hi Roy

Is that your complete test code? Looks like you've lost the Serial.begin(nnnn) to initialise the hardware serial port to the monitor. Without it, I'm not sure your Serial.write()s will work.

Also, maybe try reducing the baudrate on the software serial port from 115,200. If you can adjust the other end.

Cheers

Ray

Ill send you my final code with your amendments, see if you can stop any mistakes that way,
if not then ill just try and do most of my report without the evidence and see how it goes.

#include <TinyGPS.h>

//This program is designed to send gps coordinates to a mobile phone via bluetooth, 
//it should show some sort of indication when the gps sheild con not receive any coordinates 
//and when the device travels outside a certain boundary.
 
 #include <SoftwareSerial.h>// import the serial library

TinyGPS gps;

 SoftwareSerial ss
 (10, 11); // RX, TX



 void setup() {
   // this is the main code that will run once
   Serial.begin(57600);
   ss.begin(115200);
   
 }

 void loop() 
{
   // this is the main code that will run repeatedly 
   
    delay(5000);
    if (Serial.available()){
   
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

unsigned endLoopTime = millis() + 1000;  // Spend up to 1,000 ms in the loop
// newData previously set to false in your program

while ( (millis() < endLoopTime) && (!newData) )
{
    if (ss.available())
    {
         char c = ss.read();
         Serial.write(c); // uncomment this line if you want to see the GPS data flowing
         if (gps.encode(c)) // Did a new valid sentence come in?
             newData = true;
    }
  }  
  
  //displays the coordinates 
  if (newData)
  {
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
    Serial.print("LAT=");
    Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
    Serial.print(" LON=");
    Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
    Serial.print(" SAT=");
    Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
    Serial.print(" PREC=");
    Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
    

    // Sets the boundries
      if (flat > 53.471623)
{
      Serial.print("Lost Connection - High!");
}
else if (flat < 53.471555)
{
      Serial.print("Lost Connection - Low!");
}

if (flon > -2.240617)
{
      Serial.print("Lost Connection - Right!");
}
else if (flon < -2.241046)
{
      Serial.print("Lost Connection - Left!");
 }    
      
}

 //displays an error when the gpd shield can not receive the coordinates
  gps.stats(&chars, &sentences, &failed);
  Serial.print(" CHARS=");
  Serial.print(chars);
  Serial.print(" SENTENCES=");
  Serial.print(sentences);
  Serial.print(" CSUM ERR=");
  Serial.println(failed);
  if (chars == 0)
    Serial.println("** No satellites connected **");
 
    }
    
}

but i really appreciate your help, thank you.

Please can i ask one more thing from you.
Is there any chance you could help me explain(annotate) each section of the code?

That would be great if you could,
Thanks for all your help.