(edit sidebar)
Intro to Physical Computing Syllabus

Research & Learning

Other Class pages

Shop Admin

ITP Help Pages
Tom's pcomp site
DanO's pcomp site


Reading A Serial Protocol

Tutorials.ReadingASerialProtocol History

Hide minor edits - Show changes to output

Changed lines 19-20 from:
GPS reader --> USB-to-serial adaptor --> computer's USB port --> Processing
to:
%alt='gps system diagram'%http://itp.nyu.edu/physcomp/images/gps_system_diagram.png
Added lines 21-22:
[[<<]]
Added line 14:
%lfloat margin=10 alt='Garmin GPS72 reader screen'%http://itp.nyu.edu/physcomp/images/gps_screen.JPG
Changed lines 142-144 from:
@]
to:
@]

That's it!
Changed line 127 from:
to:
[@
Changed lines 141-142 from:
}
to:
}
@]
Changed lines 24-27 from:
->Under the NMEA-0183 standard, all characters used are printable ASCII text (plus carriage return and line feed).  NMEA-0183 data is sent at 4800 baud.-<

-
>The data is transmitted in the form of "sentences".  Each sentence starts with a "$", a two letter "talker ID", a three letter "sentence ID", followed by a number of data fields separated by commas, and terminated by an optional checksum, and a carriage return/line feed.  A sentence may contain up to 82 characters including the "$" and CR/LF.-<
to:
->Under the NMEA-0183 standard, all characters used are printable ASCII text (plus carriage return and line feed).  NMEA-0183 data is sent at 4800 baud.

->The data is transmitted in the form of "sentences".  Each sentence starts with a "$", a two letter "talker ID", a three letter "sentence ID", followed by a number of data fields separated by commas, and terminated by an optional checksum, and a carriage return/line feed.  A sentence may contain up to 82 characters including the "$" and CR/LF.
Changed lines 24-27 from:
->Under the NMEA-0183 standard, all characters used are printable ASCII text (plus carriage return and line feed).  NMEA-0183 data is sent at 4800 baud.

The data is transmitted in the form of "sentences".  Each sentence starts with a "$", a two letter "talker ID", a three letter "sentence ID", followed by a number of data fields separated by commas, and terminated by an optional checksum, and a carriage return/line feed.  A sentence may contain up to 82 characters including the "$" and CR/LF.-<
to:
->Under the NMEA-0183 standard, all characters used are printable ASCII text (plus carriage return and line feed).  NMEA-0183 data is sent at 4800 baud.-<

->
The data is transmitted in the form of "sentences".  Each sentence starts with a "$", a two letter "talker ID", a three letter "sentence ID", followed by a number of data fields separated by commas, and terminated by an optional checksum, and a carriage return/line feed.  A sentence may contain up to 82 characters including the "$" and CR/LF.-<
Changed lines 24-29 from:
->
Under the NMEA-0183 standard, all characters used are printable ASCII text (plus carriage return and line feed).  NMEA-0183 data is sent at 4800 baud.

The data is transmitted in the form of "sentences".  Each sentence starts with a "$", a two letter "talker ID", a three letter "sentence ID", followed by a number of data fields separated by commas, and terminated by an optional checksum, and a carriage return/line feed.  A sentence may contain up to 82 characters including the "$" and CR/LF.
-<
to:
->Under the NMEA-0183 standard, all characters used are printable ASCII text (plus carriage return and line feed).  NMEA-0183 data is sent at 4800 baud.

The data is transmitted in the form of "sentences".  Each sentence starts with a "$", a two letter "talker ID", a three letter "sentence ID", followed by a number of data fields separated by commas, and terminated by an optional checksum, and a carriage return/line feed.  A sentence may contain up to 82 characters including the "$" and CR/LF.-<
Changed lines 28-29 from:
<-
to:
-<
Deleted lines 0-1:
! Reading an Existing Serial Protocol
Deleted lines 58-59:
!! Write a program that just reads the protocol
Added lines 70-71:
!! Write a program that just reads the protocol
Added lines 116-117:
!! Add a method to parse the data once you know you have it
Changed line 106 from:
  String myString = myPort.readStringUntil(carriageReturn);
to:
  String myString = myPort.readStringUntil(linefeed);
