Search code examples
gpsarduinonmearfduino

RFduino not pulling NMEA strings from GPS


I'm having trouble using the TinyGPS library to parse Lat and Lon. Is this library compatible with the RFduino? I can read NMEA strings by loading a blank sketch to the RFduino and then just opening the Serial Monitor, so I know that the GPS data is going through the serial port, but when I try to get the Lat or Lon into a variable, it fills the variable with 999999999. I'm sending this data through BLE to an android. If I don't try to get GPS data, I can send any value I want in the lat or lon variables and it appears in my custom Android App. I read somewhere that the softserial library doesn't work on rfduino. Is this true? If not, I would be able to print my data through the hard serial port, making troubleshooting much easier. Below I've attached the code I'm using on my RFduino. Any advice would be appreciated.

    //       CODE         //

#include <RFduinoBLE.h>
#include <TinyGPS.h>


TinyGPS gps;

long lat = 5; //Load lat/lon with junk value for testing
long lon = 6;
char latBuf[20];
char lonBuf[20];

void setup() {
  // this is the data we want to appear in the advertisement
  // (if the deviceName and advertisementData are too long to fix into the 31 byte
  // ble advertisement packet, then the advertisementData is truncated first down to
  // a single byte, then it will truncate the deviceName)
  RFduinoBLE.advertisementData = "ledbtn";

  // start the BLE stack
  RFduinoBLE.begin();
  Serial.begin(9600);//For GPS Communication
}



void loop(){
    char c = byte(Serial.read());
    gps.encode(c);
    gps.get_position(&lat,&lon); // get latitude and longitude
    // send position as char[]

    String latString = String(lat);
    String lonString = String(lon);

    latString.toCharArray(latBuf, 20);
    lonString.toCharArray(lonBuf, 20);    
    RFduinoBLE.send(lonBuf, 20);
  }


void RFduinoBLE_onDisconnect()
{
}

void RFduinoBLE_onReceive(char *data, int len)
{
  RFduinoBLE.send(lonBuf, 20);
}

Solution

  • One problem I see: the loop() is trying to read out the GPS coordinates every time loop is executed. This approach has two problems: 1) the loop doesn't wait until serial data is ready, and 2) the loop doesn't wait until the received GPS data is valid.

    From reading http://arduino.cc/en/Tutorial/ReadASCIIString and http://arduiniana.org/libraries/tinygps/ I recommend rewriting loop() to something like this:

    loop() {
      char c;
      float fLat, fLon;
      unsigned long fix_age;
      static unsigned long previous_fix_age = 0;
    
      // If nothing to read; do nothing.
      // Read as many characters as are available.
      while (Serial.available() > 0) {
    
        // Tell the GPS library about the new character.
        c = Serial.read();
        gps.encode(c);
    
        gps.f_get_position(&flat, &flon, &fix_age);
        if (fix_age != TinyGPS::GPS_INVALID_AGE && fix_age != previous_fix_age) {
          // new GPS data is valid, new, and ready to be printed
    
          previous_fix_age = fix_age; // remember that we've reported this data.
    
          String latString = String(lat);
          ...the rest of the code you already have to print the lat and lon.
        }
    
      }
    }
    

    The code about previous_fix_age is there so that the loop prints coordinates only when a new fix has been received from the GPS.