Hello all,
I'm working on a self-guided robotic vechicle project. I've got 2 arduino boards, an arduinoBT as master and an arduino Uno as slave. I'm using the TinyGPS library to get the data I need from my (parallax) GPS module which is mounted on the slave micro. The 2 boards communicate through i2c protocol and the slave transmits latitude and longitude values to master.
When the 2 boards don't communicate and I just print the gps data on the serial monitor, everything works fine. I get a fix with high precision and no or like 1 checksum error every 5 reads which is ok, I guess.
When the boards communicate (I send float latitude, longitude values from slave to master for further proccess) I get 1-3 checksum errors with every read. This is crucial for my project because the data I read are stale or don't have the same (needed) precision like before.
Master
#include <Wire.h>
#include <stdlib.h>
#define PRINT
#define commPin 9
int compassAdress = 0x21, slaveMicroControllerAddress = 2;
float currentLatitude, currentLongitude;
void setup()
{
pinMode(commPin, INPUT);
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(115200); // start serial for output
}
void loop()
{
if(digitalRead(commPin) == HIGH)
requestGPSData();
else
Serial.println("no gps data");
delay(1000);
}
void requestGPSData()
{
char buffer[17];
char *latEnd;
Wire.requestFrom(slaveMicroControllerAddress, 17); // request 8 bytes from slave device #2
int i = 0;
while(Wire.available()) // slave may send less than requested
{
buffer[i] = Wire.receive(); // receive a byte as character
i++;
}
currentLatitude = strtod(buffer,&latEnd);
currentLongitude = strtod(latEnd,NULL);
#ifdef PRINT
Serial.print("currentLatitude = ");Serial.print(currentLatitude,5);Serial.print(" currentLongitude = ");Serial.println(currentLongitude,5);
#endif
}
Slave
#include <Wire.h>
#include <NewSoftSerial.h>
#include <TinyGPS.h>
#include <stdlib.h>
#define commPin 9
float currentLatitude, currentLongitude;
TinyGPS gps;
NewSoftSerial nss(2, 3);
void setup()
{
Wire.begin(2); // join i2c bus with address #2
Wire.onRequest(sendGPSData); // register event
nss.begin(4800);
Serial.begin(115200);
pinMode(commPin, OUTPUT);
digitalWrite(commPin, LOW);
void loop()
{
requestGPSDataFromDevice();
}
void sendGPSData()
{
char bufferLatitude[8];
char bufferLongitude[8];
char bufferToSend[17];
dtostrf(currentLatitude,8,5,bufferLatitude); // double to string
dtostrf(currentLongitude,8,5,bufferLongitude);
for(int i=0;i<8;i++)
bufferToSend[i] = bufferLatitude[i];
bufferToSend[8]=' ';
for(int i=9;i<17;i++)
bufferToSend[i] = bufferLongitude[i-9];
Wire.send(bufferToSend);
}
void requestGPSDataFromDevice()
{
bool newdata = false;
unsigned long start = millis();
// Every 1 seconds we take an update
while (millis() - start < 1000)
{
if (feedgps())
newdata = true;
}
if (newdata)
{
digitalWrite(commPin, HIGH);
Serial.println("Acquired Data");
Serial.println("-------------");
gpsdump(gps);
Serial.println("-------------");
Serial.println();
}
else
{
digitalWrite(commPin, LOW);
Serial.println("No fix...");
}
}
void gpsdump(TinyGPS &gps)
{
float flat, flon;
unsigned long age, chars;
unsigned short sentences, failed;
//feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors
gps.f_get_position(&flat, &flon, &age);
Serial.print("Lat/Long(float): "); Serial.print(flat, 5); Serial.print(", "); Serial.print(flon, 5);
Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
currentLatitude = flat;
currentLongitude = flon;
feedgps();
gps.stats(&chars, &sentences, &failed);
Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: "); Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed);
if (age == TinyGPS::GPS_INVALID_AGE)
Serial.println("No fix detected");
else if (age > 1000)
Serial.println("Warning: possible stale data!");
else
Serial.println("Data is current.");
feedgps();
}
bool feedgps()
{
while (nss.available())
{
if (gps.encode(nss.read()))
return true;
}
return false;
}
You will notice that I have connected the digital pins 9 of the boards, input on master, output on slave and pull it HIGH when there is a fix of the GPS. Master reads the pin input to proceed requesting the data.
I also tried to feed the gps object during the sendGPSData() function but I didn't see any improvements.
Does anyone know why this happens? How can I work this around?