TinyGPS++ and Yun

Hello,

I am trying to setup a GPS tracker running on Yun/Mega 2560 combo.

I am using the TinyGPS++ library and the example using SoftwareSerial to show the GPS data on the serial monitor works great.

Now I am trying to show the data using Bridge library via the Yun shield on a browser but somehow the GPS data is not passing to the client.println call.

Not sure what I am doing wrong but is there a call that I need to make in the BridgeLibrary or the TinyGPS++ library to pass data ?

thx

Not sure what I am doing wrong

It probably depends on your code, which you did not post.

On its own just including TinyGPS++ does nothing.

Well, I though it was something simple that I was missing using the Bridge library.

Anyway here is the TinyGPS++ example with the addition of the Bridge code.

Basically the data is not passed to the client.print call:
client.println(""+ String(gps.satellites.value()) +"");

#include <TinyGPS++.h>  
#include <SoftwareSerial.h>

#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h>

/* 
  This sample code demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object. 
  It requires the use of SoftwareSerial, and assumes that you have a 
  4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx). 
*/  
static const int RXPin = 4, TXPin = 3;  
static const uint32_t GPSBaud = 9600;  
  
  
// The TinyGPS++ object  
TinyGPSPlus gps;  

BridgeServer server;

// The serial connection to the GPS device  
SoftwareSerial ss(RXPin, TXPin);
  
  
void setup()  
{  
 Serial.begin(115200);
 ss.begin(GPSBaud);  

 BridgeServer server;
 server.listenOnLocalhost();
 server.begin();
  
 Serial.println(F("FullExample.ino"));  
 Serial.println(F("An extensive example of many interesting TinyGPS++ features"));  
 Serial.print(F("Testing TinyGPS++ library v. "));
 Serial.println(TinyGPSPlus::libraryVersion());  
 Serial.println(F("by Mikal Hart"));  
 Serial.println();  
 Serial.println(F("Sats HDOP Latitude   Longitude   Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum"));  
 Serial.println(F("          (deg)      (deg)       Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail"));  
 Serial.println(F("---------------------------------------------------------------------------------------------------------------------------------------"));  
}  
  
  
void loop() {
 static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

 BridgeClient client = server.accept();
 //Serial.println("satellite: "+gps.satellites.value());

while(client) {
 String action;
 sendHTTPResponse(client);
 client.println("<data>");
   
 printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
 printInt(gps.hdop.value(), gps.hdop.isValid(), 5);
 printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
 printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
 printInt(gps.location.age(), gps.location.isValid(), 5);
 printDateTime(gps.date, gps.time);
 printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
 printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
 printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
 printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.value()) : "*** ", 6);

 unsigned long distanceKmToLondon =  
   (unsigned long)TinyGPSPlus::distanceBetween(  
     gps.location.lat(),  
     gps.location.lng(),  
     LONDON_LAT,  
     LONDON_LON) / 1000;  
 printInt(distanceKmToLondon, gps.location.isValid(), 9);  
  
  
 double courseToLondon =  
   TinyGPSPlus::courseTo(  
     gps.location.lat(),  
     gps.location.lng(),  
     LONDON_LAT,  
     LONDON_LON);  
  
  
 printFloat(courseToLondon, gps.location.isValid(), 7, 2);  
  
  
 const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);  
  
  
 printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);  
  
  
 printInt(gps.charsProcessed(), true, 6);
 printInt(gps.sentencesWithFix(), true, 10);
 printInt(gps.failedChecksum(), true, 9);
 Serial.println();
 
 smartDelay(1000);
  
 if (millis() > 5000 && gps.charsProcessed() < 10)
   Serial.println(F("No GPS data received: check wiring"));

client.println("<satellites>"+ String(gps.satellites.value()) +"</satellites>");

// Process request
   
    client.println("</data>");
    process(client);
    client.stop();
 }
}

// This custom version of delay() ensures that the gps object is being "fed".  
static void smartDelay(unsigned long ms) {
 unsigned long start = millis();
 do {
   while (ss.available())
     gps.encode(ss.read());
 } while (millis() - start < ms);
}

