Working with GPS on my Arduino board

Hi! I have a Globalsat EM-406 / 411 GPS connected to my Arduino board and need a code to get it working. I found one in an older post:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1166042147/

But couldn't quite get it to work. Is there anyone who have programmed a similar device who can help me out?

Thanks for any help!

But couldn't quite get it to work.

What doesn't quite work?

Can you post your code?

Woah, I ment this one, sorry…

#include <SoftwareSerial.h>
// Pin 12 = MISO
// Pin 11 = MOSI
#define rxPin 11
#define txPin 12
#define GPS_BUFFER_SIZE 82

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
byte pinState = 0;

void Printfloat(float a) //Printfloat is a function made here in order to send a float value with dec(=2) digits precision.
{

char n;
int d, dec=2; //dec; decides number of decimals. NB: MAX 5 decimals!
if(a<0) { //The if is for making the Printfloat function work for negative numbers
a = -a;
Serial.print(’-’);
}
int whole = (int)a;
int fract = (int)(pow(10,dec) * (a - (float)whole));
Serial.print(whole);
Serial.print(’.’);
Serial.print(fract);
}

//Get the GPS
void get_gps()
{
char string[GPS_BUFFER_SIZE];
char a;
int ctr;
try_again:
ctr = 0;

while((a = mySerial.read()) != ‘$’);
while((string[ctr++] = mySerial.read()) != ‘\n’);
string[ctr-1] = 0x20;
string[ctr-2] = 0x20;
string[ctr] = 0;

if((ctr = strncmp(string,“GPGGA”,5)) == 0) {
Serial.print(“S”);
// Pick chars 17,18,19,20,21,22,23,24,25,26
Serial.print(string[17]);
Serial.print(string[18]);
Serial.print(string[19]);
Serial.print(string[20]);
Serial.print(string[21]);
Serial.print(string[22]);
Serial.print(string[23]);
Serial.print(string[24]);
Serial.print(string[25]);
//Pick chars 30,31,32,33,34,35,36,37,38,39
Serial.print(" “);
Serial.print(string[29]);
Serial.print(string[30]);
Serial.print(string[31]);
Serial.print(string[32]);
Serial.print(string[33]);
Serial.print(string[34]);
Serial.print(string[35]);
Serial.print(string[36]);
Serial.print(string[37]);
Serial.print(string[38]);
//Pick chars 52,53,54,55
Serial.print(” “);
Serial.print(string[51]);
Serial.print(string[52]);
Serial.print(string[53]);
Serial.print(string[54]);
Serial.print(string[55]);
Serial.print(string[56]);
//Pick chars 45,46
Serial.print(” ");
Serial.print(string[44]);
Serial.print(string[45]);

} else {goto try_again;

}

}

// This function is executed at power up
void setup()
{
Serial.begin(38400); // configure the serial port to 38400 baud
pinMode(8,OUTPUT); // configure the port with the LED
digitalWrite(8,HIGH); // Turn off the LED
pinMode(rxPin, INPUT); // Set the input from GPS
pinMode(txPin, OUTPUT); // Set the output from GPS
mySerial.begin(4800); // GPS Serial start with 4800 baud rate
delay(200);
Serial.println(“F8D1D1”); // Set the Transmitter Frequency
delay(500);
Serial.println(“CSTBNC7”); // Set the ID
delay(200);
}

int counter;
void loop()
{
int pressure;
int temperature;
float acc;
float voltage;
float kpa;
float celcius;
long time;

counter++;

get_gps(); // Run the GPS function
pressure = analogRead(0); // read analog port 0 with the pressure sensor
temperature = analogRead(1); // read analog port 1 with the temperature sensor
acc = analogRead(2); // read analog port 2 with the accelerometer
voltage = (float)pressure / 1023.0 * 5.0; // calculate the voltage of the pressure sensor
kpa = 22.222 * voltage + 10.566; // calculate the pressure in KPa
voltage = (float)temperature / 1023.0 * 5.0; // calculate the voltage of the temp. sensor
celcius = voltage * 50.0 + 4.5; // calculate the temperature in Celcius
Serial.print(" “); // send transmit command to transmitter
Printfloat(kpa); // print the pressure sensor value
Serial.print(” “); // insert a space
Printfloat(celcius); // print the temperature
Serial.print(” “); // insert space and terminate
Printfloat(acc); // Accelerometer
Serial.print(” ");

time=millis();
Serial.print(counter);
Serial.print(" “);
Serial.print(time);
Serial.println(”");

digitalWrite(8, LOW); // LED ON
delay(100);
digitalWrite(8, HIGH); // LED OFF
delay(400);
// wait 500 milliseconds

}

I get coordinates but they are waaay off. So it's really a question of calibrating...

I'm sorry for lack of information.

get coordinates but they are waaay off

How far is "Waaay"? Crab Nebula? Woking?

"Waaay" is almost the other side of the world...

MrPotatoSatellite: I get coordinates but they are waaay off.

Have you tried printing the entire string to make sure all of the fields are present? How about pasting the actual string into your post.

I have seen some receivers that leave out some of the stuff. (They just put successive commas without any digits for some of the items, so actual positions of some meaningful fields in the string may be different.)

Like this: I get stuff like this:


[color=blue]$GPRMC,191834.607,A,3813.9806,N,12237.8049,W,,,141110,,*1C
$GPGGA,191835.607,3813.9749,N,12237.8051,W,0,03,,24.7,M,-24.7,M,,0000*7A
$GPGSA,A,1,25,04,02,,,,,,,,,,,,*1F[/color]

The TinyGPS library seems successful in being able to parse lines with empty fields (at least it works for me with an EM-406A module).

Now, assuming all of the fields that you need are present and are in the expected place in the string so that you can actually get the latitude and longitude numbers from the receiver:

Shouldn't you be checking character 42 in your array (the Fix Quality) and, maybe, characters 44 and 45 (Number of Active Satellites)? I mean, a GPS receiver will spit out messages every second, regardless of conditions. You have to check to see whether they are meaningful, right?

What values, exactly, are you getting for the latitude and longitude items? What is your actual latitude and longitude?

Regards,

Dave

Footnote: Current Arduino libraries will print floats without the special function in your code. You can reduce source code clutter by just calling Serial.print for your floats.

besides TinyGPS, you should use the NewSoftSerial library, both of which were written by Mikal Hart. Just google it.