Changed lines 116-118 from:
Once you've got the string, you can pass it to a method to parse the string, like so:

to:
Once you've got the string, you can pass it to a method to parse the string. First, add a few global variables at the beginning of the program:

[@
float latitude = 0.0;    // the latitude reading in degrees
String northSouth;      // north or south?
float longitude = 0.0;  // the longitude reading in degrees
String eastWest;        // east or west?
@]


Then replace @@println(myString);@@ above with @@parseString(myString);@@

Then add this method at the end of the program:

void parseString(String serialString) {
  // split the string at the commas
  //and convert the sections into integers:
  String items[] = (split(serialString, ','));
  // if the first item in the sentence is our identifier, parse the rest:
  if (items[0].equals("$GPGLL") == true) {
    // move the items from the string into the variables:
    latitude = float(items[1]);
    northSouth = items[2];
    longitude = float(items[3]);
    eastWest = items[4];
    println(latitude + northSouth + "," +longitude + eastWest);
  }
}
Changed lines 116-118 from:
to:
Once you've got the string, you can pass it to a method to parse the string, like so:

Changed lines 22-23 from:
!! Understand the protocol's structure
to:
!! Understand the protocol's structure, and look at it
Added lines 59-60:
!! Write a program that just reads the protocol
Added lines 72-116:
To convert this into code, start by just reading the serial data in until you get a carriage return.  Following is the Processing code:

[@

// import the serial library:
import processing.serial.*;

int linefeed = 10;      // linefeed in ASCII
int carriageReturn = 13; // carriage return in ASCII
Serial myPort;          // The serial port

void setup() {
  // List all the available serial ports
  println(Serial.list());

  // I know that the first port in the serial list on my mac
  // is always my  Keyspan adaptor, so I open Serial.list()[0].
  // Open whatever port is the one you're using.
  myPort = new Serial(this, Serial.list()[0], 4800);

  // read bytes into a buffer until you get a carriage return (ASCII 13):
  myPort.bufferUntil(carriageReturn);
}

void draw() {
  // not doing anything here
}

// serialEvent  method is run automatically by the Processing applet
// whenever the buffer reaches the  byte value set in the bufferUntil()
// method in the setup():

void serialEvent(Serial myPort) {
  // read the serial buffer:
  String myString = myPort.readStringUntil(carriageReturn);
  // if you got any bytes other than the linefeed:
  if (myString != null) {
    // print it:
    println(myString);
  }
}

@]

Added line 65:
Use the third element to determine north/south
Added line 67:
Use the fifth element to determine east/west
Changed lines 48-51 from:
You know from the description above that each line is a sentence.  Reading further in the NMEA FAQ, you learn that there are several formats of the sentence, and that the first element ($GPRMC, $GPGLL, etc) describes the sentence.  You'd need to read the descriptions o the sentences to see which one contains the data you need.


to:
You know from the description above that each line is a sentence.  Reading further in the NMEA FAQ, you learn that there are several formats of the sentence, and that the first element ($GPRMC, $GPGLL, etc) describes the sentence.  You'd need to read the descriptions o the sentences to see which one contains the data you need. If all you need is latitude and longitude, the $GPGLL sentence looks easy:

[@
  GLL - Geographic position, Latitude and Longitude
        GLL,4916.45,N,12311.12,W,225444,A
          4916.46,N    Latitude 49 deg. 16.45 min. North
          12311.12,W  Longitude 123 deg. 11.12 min. West
          225444      Fix taken at 22:54:44 UTC
          A            Data valid
@]

In other words, the first item in the sentence names the sentence, the second is latitude, the third identifies north/south, the fourth is longitude, the fifth identifies east/west, and the sixth is the time of the reading. Each item is separated by a comma. So you can already write an outline for a program to read it, like so:

[@
Read data into a string until you get a carriage return
Separate the string into individual elements at the commas
Put the second element into a variable called @@latitude@@
Put the fourth element into a variable called @@longitude@@
@]

