3D Robotics

Basic Stamp autopilot tutorial, part 3

SparkFun has quite a few GPS modules, but I prefer the EM406, because it uses the standard 5v power we're using on the dev board (as opposed to the EM408, which needs 3.3v) and has a handy red LED to show sat acquisition status (the 408 doesn't).

There are two difference between using the Parallax GPS module and a third-party one like the EM406. The first is that you've got to wire up a connector so the EM406's cable can plug into our Basic Stamp breadboard. The second is that while the Parallax GPS module has a "smart mode", where you can query the GPS module for a specific data field (lat, lon, # sats, etc) and it will return just that, most other modules such as the EM406 continuously output all their data in "NEMA sentences" that you have to parse.

The connector you need to wire up looks like this (right), and is simply made by cutting off one end of the connector cable and soldering (and covering with heat-shrink tubing) the wires to a six-pin segment of break-away headers. You can plug the header pins straight into your breadboard (we'll actually only be using three of the first four pins--ground, V+and tx--so if you want to use just a three-pin header you can.)

If you're planning to place the GPS module at some distance from the autopilot (like on the top of your plane's fuselage or on a wing, which is always a good idea to ensure the best reception), the cable construction process is a good time to splice longer wires on, too. Or, since we just use three of the six pins, you can use a standard servo extension cable, which fits the header strip and can plug into the Basic Stamp development board's servo port, just as easily.

All this is covered in more detail in this very handy tutorial. (The full series on that and code files are here). [UPDATE: that tutorial has an error in the EM406 pin diagram. The actual pins you need are 1 (ground), 2 (V+) and 4 (Tx). The proper instructions can be found here.]

Here's some Basic Stamp code I wrote that will test your GPS, displaying the NEMA sentences on your PC debug terminal. As always, change it if you're using a different pin for the GPS Tx (this code has it on pin 9) or if you're using a Stamp other than the BS2p (by modifying the "GPSBD CON 500" as instructed by the comments on that line)

The second thing you need to do is write a GPS parser to extract the data you need from these NEMA sentences for your autopilot code. Fortunately many have come before you, so you can just modify the code you need from this series of tutorials, or just roll your own. I haven't modified our own autopilot code yet to use this GPS module, but I'll get to that in the next week or so. [UPDATE: here it is]

Previous posts in this series:

Tutorial 1 -- Servos
Tutorial 2 -- Reading the Rx
E-mail me when people leave their comments –

You need to be a member of diydrones to add comments!

Join diydrones

Comments

  • sample.TXTAlso, SIRFDemo seems to leave your EM406 talking at 9600 baud. This will mean that you should use 84 instead of 188 for the SERIN config. You can look at raw data by simply connecting the EM406 through the FTDI (USB to Serial) and using "hyper terminal"
  • A quick pointer for anyone using a BS2 or BS2e > this code does not seem to work even if the SERIN GPSBD variable is changed. Apparently the SPSTR keyword is only supported on a few of the more expensive Stamps. This allows the serial NMEA to be dumped to scratchpad RAM. Ah, well ;(
    At least you can test the GPS by using the SIRFDemo utility (See Sparkfun) or use one of Jordi's test routines on the Ardupilot..

    Also, you can save your connector by using some wirewrap
  • 3D Robotics
    Here's a subroutine to read GPS in Arduinio:

    // This subroutine reads GPS sentences, spots the one we're looking for [either GPRMC (case 1) or GPGGC (case 2)]and hands over to a NMEA parser

    void GPS(int NMEAtype)
    {
    time1 = millis();
    time2 = time1;
    stop = false;
    good = 0;
    while (!stop && (time2-time1 < 1000)) // loop until you've found the string you're looking for or have run out of time
    {
    time2 = millis();
    if (time2-time1 > 999) {Serial.println("Timed out!");}
    if (Serial.available()>0)
    {
    byteGPS = Serial.read();
    if (byteGPS == 13) {Serial.println("");}
    if (byteGPS > 32) // only print printable characters
    {
    Serial.print(byteGPS); // for debugging
    }
    } else {delay (5);}
    if (byteGPS == 36) // if you've reached a "$"
    {
    Serial.println("");
    good = 0;
    for (int i=1; i<6;i++)
    {
    if (Serial.available()>0)
    {
    line[i] = Serial.read();
    } else {delay (5);}
    delay (5); // here to get serial timings right, to compensate for the slow GPS baud rate
    if (NMEAtype == 1)
    {
    if (line[i] == commandGPRMC[i-1])
    {
    good++;
    }
    }
    if (NMEAtype == 2)
    {
    if (line[i] == commandGPGGA[i-1])
    {
    good++;
    }
    }
    }
    }
    if (good == 5) // you've found the string you're looking for, now get the rest of it
    {
    counter = 5;
    if (NMEAtype == 1) {Serial.print("GPRMC");} // for debugging
    if (NMEAtype == 2) {Serial.print("GPGGA");} // for debugging
    stop2=false;
    while (!stop2) // get the rest of the string until you hit a line feed or have gone too far
    {
    if (Serial.available()>0)
    {
    line[counter] = Serial.read();
    if (line[counter] > 32) // only print printable characters
    {
    Serial.print(line[counter]);
    }
    if (line[counter] == 13) {stop2=true;} // hit a line feed
    if (line[counter] == 36) {stop2=true;} // hit a $, the start of the next sentence
    counter++;
    if (counter > 100) {stop2=true;}
    } else {delay (5);}
    delay(2); // to compensate for the slow GPS baud rate
    }
    Serial.println(""); // for debugging
    Serial.println ("Found right NMEA"); // for debugging
    stop=true;
    convertNMEA(NMEAtype);
    }
    }
    }
  • I have a problem with my GPS too, I'm programming a LR9540 GPS with a atmega128 AVR, I've got a source code for programming AVR, it sets GPS's RS232 buad rate itselfe.
    I send a string o GPS to take my buad-rate. but when it start to work it just send unknown charactors... I dont know how to made GPS know my buad-rate...
    you'll makeme so happy if you help... or just send a sample code in C which connect a GPS to a atmega128..
    srry for my bad english, my english i terrible ... :(
    I'm waiting for your help hoply ... :)

    sara_n_a_84@yahoo.com
  • 3D Robotics
    The EM 408 (link below) does, but you'll need a power converter to handle the module's 3.3v requirement. The tutorial I linked to above discusses how to do that.

    http://www.sparkfun.com/commerce/product_info.php?products_id=8234
  • Do either of these GPS modules, Parallax or Sparkfun, have a socket for a external antenna?
  • 3D Robotics
    James,

    Don't worry, it's good enough for most uses (I've flown very happily with it). It's also a lot more straightforward to use and better for beginners. I just wanted to ensure that those wanting to go to the next stage were served, too.

    For some people with reception problems, the SIRF III boards are the solution. But unless you're flying in the shadows of skyscrapers or at the north pole, I'm sure the Parallax board will be good enough ;-)
  • Hmm...and I just orderd the Parallax GPS module. Arrghh...
This reply was deleted.