reading GPS NMEA from BT-359

I'm posting this just in case anyone wants to play with a globalsat bt-359 GPS module.

here's a picture of where you can find the serial NMEA data being fed from the GPS module to the bluetooth module. tap into it at will! it's labelled TP4, baudrate 38400.

a good way to test for the GPS serial pin is to plug you arduino into your computer, load this sketch and just fiddle with pins until a bunch of proper looking numbers come up in the serial terminal:

void setup(){
Serial.begin(38400);
}

void loop(){
if(Serial.available()){
while(Serial.available()){
Serial.print(byte(Serial.read()));
delayMicroseconds(300);
}
Serial.println("");
}
}

that basicly just echoes what the arduino reads straight to your PC.

once you find the pin, you can upload this sketch which exctracts all the data from the NMEA string coming out of the GPS and turn them into numbers:

String prefix="";
String GPRMC="";
String GPGGA="";
long lattitude; // imma make these the angle x 10^6 to avoid using floats
long longitude;
long altitude;
long fixtime; // this is time in seconds x 1000
long fixdate;
int dltm=209; /* the delay in us between serial reads,
used just for some troubleshooting .
So far I believe it is (number of us in a second)/(baud x 8)
= 1000000/(38400*8) = 208.3333
*/

void setup(){
Serial.begin(38400);
digitalWrite(13,HIGH);
}

void loop(){
if(Serial.available()){
prefix="";
for(int i=0;i<6;i++){
prefix+=byte(Serial.read());
delayMicroseconds(dltm);
}

/* okay for this 'while' bit, the code looks to see if
prefix == "$GPRMC" ; otherwise it shifts all the
characters along to the left by one and adds the next
serial character on and compares again. It keeps doing
this until $GPRMC is found or the serial buffer is
empty. Then if prefix is equal to GPRMC or GPGGA, well
I'm sure you can guess that it reads the appropriate data into
the apropriate string. /
while(Serial.available()){
if(prefix=="$GPGGA"){
GPGGA="";
while(Serial.available()){
// this adds bytes to GPGGA until * is reached,
// signalling the end of the GPGGA part.
GPGGA+=byte(Serial.read());
if(GPGGA.endsWith("
")){
break;
}
delayMicroseconds(dltm);
}
Serial.println("$GPGGA"+GPGGA);
}
if(prefix=="$GPRMC"){
GPRMC="";
while(Serial.available()){
// this adds bytes to GPRMC until there are none
// left, since its the last part.
GPRMC+=byte(Serial.read());
delayMicroseconds(dltm);
}
Serial.println("$GPMRC"+GPRMC);
}
else{
prefix=prefix.substring(1)+byte(Serial.read());
delayMicroseconds(dltm);
}
}
/* okay, now lets interpret the GPGGA and GPRMC strings!
Since the bt-359 GPS wierdly only sends a GPMRC 4 times every
5 seconds, I will be taking the position from the GPGGA
string which is updated every second, and then the speed and
date from GPRMC since GPGGA doesn't have this info.
If you are using a better GPS that doesn't have this freakout,
you might want to just get everything from the GPRMC for
simplicity. */

/* since the NMEA gives your position in degrees minutes and seconds
and I simply hate that, these minute/seconds stupid things will
be converted to decimal, I don't know if this is the best way but
yeah, whatevs :smiley: */

/* all the commented Serial.print's are for debugging purposes,
I am quite a noob at this! */

String lattdecstrng1=GPGGA.substring(14,16);
String lattdecstrng2=GPGGA.substring(17,19);
String lattdecstrng3=GPGGA.substring(19,21);
// Serial.print(lattdecstrng1);
// Serial.print(lattdecstrng2);
// Serial.println(lattdecstrng3);
char lattdecchar1[3];
char lattdecchar2[3];
char lattdecchar3[3];
lattdecstrng1.toCharArray(lattdecchar1, 3);
lattdecstrng2.toCharArray(lattdecchar2, 3);
lattdecstrng3.toCharArray(lattdecchar3, 3);
// Serial.print(lattdecchar1);
// Serial.println(lattdecchar2);
// Serial.println("now the above mapped =");
int lattdecunmapped1=atoi(lattdecchar1);
int lattdecunmapped2=atoi(lattdecchar2);
int lattdec3=atoi(lattdecchar3);
// lattdecstrng3 is already in a base 10 from
long lattdec1=lattdecunmapped11000000/60;
long lattdec2=lattdecunmapped2
lattdec32.7778; // same as (lat210^6)/((lat3/100)*3600)
// Serial.println(lattdec1);
// Serial.println(lattdec2);
long lattdec=lattdec1+lattdec2;
// wow all that shit there just for the DECIMAL part of lattitude
String lattintstrng=GPGGA.substring(13,15);
char lattintchar[3];
lattintstrng.toCharArray(lattintchar, 3);
long lattint=atoi(lattintchar)*1000000;
lattitude=lattint+lattdec;
Serial.print("lattitude in degrees x 10^6 : ");
Serial.println(lattitude);

// OKAY now for longitude

String longdecstrng1=GPGGA.substring(27,29);
String longdecstrng2=GPGGA.substring(30,32);
String longdecstrng3=GPGGA.substring(32,34);
char longdecchar1[3];
char longdecchar2[3];
char longdecchar3[3];
longdecstrng1.toCharArray(longdecchar1, 3);
longdecstrng2.toCharArray(longdecchar2, 3);
longdecstrng3.toCharArray(longdecchar3, 3);
int longdecunmapped1=atoi(longdecchar1);
int longdecunmapped2=atoi(longdecchar2);
int longdec3=atoi(longdecchar3);
// lattdecstrng3 is already in a base 10 from
long longdec1=longdecunmapped11000000/60;
long longdec2=longdecunmapped2
longdec3*2.7778;
// Serial.println(longdec1);
// Serial.println(longdec2);
long longdec=longdec1+longdec2;
// wow all that shit there just for the DECIMAL part of longitude
String longintstrng=GPGGA.substring(24,27);
char longintchar[4];
longintstrng.toCharArray(longintchar, 4);
long longint=atoi(longintchar)*1000000;
longitude=longint+longdec;
Serial.print("longitude in degrees x 10^6 : ");
Serial.println(longitude);

// phew, what a bloody handful.
// okay,
}
}