Changed lines 24-25 from:
The NMEA FAQ explains the NMEA protocol well, specifically that it is an ASCII-based protocol, that each reading ends in a
to:
The [[http://vancouver-webpages.com/peter/nmeafaq.txt |NMEA FAQ]] explains the NMEA protocol well, including this summary:

->
Under the NMEA-0183 standard, all characters used are printable ASCII text (plus carriage return and line feed).  NMEA-0183 data is sent at 4800 baud.

The data is transmitted in the form of "sentences".  Each sentence starts with a "$", a two letter "talker ID", a three letter "sentence ID", followed by a number of data fields separated by commas, and terminated by an optional checksum, and a carriage return/line feed.  A sentence may contain up to 82 characters including the "$" and CR/LF.
<-

In other words, it operates at 4800 bits per second, it's all in ASCII, and each sentence ends with a carriage return and a linefeed. The simplest way to see if you can read it is to open a serial terminal program. Open up Hyperterminal, zTerm, or screen and see what comes in. You'll get something like this:

[@
$GPRMC,175822,V,4043.8533,N,07359.7486,W,0.0,0.0,010606,13.4,W,S*29
$GPRMB,V,9.99,R,,GARMIN,3851.3330,N,09447.9410,W,966.357,270.1,,V,S*69
$GPGGA,175822,4043.8533,N,07359.7486,W,8,11,2.0,20.6,M,-34.0,M,,*45
$GPGLL,4043.8533,N,07359.7486,W,175822,V,S*50
$GPBOD,257.4,T,270.8,M,GARMIN,*50
$GPBWC,175822,3851.3330,N,09447.9410,W,270.1,T,283.5,M,966.357,N,GARMIN,S*75
$GPVTG,0.0,T,13.4,M,0.0,N,0.0,K*78
$GPXTE,V,V,9.99,R,N,S*06
$PGRME,15.0,M,22.5,M,27.0,M*1A
$PGRMZ,68,f,3*25
$PGRMM,WGS 84*06
@]

You know from the description above that each line is a sentence.  Reading further in the NMEA FAQ, you learn that there are several formats of the sentence, and that the first element ($GPRMC, $GPGLL, etc) describes the sentence.  You'd need to read the descriptions o the sentences to see which one contains the data you need.


Changed lines 22-23 from:

to:
!! Understand the protocol's structure

The NMEA FAQ explains the NMEA protocol well, specifically that it is an ASCII-based protocol, that each reading ends in a

Changed lines 18-19 from:
Since many laptops nop longer have RS-232 serial ports,
to:
Since many laptops no longer have RS-232 serial ports, so you'd need an RS-232 to USB converter to make this work. Briefly, the system here is:

GPS reader --> USB-to-serial adaptor --> computer's USB port --> Processing


Added lines 1-19:
! Reading an Existing Serial Protocol

Many applications are best realized NOT by making your own devices, but by using existing hardware.  For example, you could build your own GPS receiver for a couple hundred dollars and a few dozen hours of sweating over a circuit board, or you could buy a cheap one off the shelf. GPS receivers are all supposed to be able to communicate using one of several standard protocols.  To use an off-the-shelf unit in your application, you'd need to program your computer or microcontroller to read whichever protocol your receiver speaks.

There are a few parameters to consider when learning to use an existing serial protocol:
* what are the physical connections, and can you get or make the appropriate connector?
* What are the electrical levels used?  TTL?  RS-232?  RS-485?  Something else? What do you need to match them to your controller?
* Is the protocol ASCII-based or binary?
* Is it a handshaking (call-and-response) protocol, or does the device just send data continually?
* Is the protocol specification available publicly? Has someone else already written an example program for it, to save you time?

This example shows how use Processing to read a GPS receiver that's using the [[http://vancouver-webpages.com/peter/ |NMEA 0183 protocol]]. the principles shown here can be applied generically to many serial protocols.

!! Get the physical and electrical interface right

The GPS receiver used here is a Garmin GPS72, which has an RS-232 serial port.  It also has a simulation mode, in which it sends out "fake" GPS readings that conform to the protocol.  This is useful, since GPs doesn't work indoors, so testing with a receiver that doesn't have a simulation mode would be difficult. You'd have to program outdoors. Furthermore, it shows the readings onscreen, so you can check your serial data against what's onscreen.

Since many laptops nop longer have RS-232 serial ports,

  Edit | View | History | Print | Recent Changes | Search Page last modified on June 01, 2006, at 03:33 PM