{"id":262,"date":"2007-01-31T09:04:44","date_gmt":"2007-01-31T09:04:44","guid":{"rendered":"http:\/\/beta.robertprice.co.uk\/robblog\/2007\/01\/using_a_bluetooth_gps_from_python-shtml\/"},"modified":"2007-01-31T09:04:44","modified_gmt":"2007-01-31T09:04:44","slug":"using_a_bluetooth_gps_from_python-shtml","status":"publish","type":"post","link":"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/","title":{"rendered":"Using A Bluetooth GPS From Python"},"content":{"rendered":"<p>\nFollowing on from my earlier posting on <a href=\"\/robblog\/archive\/2007\/1\/Programming_Bluetooth_Using_Python.shtml\">programming bluetooth from Python<\/a>, I tried talking to a bluetooth <acronym title=\"Global Positioning System\">GPS<\/acronym> unit from <a href=\"http:\/\/www.python.org\/\">Python<\/a>.\n<\/p>\n<p>\nI have a cheap <a href=\"http:\/\/www.msi.com.tw\/program\/products\/communication\/cmu\/pro_cmu_detail.php?UID=623\">MSI Starfinder SF100<\/a> bluetooth GPS that transmits <acronym title=\"National Marine Electronics Association\">NMEA<\/acronym> format positioning information over a bluetooth socket. So, the first thing we have to do is to is to open a bluetooth socket.\n<\/p>\n<div class=\"code\"><code>import bluetooth<br \/>\n# bluetooth address of the GPS device.<br \/>\naddr = \"00:08:1B:C2:AA:6D\"<br \/>\n# port to use.<br \/>\nport = 1<br \/>\n# create a socket and connect to it.<br \/>\nsocket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)<br \/>\nsocket.connect((addr, port))<br \/>\n<\/code><\/div>\n<p>\nFingers crossed we should now be connected to the GPS unit. In the real world we&#8217;d also be checking for exceptions to make sure we really have been able to connect, but this is just a simplified example.\n<\/p>\n<p>\nNow we need to receive data from the GPS.\n<\/p>\n<div class=\"code\"><code>data = \"\"<br \/>\nwhile True:<br \/>\ndata = socket.recv(1024)<br \/>\n<\/code><\/div>\n<p>\nHere we&#8217;re initialising a holding variable called data where the received data from the bluetooth socket goes, then we create an infinate loop and continually receive data from the bluetooth socket we creataed earlier.\n<\/p>\n<p>\nWe should now have some data coming in, so to test it we can just print it out.\n<\/p>\n<div class=\"code\"><code>  print data<br \/>\n<\/code><\/div>\n<p>\nHere&#8217;s what we get back.\n<\/p>\n<div class=\"code\">\n<pre>$GPRMC,225406.537,A,5046.3972,N,00017.\n3365,E,0.00,,300107,,,A*7E\n$GPGGA,225407.537,5046.3972,N,00017.3365,E,1,05,1.7,55.5,\nM,,,,0000*33\n$GPGSA,A,3,27,10,29,28,08,,,,,,,,3.9,1.7,3.5*35\n$GPRMC,225407.537,A,5046.3972,N,00017.3365,E,0.00,,300107,,,A*7F\n$GPGGA,225408.537,5046.3972,N,00017.3365,E,1,05,1.7,55.5,M,,,,0000*3C\n$GPGSA,A,3,27,1\n0,2\n9,28,08,,,,,,,,3.9,1.7,3.5*35\n$GPGSV,2,1,08,10,70,218,31,08,64,067\n,35,29,49,287,30,27,37,058,40*70\n$GPGSV,2,2,08,26,35,283,,28,34,133,45,24,27,254,22,21,12,324,*72\n$GPRMC,225408.537,A,5046.3972,N,00017.3365,E,0.00,,300107,,,A*70\n$GPGGA,225409.537,5046.3972,N,00017.3365,E,1,06,1.4,55.5,M,,,\n,0000*3D\n<\/pre>\n<\/div>\n<p>\nOh dear, although we are receiving data over the bluetooth socket, it&#8217;s in random packet sizes. The NMEA data we want is sent in lines terminated with a carriage return and a line feed. So how can we get the data in this format?\n<\/p>\n<p>\nWell we need to use Python&#8217;s string manipulation methods. We can use the <code>splitlines<\/code> method to split the data into a list of lines. As we can&#8217;t be sure we have a complete line at the end of the list we need to check there is a carriage return and linefeed there. By default <code>splitlines<\/code> helpfully removes these, so we need to tell it to keep them in place, after all we can use the <code>strip<\/code> method later to remove them manually. So all we need to do now is to check the last line in the list has the carriage return and linefeed, if it doesn&#8217;t we need to make sure the next <var>data<\/var> received from the bluetooth socket is appended to the end before we repeat the process again. Imagine we create a holding variable called <var>olddata<\/var> at the same time as <var>data<\/var> and this is to hold a copy of the last line. Here&#8217;s the code&#8230;\n<\/p>\n<div class=\"code\"><code>  # make sure we actually have some data.<br \/>\nif len(data) > 0:<br \/>\n# append the old data to the front of data.<br \/>\ndata = olddata + data<br \/>\n# split the data into a list of lines, but make<br \/>\n# sure we preserve the end of line information.<br \/>\nlines = data.splitlines(1)<br \/>\n# iterate over each line<br \/>\nfor line in lines:<br \/>\n# if the line has a carriage return and a<br \/>\n# linefeed, we know we have a complete line so<br \/>\n# we can remove those characters and print it.<br \/>\nif line.find(\"rn\") != -1 :<br \/>\nline = line.strip()<br \/>\nprint line<br \/>\n# empty the olddata variable now we have<br \/>\n# used the data.<br \/>\nolddata = \"\"<br \/>\n# else we need to keep the line to add to data<br \/>\nelse :<br \/>\nolddata = line<br \/>\n<\/code><\/div>\n<p>\nWe now have some useful data coming in&#8230;\n<\/p>\n<div class=\"code\">\n<pre>$GPRMC,225406.537,A,5046.3972,N,00017.3365,E,0.00,,300107,,,A*7E\n$GPGGA,225407.537,5046.3972,N,00017.3365,E,1,05,1.7,55.5,M,,,,0000*33\n$GPGSA,A,3,27,10,29,28,08,,,,,,,,3.9,1.7,3.5*35\n$GPRMC,225407.537,A,5046.3972,N,00017.3365,E,0.00,,300107,,,A*7F\n$GPGGA,225408.537,5046.3972,N,00017.3365,E,1,05,1.7,55.5,M,,,,0000*3C\n$GPGSA,A,3,27,10,29,28,08,,,,,,,,3.9,1.7,3.5*35\n$GPGSV,2,1,08,10,70,218,31,08,64,067,35,29,49,287,30,27,37,058,40*70\n$GPGSV,2,2,08,26,35,283,,28,34,133,45,24,27,254,22,21,12,324,*72\n$GPRMC,225408.537,A,5046.3972,N,00017.3365,E,0.00,,300107,,,A*70\n$GPGGA,225409.537,5046.3972,N,00017.3365,E,1,06,1.4,55.5,M,,,,0000*3D\n<\/pre>\n<\/div>\n<p>\nAs you can see the NMEA strings are simply comma seperated blocks of data.\n<\/p>\n<p>\nThe most useful string is the one with the actual position in. This string is the one starting with <code>$GPRMC<\/code>. If we look out for this line and split it&#8217;s data, we can get our latitude and longitude and use it as we please.\n<\/p>\n<div class=\"code\"><code>gpsstring = line.split(',')<br \/>\nif gpsstring[0] == '$GPRMC' :<br \/>\nprint \"Lat:  \" + gpsstring[3] + gpsstring[4]<br \/>\nprint \"Long: \" + gpsstring[5] + gpsstring[5]<br \/>\n<\/code><\/div>\n<p>\nThis gives us&#8230;\n<\/p>\n<div class=\"code\">\n<pre>Lat:  5046.3972N\nLong: 000017.3365\n<\/pre>\n<\/div>\n<p>\nWhich translates to 50 deg 46.3972&#8242; N and 0 deg 17.3365 E.\n<\/p>\n<p>\nThere you have it, it&#8217;s time to start geocoding you data.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Following on from my earlier posting on programming bluetooth from Python, I tried talking to a bluetooth GPS unit from Python. I have a cheap MSI Starfinder SF100 bluetooth GPS that transmits NMEA format positioning information over a bluetooth socket. So, the first thing we have to do is to is to open a bluetooth &hellip; <a href=\"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Using A Bluetooth GPS From Python&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[2],"tags":[17,53],"class_list":["post-262","post","type-post","status-publish","format-standard","hentry","category-dev","tag-dev","tag-python"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Using A Bluetooth GPS From Python - Robert Price<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using A Bluetooth GPS From Python - Robert Price\" \/>\n<meta property=\"og:description\" content=\"Following on from my earlier posting on programming bluetooth from Python, I tried talking to a bluetooth GPS unit from Python. I have a cheap MSI Starfinder SF100 bluetooth GPS that transmits NMEA format positioning information over a bluetooth socket. So, the first thing we have to do is to is to open a bluetooth &hellip; Continue reading &quot;Using A Bluetooth GPS From Python&quot;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/\" \/>\n<meta property=\"og:site_name\" content=\"Robert Price\" \/>\n<meta property=\"article:published_time\" content=\"2007-01-31T09:04:44+00:00\" \/>\n<meta name=\"author\" content=\"rob\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"rob\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/using_a_bluetooth_gps_from_python-shtml\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/using_a_bluetooth_gps_from_python-shtml\\\/\"},\"author\":{\"name\":\"rob\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#\\\/schema\\\/person\\\/fac6d5b076e0e14e1fb13e15b542a6c5\"},\"headline\":\"Using A Bluetooth GPS From Python\",\"datePublished\":\"2007-01-31T09:04:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/using_a_bluetooth_gps_from_python-shtml\\\/\"},\"wordCount\":463,\"keywords\":[\"Dev\",\"Python\"],\"articleSection\":[\"Dev\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/using_a_bluetooth_gps_from_python-shtml\\\/\",\"url\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/using_a_bluetooth_gps_from_python-shtml\\\/\",\"name\":\"Using A Bluetooth GPS From Python - Robert Price\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#website\"},\"datePublished\":\"2007-01-31T09:04:44+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#\\\/schema\\\/person\\\/fac6d5b076e0e14e1fb13e15b542a6c5\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/using_a_bluetooth_gps_from_python-shtml\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/using_a_bluetooth_gps_from_python-shtml\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/using_a_bluetooth_gps_from_python-shtml\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using A Bluetooth GPS From Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#website\",\"url\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/\",\"name\":\"Robert Price\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#\\\/schema\\\/person\\\/fac6d5b076e0e14e1fb13e15b542a6c5\",\"name\":\"rob\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g\",\"caption\":\"rob\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using A Bluetooth GPS From Python - Robert Price","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/","og_locale":"en_GB","og_type":"article","og_title":"Using A Bluetooth GPS From Python - Robert Price","og_description":"Following on from my earlier posting on programming bluetooth from Python, I tried talking to a bluetooth GPS unit from Python. I have a cheap MSI Starfinder SF100 bluetooth GPS that transmits NMEA format positioning information over a bluetooth socket. So, the first thing we have to do is to is to open a bluetooth &hellip; Continue reading \"Using A Bluetooth GPS From Python\"","og_url":"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/","og_site_name":"Robert Price","article_published_time":"2007-01-31T09:04:44+00:00","author":"rob","twitter_card":"summary_large_image","twitter_misc":{"Written by":"rob","Estimated reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/#article","isPartOf":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/"},"author":{"name":"rob","@id":"https:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5"},"headline":"Using A Bluetooth GPS From Python","datePublished":"2007-01-31T09:04:44+00:00","mainEntityOfPage":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/"},"wordCount":463,"keywords":["Dev","Python"],"articleSection":["Dev"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/","url":"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/","name":"Using A Bluetooth GPS From Python - Robert Price","isPartOf":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/#website"},"datePublished":"2007-01-31T09:04:44+00:00","author":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5"},"breadcrumb":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.robertprice.co.uk\/robblog\/using_a_bluetooth_gps_from_python-shtml\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.robertprice.co.uk\/robblog\/"},{"@type":"ListItem","position":2,"name":"Using A Bluetooth GPS From Python"}]},{"@type":"WebSite","@id":"https:\/\/www.robertprice.co.uk\/robblog\/#website","url":"https:\/\/www.robertprice.co.uk\/robblog\/","name":"Robert Price","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.robertprice.co.uk\/robblog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Person","@id":"https:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5","name":"rob","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g","caption":"rob"}}]}},"_links":{"self":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts\/262","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/comments?post=262"}],"version-history":[{"count":0,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts\/262\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/media?parent=262"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/categories?post=262"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/tags?post=262"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}