How do I send a serial command to GPS?

Hi again!

I have a Parallax GPS Receiver Module (http://www.parallax.com/Store/Microcontrollers/BASICStampModules/tabid/134/txtSearch/gps/List/1/ProductID/396/Default.aspx?SortField=ProductName%2CProductName).

The commands I need to send are documented in this PDF on page 4: http://www.parallax.com/Portals/0/Downloads/docs/prod/acc/GPSManualV1.1.pdf . Also in this doc is sample code, but it's for a BASIC stamp, so it's a bit of gobbledygook to me, but I've tried to interpret that and convert it to C/Arduino.

It says "To send a command to the GPS Receiver Module, the user must first send the header string, which is “!GPS” without the quotes, followed by the specific command byte of their choice. Each command consists of a single byte in hexadecimal. Depending on the command, a specific number of data bytes will be returned."

I am trying to send this command: 0x00 as my first test...just for somewhere to start. What code should I be using to send the serial command to the GPS module? I am currently trying...

  Serial.print("!GPS");
  Serial.print(0x00, HEX);

And i also tried:

  Serial.println("!GPS");
  Serial.println(0x00, HEX);

And:

  byte Command = 0x00;
    // Send command
  Serial.println("!GPS" && Command);

Would someone mind pointing me in the right direction here on how to send the command? Once I've got that nutted out, I'll be onto trying to receive the response. Eek! :-?

Cheers,
Scott.

scootabug,

I think what you want is:

Serial.print("!GPS");
Serial.print(0x00, BYTE);

The "HEX" specifier means that you want to render the value as a hexadecimal value in ASCII. Perhaps an example would be clearer:

int x = 0x23;

Serial.print(x); // sends two bytes: a '3' and a '5'
Serial.print(x, HEX); // sends a '2' and a '3'
Serial.print(x, BYTE); // sends a single byte: 0x23

Mikal

Thanks Mikal.

I still can't get this working. One problem I can see is that this GPS module has only one wire for serial data (it only has an SIO, no TX/RX). I'm wondering if I'm seeing the data I'm sending as I am trying to receive?

This is the code I have at the moment:

void loop() {

  digitalWrite(ledPin, LOW);

  Serial.print("!GPS");
  Serial.print(0x00, BYTE); 
  delay(100);

  millisStart = millis();

  while(millis() < (millisStart + 3000)){
    if (Serial.available() > 0) {
      // read the incoming byte:
      incomingByte = Serial.read();

      // say what you got:
      Serial.print("I received: ");
      Serial.println(incomingByte, DEC);
    }
  }
}

I've got a 3 second loop there and I am varying the initial delay after sending the command to attempt to miss my send. Not even sure if that makes sense.

At the moment my output is varying like so:
I received: 10
I received: 73
I received: 32
I received: 114
I received: 13
I received: 13
I received: 13
I received: 13
I received: 13

What method should I actually be using here? This makes no sense to me at all really...communicating on the one wire!

Thanks again for your help...it is a godsend!

Cheers,
Scott

Well since my last post I've managed to realise that I'm not handling the data correctly, even if it is coming back after I send the command. I can't tell if I'm even sending it properly so I'm not sure where to go from here!

have you looked at this?

http://www.arduino.cc/playground/Tutorials/GPS

It has all the arduino code necassary to run the Parallax GPS unit that you have.

@Paul: Yep. I used that sample code and it works great. I'm just interested to learn how I send and receive the commands to it as they do with the BASIC stamp. Thanks for the input!

That tutorial has always puzzled me. The code shows pin 1 being used as an output pin, but in the diagram it's not hooked up to anything.

Mikal

It is a tad strange about Pin 1 being an output, because you're right Mikal, it's not used at all in his code. It is declared as txPin, so maybe he had been sending serial commands to the GPS (which is what I am trying to do!).

Any thoughts on how you send and receive over 1 wire? At the moment I'm puzzled!

I have no idea whether this would work, but it's the only way I can think of to do tx/rx over the same pin. Let's say the GPS's SIO is hooked up to Arduino 2. Create a SoftwareSerial object with txpin=2 and use it to transmit. Then destroy that object and create a new one with rxpin=2 to receive the response. Something like this:

#include <SoftwareSerial.h>
#define SIOPIN 2
void loop()
{
  {
    SoftwareSerial s(-1, SIOPIN); //rxpin=ignore, txpin=2
    s.begin(4800);
    s.print("!GPS");
    s.print(0, BYTE);
  }
  {
    SoftwareSerial s(SIOPIN, -1); //rxpin=2, txpin=ignore
    s.begin(4800);
    while (true)
    {
      int c = s.read();
      if (c != -1)
      {
        //got a char
      }
    }
  }
}

EDIT: fixed per next message

Mikal

Looks good. I notice you've got rx and tx switched around...SoftwareSerial(rxPin, txPin). I'm having a play with it now, I'll post again when I get a result. Thanks!

Just out of curiosity, did the technique of repeatedly creating and destroying SoftwareSerial objects yield any interesting results?

Mikal

It didn't fair too well actually. Couldn't get anything sent or received until I moved "
SoftwareSerial SerialFPS = SoftwareSerial(rxPin, txPin);" prior to the Setup() function.