static void printFloat(float val, bool valid, int len, int prec) {
 if (!valid) {
   while (len-- > 1)
     Serial.print('*');
   Serial.print(' ');
 } else {
   Serial.print(val, prec);
   int vi = abs((int)val);
   int flen = prec + (val < 0.0 ? 2 : 1); // . and -  
   flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
   for (int i=flen; i<len; ++i)
     Serial.print(' ');
 }
 smartDelay(0);
}
 
static void printInt(unsigned long val, bool valid, int len) {
 char sz[32] = "*****************";
 if (valid)
   sprintf(sz, "%ld", val);
 sz[len] = 0;
 for (int i=strlen(sz); i<len; ++i)
   sz[i] = ' ';
 if (len > 0)
   sz[len-1] = ' ';
 Serial.print(sz);
 smartDelay(0);
}
 
static void printDateTime(TinyGPSDate &d, TinyGPSTime &t) {
 if (!d.isValid()) {
   Serial.print(F("********** "));  
 } else {
   char sz[32];  
   sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());  
   Serial.print(sz);  
 }
 
 if (!t.isValid()) {
   Serial.print(F("******** "));  
 } else {
   char sz[32];
   sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
   Serial.print(sz);
 }
 
 printInt(d.age(), d.isValid(), 5);  
 smartDelay(0);  
}  

static void printStr(const char *str, int len) {  
 int slen = strlen(str);
 for (int i=0; i<len; ++i)
   Serial.print(i<slen ? str[i] : ' ');
 smartDelay(0);
}
// ==========================================================================================
// Send data back to client
// ==========================================================================================
void sendHTTPResponse(BridgeClient client) {
  ////Serial.println(content.length());
  client.println("Status: 200");
  client.println("Content-Type: text/xml; charset=UTF-8");
  //client.println("Content-Type: application/xml; charset=UTF-8");
  client.println("Connection: keep-alive");
  // any other header
  client.println(); //mandatory blank line
}
void process(BridgeClient client) {
  // read the command
  String command = client.readStringUntil('/');
  //String command = client.readString();
  command.trim();        //kill whitespace
  if(command == "show") {
    return;
  }
}

Just an update.

I noticed that if I comment out the process(client); line the example show GPS updates.
If I leave it it stops at the first line.

any idea?
thx

 BridgeClient client = server.accept();
 //Serial.println("satellite: "+gps.satellites.value());

while(client) {
<snip>
    client.println("</data>");
    process(client);
    client.stop();
 }

I can not, for the life of me, imagine a single possible reason for using a while statement there.

In any case, your code is a real mess. It should be doing two things simultaneously - reading from the GPS and responding to client requests for the latest data. It should NOT read the GPS only when there is a client interested in the data.

The stupidly named smartDelay() method should be permanently assigned to the bit bucket.

Read any available data on every pass through loop(). Use the data only when gps.encode() returns true.

void process(BridgeClient client) {
  // read the command
  String command = client.readStringUntil('/');
  //String command = client.readString();
  command.trim();        //kill whitespace
  if(command == "show") {
    return;
  }
}

If the client request was “show”, return. Otherwise, return. It makes NO sense to call this function.

It makes no sense to be using SoftwareSerial on a Mega, either.

thanks for the reply, I am just new to these libraries.

the code is not mine but from examples of TinyGPS and Bridge and I am trying to make them work together.

The while is a mistake, not sure why I put it there! :frowning:

So you are saying that the Loop is doing the work and GPS is continuously feeding data. Than upon request from client data is shown.

And from what I understand the call inside the SmartDelay that reads the GPS data from pins.

The SmartDelay is from the TinyGPS++ example.

I know that the process function does nothing in the example when invoked but is needed if you want to add other commands which calls other functions. That’s how it is used in the Yun example.

thx

The SmartDelay is from the TinyGPS++ example.

That does not make it right.

I understand that but I am just using the examples to learn.

Can you answer my other question?

"So you are saying that the Loop is doing the work and GPS is continuously feeding data. Than upon request from client data is shown.

And from what I understand the call inside the SmartDelay that reads the GPS data from pins."

thx

Your loop function should look like this:

void loop()
{
   getGPSData();
   handleClientRequests();
}

Do NOT try to read from the GPS in handleClientRequests() and do NOT try to send data to the client in getGPSData().

Do NOT use smartDelay() ANYWHERE in your application. It is NOT smart.

great, thanks for the confirmation !