to be honest, it's been a while since i used these but I think it works. If not, just fiddle around, idk, I wrote this when I was a n00b so it's probably very innefficient

It's stressful to get this stuff working, and it is very specific to the bt-359 that I have which doesn't spit full strings, so I hope this is of any use to anyone

I don't know how many people have the BT-359 but, showing your process like you have can help people crack their own devices. Therefore, thanks for sharing!

Thank you very much for your observation, hope this would help me to get use my BT-359 in my project instead of buying another GPS module.

Hi. I realise this is an old thread but I just wanted to add a little to it for others.

I was scratching my head for a while in a noobish way as the sketch at the top (for sniffing out the TX pad) was pumping out streams of numbers rather than the NMEA text string. After trying multiple alternative baud rates and things (mine is a v2.0.1 board so I thought it may differ to the one in the post here) I realised that the stuff coming out on the Serial monitor was the ASCII in decimal form. After a little while and some luck I found that all I needed to do was change the line from Serial.print() to Serial.write() and remove the byte() function. so I have:

int incomingByte = 0;	// for incoming serial data

void setup() {
  Serial.begin(38400);	// opens serial port, sets data rate to 9600 bps
}

void loop() {

  // send data only when you receive data:
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();

    // say what you got:
//    Serial.print("I received: ");
    Serial.write(incomingByte);

  }
}

This now spits out the correct NMEA sentences and all is good.

I am also powering the board from the 3.3v pins on the Arduino. I don't know if this is ok to do but it seems to work. The battery is ratted as 3.7v so i figured 3.3v is like the battery is running out. To confirm this the board does show the red power light like when the battery is about to die. It all still works and finds the gps fix with no issue.

Does anyone know if there is a way to prevent the auto-off function of the board. It goes off after 10 mins without BT connection but now I'm hacked into it I want it to stay alive all the time. Is there a way I can trick it into thinking it's BT connected without actual bluetooth?

me too worried about 10 minute standby limit before connecting it, so I connected my phone to it at the start, but surprisingly mine keeps working even after four hours, without any kind of Bluetooth connection.

FIY: But in my case the GPS keeps feeding Arduino and it is installed with its battery and charging usb connection, in order to do that I soldered the TP4 pad with small piece of Solar Cell tabbing wire.

hope this helps.

Now I'm just thinking out loud here, but would there be any way to directly power just the GPS module in here without the bluetooth at all? How would I go about working out if any of the TP# or PAD# spots would be for power and ground (without blowing it up :blush:) and would it need serial commands sent to it to tell it what to do or does it just power up and start transmitting data?

Anyone got any ideas if or how to go about this?

Cheers