{"id":127,"date":"2007-11-20T11:13:27","date_gmt":"2007-11-20T16:13:27","guid":{"rendered":"http:\/\/www.tigoe.net\/pcomp\/code\/category\/code\/processing\/127"},"modified":"2008-01-15T21:33:19","modified_gmt":"2008-01-16T02:33:19","slug":"xor-calculation-for-nmea-checksums-gps-protocol","status":"publish","type":"post","link":"https:\/\/www.tigoe.com\/pcomp\/code\/Processing\/127\/","title":{"rendered":"XOR calculation for NMEA checksums (GPS protocol)"},"content":{"rendered":"<p>If you&#8217;ve ever seen the serial output of a GPS reader, you&#8217;ve seen a mystery string at the end like this:<\/p>\n<p>That&#8217;s the checksum of the whole string.   NMEA data structure for Global Positioning (GPS) readers has a checksum on the end of each sentence. The checksum is the XOR of all the bytes between the $ and the * in the sentence.  For example, if the sentence is this:<\/p>\n<pre>$GPRMC,155123.000,A,4043.8432,N,07359.7653,W,0.15,83.25,200407,,*28\n<\/pre>\n<p>then you run a checksum on this:<\/p>\n<pre>GPRMC,155123.000,A,4043.8432,N,07359.7653,W,0.15,83.25,200407,,\n<\/pre>\n<p>Here&#8217;s a Processing method to calculate the checksum, given the string between the $ and the *:<\/p>\n<p><!-- technorati tags start --><\/p>\n<p style=\"text-align:right;font-size:10px;\">Technorati Tags: <a href=\"http:\/\/www.technorati.com\/tag\/GPS\" rel=\"tag\">GPS<\/a>, <a href=\"http:\/\/www.technorati.com\/tag\/NMEA\" rel=\"tag\">NMEA<\/a><\/p>\n<p><!-- technorati tags end --><br \/>\n<!--more--><\/p>\n<pre>char checkSum(String theseChars) {\n  char check = 0;\n  \/\/ iterate over the string, XOR each byte with the total sum:\n  for (int c = 0; c &lt; theseChars.length(); c++) {\n    check = char(check ^ theseChars.charAt(c));\n  } \n  \/\/ return the result\n  return check;\n}\n<\/pre>\n<p>And here&#8217;s a whole program to use the checksum with an Etek EB-85A reader:<\/p>\n<pre>\/*\n  ETEK EB-85A GPS reader test.\n \n This program reads NMEA data in from a GPS reader at 4800 bps.\n The ETEK EB-85A reader has a proprietary command protocol that\n requires the calculation of the checksum of each command you send.  \n The checksum is the XOR of all the bytes between the $ \n and the * in the command string. The checkSum() routine\n does that calculation.\n\n created 20 Nov. 2007\n by Tom Igoe and Kristin O'Friel\n \n *\/\n\nimport processing.serial.*;\n\nSerial myPort;\n\nvoid setup(){\n  \/\/ get the serial list:\n  String[] thisPort = Serial.list();\n  println(thisPort);\n  \/\/ open the port:\n  myPort = new Serial(this,thisPort[0] , 4800);  \n}\n\nvoid draw() {\n\n}\n\nvoid keyReleased() {\n  \/\/ command to turn on WAAS:\n  String cmd = \"PMTK501,2\";\n  \/\/ turn off all byt the RMC sentence:\n  \/\/ String cmd = \"PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\";\n  \/\/ cold reset:\n  \/\/String cmd = \"PMTK104\";\n  \/\/ test packet:\n  \/\/String cmd = \"PMTK000\";\n  \/\/ calculate the checksum, convert it to a 2-byte hex string:\n  String checkSum = hex(checkSum(cmd),2);\n  \/\/ add the $, the *, the checksum, the CR and LF:\n  cmd = \"$\" + cmd + \"*\" + checkSum + \"&#38;#92;r&#38;#92;n\";\n  \/\/ print it for debugging:\n  println(\"&#38;#92;r&#38;#92;n&#38;#92;r&#38;#92;n\");\n  println(cmd);\n  println(\"&#38;#92;r&#38;#92;n&#38;#92;r&#38;#92;n\");\n  \/\/ send it out the serial port:\n  myPort.write(cmd);\n}\n\/\/ print anything that comes in the serial port:\nvoid serialEvent(Serial myPort) {\n  char inByte = char(myPort.read());\n  print (inByte);\n}\n\n\/\/ calculate the checksum:\nchar checkSum(String theseChars) {\n  char check = 0;\n  \/\/ iterate over the string, XOR each byte with the total sum:\n  for (int c = 0; c &lt; theseChars.length(); c++) {\n    check = char(check ^ theseChars.charAt(c));\n  } \n  \/\/ return the result\n  return check;\n}\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>IF you&#8217;ve ever seen the serial output of a GPS reader, you&#8217;ve seen a mystery string at the end like this:That&#8217;s the checksum of the whole string&#8230;.  For example, if the sentence is this:LKLKJLKJLthen you run a checksum on this:KLKJLKJLKHere&#8217;s a Processing method to calculate the checksum, given the string between the $ and the *:char checkSum(String theseChars) { char check = 0; \/\/ iterate over the string, XOR each byte with the total sum: for (int c = 0; c &lt; theseChars.length(); c++) { check = char(check ^ theseChars.charAt(c)); } \/\/ return the result return check;}And here&#8217;s a whole program to use the checksum with an Etek EB-85A reader:\/* ETEK EB-85A GPS reader test.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-127","post","type-post","status-publish","format-standard","hentry","category-Processing"],"_links":{"self":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/127","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/comments?post=127"}],"version-history":[{"count":0,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/127\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/media?parent=127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/categories?post=127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/tags?post=127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}