<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.element14.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Microstack GPS and Piface Control and Display Geocaching</title><link>https://community.element14.com/products/devtools/technicallibrary/w/documents/17668/microstack-gps-and-piface-control-and-display-geocaching</link><description /><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>Microstack GPS and Piface Control and Display Geocaching</title><link>https://community.element14.com/products/devtools/technicallibrary/w/documents/17668/microstack-gps-and-piface-control-and-display-geocaching</link><pubDate>Tue, 21 Jul 2015 00:26:02 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:137f7623-ea1f-4a94-81ef-33f08a47aa74</guid><dc:creator>Former Member</dc:creator><comments>https://community.element14.com/products/devtools/technicallibrary/w/documents/17668/microstack-gps-and-piface-control-and-display-geocaching#comments</comments><description>Current Revision posted to Documents by Former Member on 7/21/2015 12:26:02 AM&lt;br /&gt;
&lt;h1 id="jive_content_id_Microstack_GPS_and_Raspberry_Pi_Geocaching"&gt;Microstack GPS and Raspberry Pi Geocaching&lt;/h1&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;/p&gt;&lt;div class="toc"&gt;&lt;ul&gt;&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_Microstack_GPS_and_Raspberry_Pi_Geocaching"&gt;Microstack GPS and Raspberry Pi Geocaching&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_Everything_I_am_using"&gt;Everything I am using:&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_The_basic_Idea"&gt;The basic Idea&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_So_the_first_things_first_get_the_Pi_up_and_running"&gt;So the first things first get the Pi up and running&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_The_Plan_for_the_Code"&gt;The Plan for the Code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_The_GPS_Code"&gt;The GPS Code&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_Geocachestxt"&gt;Geocaches.txt&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_microgpspy"&gt;microgps.py&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_1_Import_all_libraries_and_set_up_GPS_"&gt;1. Import all libraries and set up GPS &lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_2_Import_all_the_geocache_locations_into_a_nested_array_so_we_can_reference_them_easily"&gt;2. Import all the geocache locations into a nested array so we can reference them easily&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_3_connect_to_the_GPS_and_get_our_location"&gt;3. connect to the GPS and get our location&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_4_function_to_calculate_distance_from_our_location_to_each_cache"&gt;4. function to calculate distance from our location to each cache&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_6_store_distance_in_gpsdatatxt"&gt;6. store distance in gpsdata.txt&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_7_Set_time_lapse_for_loop"&gt;7. Set time_lapse for loop&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;&lt;ul&gt;&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_8_Append_current_location_to_currentposcsv_keeps_log_of_route_in_csv_format"&gt;8.&amp;nbsp;&amp;nbsp;&amp;nbsp; Append current location to currentpos.csv (keeps log of route in csv format)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_9_Now_put_it_all_together_and_you_get"&gt;9. Now put it all together and you get:&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_Getting_the_Screen_to_work"&gt;Getting the Screen to work&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;&lt;ul&gt;&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_1_Initialise_and_set_up_the_control_and_display"&gt;1. Initialise and set up the control and display&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_2_read_the_distances_file_gpsdatatxt"&gt;2. read the distances file (gpsdata.txt)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_3_display_distance_of_selected_cache"&gt;3. display distance of selected cache&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_4_If_nav_switch_is_being_pressed_or_tweaked_then_change_selected_cache"&gt;4.&amp;nbsp; If nav switch is being pressed or tweaked then change selected cache&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_5_pause_a_bit_to_reduce_flicker_on_screen_from_constant_refresh"&gt;5. pause a bit to reduce flicker on screen from constant refresh&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_Finishing_off_the_python_and_text_files"&gt;Finishing off the python and text files&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a class="jive-link-anchor-small" href="#jive_content_id_Getting_the_GPS_system_to_auto_run_on_boot"&gt;Getting the GPS system to auto run on boot&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;p style="margin:0;"&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;I recently got a &lt;span&gt;&lt;span class="e14-init-shown" id="addProduct-zxYKTj9A-linked" style="white-space:nowrap;"&gt;&lt;a class="jive-link-product-addtolist" href="https://www.element14.com/community/view-product.jspa?fsku=2434228&amp;amp;nsku=&amp;amp;COM=noscript" target="_blank"&gt;&lt;span class="pf-widget-map pf-productlink-cart-icon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a class="jive-link-product pf-embedded-product-link" href="https://www.element14.com/community/view-product.jspa?fsku=2434228&amp;amp;nsku=&amp;amp;COM=noscript" target="_blank"&gt;microstack GPS&lt;/a&gt;&lt;/span&gt;&lt;span class="e14-init-hidden" id="addProduct-zxYKTj9A-unlinked"&gt;microstack GPS&lt;/span&gt;&lt;/span&gt; and &lt;span&gt;&lt;span class="e14-init-shown" id="addProduct-IB6h9MvP-linked" style="white-space:nowrap;"&gt;&lt;a class="jive-link-product-addtolist" href="https://www.element14.com/community/view-product.jspa?fsku=2434227&amp;amp;nsku=&amp;amp;COM=noscript" target="_blank"&gt;&lt;span class="pf-widget-map pf-productlink-cart-icon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a class="jive-link-product pf-embedded-product-link" href="https://www.element14.com/community/view-product.jspa?fsku=2434227&amp;amp;nsku=&amp;amp;COM=noscript" target="_blank"&gt;base board&lt;/a&gt;&lt;/span&gt;&lt;span class="e14-init-hidden" id="addProduct-IB6h9MvP-unlinked"&gt;base board&lt;/span&gt;&lt;/span&gt;, and I was initially struggling to think of a good fun project to do with it u&lt;span style="font-size:10pt;line-height:1.5em;"&gt;ntil I went walking across the tops of my local moors and thought, geocaching would be really cool and far easier to do with a bit of tech helping you out.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:10pt;line-height:1.5em;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:10pt;line-height:1.5em;"&gt;The current problem is that to go geocaching you either need to be good at reading OS maps &lt;/span&gt;accurately&lt;span style="font-size:10pt;line-height:1.5em;"&gt; and have the right map for the area, or have an expensive GPS system, even the cheapest of gps systems cost more than £80.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:10pt;line-height:1.5em;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:10pt;line-height:1.5em;"&gt;Would the raspberry pi and the new Microstack GPS module and a display bring that down to less than £80&lt;/span&gt;&lt;span style="font-size:10pt;line-height:1.5em;"&gt; and then you have the freedom to disassemble it and use it as something else when you&amp;#39;re at home and no geocaching (the other 364 days of the year). &lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 id="jive_content_id_Everything_I_am_using"&gt;Everything I am using:&lt;/h2&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="color:#ff0000;"&gt;&lt;span&gt;&lt;span class="e14-init-shown" id="addProduct-AUW45p2r-linked" style="white-space:nowrap;"&gt;&lt;a class="jive-link-product-addtolist" href="https://www.element14.com/community/view-product.jspa?fsku=2431426&amp;amp;nsku=68X0155&amp;amp;COM=noscript" target="_blank"&gt;&lt;span class="pf-widget-map pf-productlink-cart-icon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a class="jive-link-product pf-embedded-product-link" href="https://www.element14.com/community/view-product.jspa?fsku=2431426&amp;amp;nsku=68X0155&amp;amp;COM=noscript" target="_blank"&gt;Raspberry Pi Module B+&lt;/a&gt;&lt;/span&gt;&lt;span class="e14-init-hidden" id="addProduct-AUW45p2r-unlinked"&gt;Raspberry Pi Module B+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="color:#ff0000;"&gt;&lt;span&gt;&lt;span class="e14-init-shown" id="addProduct-AyjpPnWe-linked" style="white-space:nowrap;"&gt;&lt;a class="jive-link-product-addtolist" href="https://www.element14.com/community/view-product.jspa?fsku=2434227&amp;amp;nsku=78X5850&amp;amp;COM=noscript" target="_blank"&gt;&lt;span class="pf-widget-map pf-productlink-cart-icon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a class="jive-link-product pf-embedded-product-link" href="https://www.element14.com/community/view-product.jspa?fsku=2434227&amp;amp;nsku=78X5850&amp;amp;COM=noscript" target="_blank"&gt;Microstack Baseboard&lt;/a&gt;&lt;/span&gt;&lt;span class="e14-init-hidden" id="addProduct-AyjpPnWe-unlinked"&gt;Microstack Baseboard&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="color:#ff0000;"&gt;&lt;span&gt;&lt;span class="e14-init-shown" id="addProduct-40Vo8cTU-linked" style="white-space:nowrap;"&gt;&lt;a class="jive-link-product-addtolist" href="https://www.element14.com/community/view-product.jspa?fsku=2434228&amp;amp;nsku=78X5851&amp;amp;COM=noscript" target="_blank"&gt;&lt;span class="pf-widget-map pf-productlink-cart-icon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a class="jive-link-product pf-embedded-product-link" href="https://www.element14.com/community/view-product.jspa?fsku=2434228&amp;amp;nsku=78X5851&amp;amp;COM=noscript" target="_blank"&gt;Microstack GPS&lt;/a&gt;&lt;/span&gt;&lt;span class="e14-init-hidden" id="addProduct-40Vo8cTU-unlinked"&gt;Microstack GPS&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="color:#ff0000;"&gt;&lt;span&gt;&lt;span class="e14-init-shown" id="addProduct-WGkyhp7F-linked" style="white-space:nowrap;"&gt;&lt;a class="jive-link-product-addtolist" href="https://www.element14.com/community/view-product.jspa?fsku=2445464&amp;amp;nsku=83X9199&amp;amp;COM=noscript" target="_blank"&gt;&lt;span class="pf-widget-map pf-productlink-cart-icon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a class="jive-link-product pf-embedded-product-link" href="https://www.element14.com/community/view-product.jspa?fsku=2445464&amp;amp;nsku=83X9199&amp;amp;COM=noscript" target="_blank"&gt;Piface I/O SHIM&lt;/a&gt;&lt;/span&gt;&lt;span class="e14-init-hidden" id="addProduct-WGkyhp7F-unlinked"&gt;Piface I/O SHIM&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="color:#ff0000;"&gt;&lt;span&gt;&lt;span class="e14-init-shown" id="addProduct-XKzDU66P-linked" style="white-space:nowrap;"&gt;&lt;a class="jive-link-product-addtolist" href="https://www.element14.com/community/view-product.jspa?fsku=2434231&amp;amp;nsku=78X5848&amp;amp;COM=noscript" target="_blank"&gt;&lt;span class="pf-widget-map pf-productlink-cart-icon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a class="jive-link-product pf-embedded-product-link" href="https://www.element14.com/community/view-product.jspa?fsku=2434231&amp;amp;nsku=78X5848&amp;amp;COM=noscript" target="_blank"&gt;Piface Control and Display&lt;/a&gt;&lt;/span&gt;&lt;span class="e14-init-hidden" id="addProduct-XKzDU66P-unlinked"&gt;Piface Control and Display&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;(if you need to buy a pi then it is cheaper to buy a &lt;span style="color:#ff0000;"&gt;&lt;span&gt;&lt;span class="e14-init-shown" id="addProduct-KsRVxmNH-linked" style="white-space:nowrap;"&gt;&lt;a class="jive-link-product-addtolist" href="https://www.element14.com/community/view-product.jspa?fsku=2254699&amp;amp;nsku=&amp;amp;COM=noscript" target="_blank"&gt;&lt;span class="pf-widget-map pf-productlink-cart-icon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a class="jive-link-product pf-embedded-product-link" href="https://www.element14.com/community/view-product.jspa?fsku=2254699&amp;amp;nsku=&amp;amp;COM=noscript" target="_blank"&gt;Raspberry Pi A&lt;/a&gt;&lt;/span&gt;&lt;span class="e14-init-hidden" id="addProduct-KsRVxmNH-unlinked"&gt;Raspberry Pi A&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&amp;nbsp; for this project (&lt;span style="font-size:10pt;line-height:1.5em;"&gt;fewer USB ports and no ethernet are the main differences)&lt;/span&gt;&lt;span style="font-size:10pt;line-height:1.5em;"&gt; but I only have a B and a B+ so I used my B+.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span&gt;&lt;a href="https://community.element14.com/resized-image/__size/356x295/__key/communityserver-wikis-components-files/00-00-00-01-46/2870.contentimage_5F00_58543.png"&gt;&lt;img alt="image" src="https://community-storage.element14.com/communityserver-components-secureimagefileviewer/communityserver/wikis/components/files/00/00/00/01/46/2870.contentimage_58543.png-356x295.png?sv=2016-05-31&amp;amp;sr=b&amp;amp;sig=mXACdKwAvZfstJBnQ4kKNn05CEr%2BjmgiqMQBJgiWhh4%3D&amp;amp;se=2026-05-08T23%3A59%3A59Z&amp;amp;sp=r&amp;amp;_=KL3u9fSzr+UaQDKFk/Bzbg==" style="max-height: 295px;max-width: 356px;" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Let me set the scene a bit better. In my spare time I am both a scout leader and a cub leader, and when we go to camp we often set up some sort of temporary geocaching route. However where we go we often do not have enough maps for all the teams to have one so we usually do the geocaching using&amp;nbsp; distances and keep the caches fairly close together and give them a compass. However if a group gets lost they have no map and so the leader&amp;nbsp; that is following them has to put them right again. So to get rid of these problems, a GPS system that gives them a distance from their &lt;strong&gt;current&lt;/strong&gt; position, would be great and mean that they couldn&amp;#39;t get lost as it would always give them the directions from their current position.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 id="jive_content_id_The_basic_Idea"&gt;The basic Idea&lt;/h2&gt;&lt;p style="margin:0;"&gt;So my idea for the project is to use the GPS module to get their location, read the list of geocaches on the Pi, choose the nearest cache automatically, then display the distance on the screen.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Simple, in theory.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 id="jive_content_id_So_the_first_things_first_get_the_Pi_up_and_running"&gt;So the first things first get the Pi up and running&lt;/h2&gt;&lt;p style="margin:0;"&gt;I recommend using the Rasbian image as it is very easy to use and has very few problems, &lt;a class="jive-link-external-small" href="http://downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip" rel="nofollow ugc noopener" target="_blank"&gt;Download Raspbian Image&lt;/a&gt;. Once Rasbian is installed, plug in a keyboard, screen, and any other peripherals that you want, also plug the Microstack base board onto the gpio pins of the Pi and then the GPS onto the base board, pretty easy as all the Microstack stuff is colour coded and it&amp;#39;s almost impossible to get it wrong.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;a href="https://lh5.googleusercontent.com/J0jLpHCSQg5HhGJAEc_eA5yYLW6apJK9GYjkhJ91Lm_y7MeUA92Vg6NBaOFAL3sQju8B13kHFeB3l38=w1416-h693-rw"&gt;&lt;img loading="lazy" alt="J0jLpHCSQg5HhGJAEc_eA5yYLW6apJK9GYjkhJ91Lm_y7MeUA92Vg6NBaOFAL3sQju8B13kHFeB3l38=w1416-h693-rw" class="image-2 jive-image" src="https://lh5.googleusercontent.com/J0jLpHCSQg5HhGJAEc_eA5yYLW6apJK9GYjkhJ91Lm_y7MeUA92Vg6NBaOFAL3sQju8B13kHFeB3l38=w1416-h693-rw" style="height:465px;width:620px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Now you need to install all the python libraries for the Microstack add-ons and the GPSpackages. This is very easy as it is in the Rasbian repository and so can be installed using the commands&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sudo apt-get install python3-microstacknode
sudo apt-get install gpsd gpsd-clients python-gps&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h2&gt;&lt;/h2&gt;&lt;h2 id="jive_content_id_The_Plan_for_the_Code"&gt;The Plan for the Code&lt;/h2&gt;&lt;p style="margin:0;"&gt;I hate to develop any code without first having a plan, this allows me to get the entire project sorted in my head and also allows me to do something else and then comeback to the project and still remember all the important points about the project. My actual plan was a scribbled diagram on a piece of paper so I digitised it to make it readable, hopefully this will allow you all to understand what I&amp;#39;m planning on doing.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;CLICK IMAGE TO ZOOM&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span&gt;&lt;a href="https://community.element14.com/resized-image/__size/134x190/__key/communityserver-wikis-components-files/00-00-00-01-46/0726.contentimage_5F00_58545.png"&gt;&lt;img loading="lazy" alt="image" src="https://community-storage.element14.com/communityserver-components-secureimagefileviewer/communityserver/wikis/components/files/00/00/00/01/46/0726.contentimage_58545.png-134x189.png?sv=2016-05-31&amp;amp;sr=b&amp;amp;sig=gN3pxsFYDTUIjbJEyexwLF27M8eBJ92nqcYi5LHzzx8%3D&amp;amp;se=2026-05-08T23%3A59%3A59Z&amp;amp;sp=r&amp;amp;_=dglxkLKuo3MQrKvMBavoTw==" style="max-height: 189px;max-width: 134px;" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;So Basically I am going to have two python files, one to deal with the gps and one to deal with the control and display, this alleviates any lag caused by waiting for the GPS module to reply, therefore giving me6 a faster response&lt;span style="font-size:10pt;line-height:1.5em;"&gt; by the control and display.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 id="jive_content_id_The_GPS_Code"&gt;The GPS Code&lt;/h2&gt;&lt;p style="margin:0;"&gt;Okay so now we have the board setup with both all the hardware and the software we need to start developing the python code.&lt;/p&gt;&lt;p style="margin:0;"&gt;The first bit of code I made was the microgps.py script this needed a geocaches.txt file to reference so lets make that first.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 id="jive_content_id_Geocachestxt"&gt;Geocaches.txt&lt;/h3&gt;&lt;p style="margin:0;"&gt;This contains a longitude and a latitude for all the geocaches that &lt;span style="font-size:10pt;line-height:1.5em;"&gt;we want to use, I went to five decimal places when entering these as that is accurate to about 1m which is about as good as you&amp;#39;ll get out of a civilian gps system (and more accurate than we&amp;#39;ll ever need. For ease I entered it in a csv layout so that when finished I can export an excel spreadsheet of grid references into a csv file and then rename to a txt file then it will work with the python scripts, no retyping needed.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;This is my layout for the geocaches.txt&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;long1,lat1
long2,lat2
long3,lat3&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;"&gt;Notice, no spaces anywhere.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 id="jive_content_id_microgpspy"&gt;microgps.py&lt;/h3&gt;&lt;p style="margin:0;"&gt;This is the main Python script, This will get our location from the Microstack GPS do all the calculations and conversions and output the distance for each geocache ready for displaying.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;So what it needs to do is:&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;strong&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;1.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;Import all the necessary libraries and set up the gps&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;strong&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;2.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;Import all the geocache locations into a nested array so we can reference them easily&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="line-height:1.5em;font-size:10pt;font-family:Arial, sans-serif;"&gt;&lt;em&gt;then it needs to continuously loop:&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;strong&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;3.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;connect to the GPS and get our location&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;strong&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;4.&amp;nbsp;&amp;nbsp;&amp;nbsp; function to &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;calculate distance from our location to each cache&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;&lt;strong&gt;5.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;&lt;strong&gt;recursive loop to calculate distance from our location to each cache&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-weight:bold;line-height:1.5em;font-size:10pt;font-family:Arial, sans-serif;"&gt;6.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-weight:bold;line-height:1.5em;font-size:10pt;font-family:Arial, sans-serif;"&gt;store distance in gpsdata.txt&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;&lt;strong&gt;7.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:Arial, sans-serif;font-size:10pt;font-weight:bold;line-height:1.5em;"&gt;Set time_lapse for loop&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;strong&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;8.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;append current location to currentpos.csv (keeps log of route in csv format)&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-family:Arial, sans-serif;"&gt;&lt;span style="font-size:10pt;"&gt;So we will be going through each of these points &lt;/span&gt;separately then combining them into the whole script.&lt;/span&gt;&lt;/p&gt;&lt;h4 id="jive_content_id_1_Import_all_libraries_and_set_up_GPS_" style="padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;1. Import all libraries and set up GPS &lt;/span&gt;&lt;/h4&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;so we are going to use time to set a pause after each loop, math to help us calculate the distances and the microstack library.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;we also need to set up the gps as an object in the script&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;###import libraries and set up gps
import sys,math,time,microstacknode.gps.l80gps
gps=microstacknode.gps.l80gps.L80GPS()&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;so that&amp;#39;s that.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;h4 id="jive_content_id_2_Import_all_the_geocache_locations_into_a_nested_array_so_we_can_reference_them_easily" style="padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;2. &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;Import all the geocache locations into a nested array so we can reference them easily&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;So now we need to import all of the geocache Coordinates into a nested array so we can access them more easily than having to open read and close a file every time. If we do eventually have a geocache list that is ridiculously long we may have to revert to reading the file every time, line by line but for now lets just have it in an array.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;So these lines of code will open the file read the whole file, split each line into a new element of the array, then split each geocache element into the long and lat elements.Therefore it is nested in two layers the top layer is each geocache the next layer is the long and lat for each cache. so the lat for cache 4 would be indexed as caches[4][1]. The fourth cache, latitude. Easy.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;The print command was just used to check it was working properly feel free to delete or comment it out if you want if you don&amp;#39;t want it to print the complete caches array every time the program starts.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;cachefile=open(&amp;quot;/home/pi/geocaches.txt&amp;quot;,&amp;quot;r&amp;quot;)
caches=cachefile.read().split(&amp;quot;\n&amp;quot;)
for i in range(0,len(caches)):
  caches[i]=caches[i].split(&amp;quot;,&amp;quot;)
print(&amp;quot;caches:&amp;quot;,caches)&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 id="jive_content_id_3_connect_to_the_GPS_and_get_our_location" style="padding-left:30px;"&gt;3. connect to the GPS and get our location&lt;/h4&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-family:Arial, sans-serif;"&gt;Okay so now we have everything set up and ready to go lets start the actual run loop. The first bit is all about connecting to the GPS and getting our location accurately.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;while current_pos==False:
    try:          # try command used to prevent crash when no response from GPS
        current_pos=gps.gpgll          # gets current GPS position
    except (microstacknode.gps.l80gps.DataInvalidError, microstacknode.gps.l80gps.NMEAPacketNotFoundError):          # if no GPS response or if response is invalid
          file=open(&amp;quot;/home/pi/gpsdata.txt&amp;quot;,&amp;quot;w&amp;quot;)              # writes error code to the text file that the display scripts reads from
            file.write(&amp;quot;ERRORSIGNAL&amp;quot;)
            file.close()
            time.sleep(1)                    #pauses before retry to connect to GPS
print(current_pos)                                # for debugging
current_pos=[current_pos[&amp;quot;longitude&amp;quot;],current_pos[&amp;quot;latitude&amp;quot;]]          #extracts long and lat fromdata returned by GPS
print(current_pos[0],current_pos[1])              # for debugging
a=str(current_pos[0])+&amp;quot;, &amp;quot;+str(current_pos[1])+&amp;quot;\n&amp;quot;                    # prepares long and lat for writing to file
file=open(&amp;quot;currentpos.txt&amp;quot;,&amp;quot;a&amp;quot;)                                        # writes current position to file for import as CSV to google map maker engine
file.write(a)
file.close()&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 id="jive_content_id_4_function_to_calculate_distance_from_our_location_to_each_cache" style="padding-left:30px;"&gt;4. function to calculate distance from our location to each cache&lt;/h4&gt;&lt;p style="margin:0;padding-left:30px;"&gt;This was fairly tricky until &lt;span&gt;&lt;a href="/members/dudley.nelson"&gt;Dudley&lt;/a&gt;&lt;/span&gt; sent me a link to this &lt;a class="jive-link-external-small" href="http://williams.best.vwh.net/avform.htm#Dist" rel="nofollow ugc noopener" target="_blank"&gt;webpage&lt;/a&gt;, which was absolutely fantastic. I just adapted the formula for python and entered it as a function at the top of the script just beneath the imports.&lt;/p&gt;&lt;p style="margin:0;padding-left:30px;"&gt;I named the function dist_calc and it accepts the long and lat for both current location and destination then it returns the distance in metres to the destination.&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;def dist_calc(lat1,lon1,lat2,lon2):
    d=math.acos(math.sin(math.radians(lat1))*math.sin(math.radians(lat2))+math.cos(math.radians(lat1))*math.cos(math.radians(lat2))*math.cos(math.radians(lon1-lon2)))    # calculates dist from lon1,lat1 to lon2,lat2 as a fraction of earth&amp;#39;s circumference
    return (d*6373000)                    #returns distance in metres&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding-left:30px;"&gt;As you can see I had to convert all the angles from degrees to radians before using any trig function as python only deals with radians, annoying but no big deal.&lt;/p&gt;&lt;p style="margin:0;padding-left:30px;"&gt;The variable d is the fraction of the circumference of the world of the distance to destination, so you simply times it by the distance round the world in the the units you want to use, I.E. there are 6,373,000 metres (roughly (yes I appreciate that the world is actually an oblate spheroid but this is only roughly) ) around the world, so d*6373000 is the distance in metres.&lt;/p&gt;&lt;p style="margin:0;padding:0px;padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-family:Arial, sans-serif;font-size:13.3333330154419px;font-weight:bold;"&gt;5.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:13.3333330154419px;"&gt;&lt;strong&gt;recursive loop to calculate distance from our location to each cache&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding-left:30px;"&gt;Now we need to put the distance to each cache into a new array ready to be passed to the display python script. To do this we need to create a new list then append to it a two element array containing the distance to each cache, so similar to the caches array but distance instead of long and lat.&lt;/p&gt;&lt;p style="margin:0;padding-left:30px;"&gt;So here&amp;#39;s the code.&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;dist=list()          # makes an empty list
for i in range(0,len(caches)-1):    # loops once per cache
  lon1=float(caches[i][0])          # next four lines prepare the current coords and the destination coords for the calculations
  lon2=current_pos[0]
  lat1=float(caches[i][1])
  lat2=current_pos[1]
  dist.append(str(dist_calc(lat1,lon1,lat2,lon2)))    # appends the distance to the cache to the end of the dist list
  print(dist)                        # used for debugging cache read/dist_calc/dist append errors&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 id="jive_content_id_6_store_distance_in_gpsdatatxt" style="font-size:13.3333339691162px;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;6. &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;store distance in gpsdata.txt&lt;/span&gt;&lt;/h4&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;Now we have the array with the distance to each cache we need to store that in the text file so that the display python script can access it.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;This is very easy.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;data=&amp;quot;&amp;quot;
for i in range(0,len(dist)-1):
    data+=str(i)+&amp;quot;,&amp;quot;+str(dist[i])+&amp;quot;\n&amp;quot;
    file=open(&amp;quot;/home/pi/gpsdata.txt&amp;quot;,&amp;quot;w&amp;quot;)
    file.write(data)
    file.close()&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;&amp;nbsp; Done.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;h4 id="jive_content_id_7_Set_time_lapse_for_loop" style="padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;7. Set time_lapse for loop&lt;/span&gt;&lt;/h4&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;To help reduce power consumption and preserve battery life&amp;nbsp; we are also going to add a time lapse to the main loop to slow down the refresh, but as we get closer to a point we need to speed the refresh up. To do this we are going to find the minimum distance to a cache and base our time lapse off of that. If it is not time to refresh then python will go into a loop that does nothing but checks the time and waits until it is time to refresh.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;    mindist=float(min(dist))
    if mindist==0:None
    elif mindist&amp;lt;30:time_lapse=0.1
    elif mindist&amp;lt;100:time_lapse=2
    elif mindist&amp;gt;=100:time_lapse=5
    end_time=time.time()+time_lapse
    while time.time()&amp;lt;=end_time:None&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h6 id="jive_content_id_8_Append_current_location_to_currentposcsv_keeps_log_of_route_in_csv_format" style="padding-left:30px;"&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;8.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Arial, sans-serif;"&gt;Append current location to currentpos.csv (keeps log of route in csv format)&lt;/span&gt;&lt;/h6&gt;&lt;p style="margin:0;padding-left:30px;"&gt;&lt;span style="font-size:10pt;line-height:1.5em;"&gt;In order to keep a log of our route we are going to put all the gps data we get into a log file which will be a csv file to make it easy to import into a spreadsheet or even straight into google maps as a route. This file will be called currentpos.csv (I know the naming isn&amp;#39;t strictly true to it&amp;#39;s purpose but I started by simply over writing the file each time then changed to appending without changing the file name, bad planning on my part, sorry) but the code is very simple.&lt;/span&gt;&lt;span style="font-size:10pt;line-height:1.5em;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;  a=str(current_pos[0])+&amp;quot;, &amp;quot;+str(current_pos[1])+&amp;quot;\n&amp;quot;
  file=open(&amp;quot;currentpos.csv&amp;quot;,&amp;quot;a&amp;quot;)
  file.write(a)
  file.close()&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding-left:30px;"&gt;This code simply prepares var &amp;quot;a&amp;quot; which contains the long and lat in a csv friendly format. Then apppends it to a new line in currentpos.csv. Thereby recording your route as you walk it.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 id="jive_content_id_9_Now_put_it_all_together_and_you_get" style="padding-left:30px;"&gt;9. Now put it all together and you get:&lt;/h4&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;import sys, math, time
import microstacknode.gps.l80gps
#import pifacecad
gps=microstacknode.gps.l80gps.L80GPS()


def dist_calc(lat1,lon1,lat2,lon2):
    d=math.acos(math.sin(math.radians(lat1))*math.sin(math.radians(lat2))+math.cos(math.radians(lat1))*math.cos(math.radians(lat2))*math.cos(math.radians(lon1-lon2)))
    return (d*6373000)




cachefile=open(&amp;quot;/home/pi/geocaches.txt&amp;quot;,&amp;quot;r&amp;quot;)
caches=cachefile.read().split(&amp;quot;\n&amp;quot;)
#cad=pifacecad.PiFaceCAD()
#cad.lcd.backlight_on()
#cad.lcd.cursor_off()
#cad.lcd.blink_off()
for i in range(0,len(caches)):
  caches[i]=caches[i].split(&amp;quot;,&amp;quot;)
print(&amp;quot;caches:&amp;quot;,caches)
start_time=time.time()
time_lapse=15


a=1
while a:
  current_pos=False
  while current_pos==False:
  try:
  current_pos=gps.gpgll
  except (microstacknode.gps.l80gps.DataInvalidError, microstacknode.gps.l80gps.NMEAPacketNotFoundError):
  file=open(&amp;quot;/home/pi/gpsdata.txt&amp;quot;,&amp;quot;w&amp;quot;)
  file.write(&amp;quot;ERRORSIGNAL&amp;quot;)
  file.close()
  time.sleep(1)
  print(current_pos)
  current_pos=[current_pos[&amp;quot;longitude&amp;quot;],current_pos[&amp;quot;latitude&amp;quot;]]
  print(current_pos[0],current_pos[1])
  a=str(current_pos[0])+&amp;quot;, &amp;quot;+str(current_pos[1])+&amp;quot;\n&amp;quot;
  file=open(&amp;quot;currentpos.csv&amp;quot;,&amp;quot;a&amp;quot;)
  file.write(a)
  file.close()

  lon2=current_pos[0]
  lon1=float(caches[0][0])
  lat2=current_pos[1]
  lat1=float(caches[0][1])
  dist=list()
  print(dist)


  for i in range(0,len(caches)-1):
  lon1=float(caches[i][0])
  lon2=current_pos[0]
  lat1=float(caches[i][1])
  lat2=current_pos[1]
  dist.append(str(dist_calc(lat1,lon1,lat2,lon2)))
  print(dist)

  data=&amp;quot;&amp;quot;
  for i in range(0,len(dist)-1):
  data+=str(i)+&amp;quot;,&amp;quot;+str(dist[i])+&amp;quot;\n&amp;quot;
  file=open(&amp;quot;/home/pi/gpsdata.txt&amp;quot;,&amp;quot;w&amp;quot;)
  file.write(data)
  file.close()
  mindist=float(min(dist))
  #if mindist==0:None
  #elif mindist&amp;lt;30:time_lapse=0.1
  #elif mindist&amp;lt;100:time_lapse=2
  #elif mindist&amp;gt;=100:time_lapse=5
  end_time=time.time()+time_lapse
  while time.time()&amp;lt;=end_time:None&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:14pt;"&gt;PHEW! Half way there,&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Now to get the screen working.....&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 id="jive_content_id_Getting_the_Screen_to_work"&gt;Getting the Screen to work&lt;/h2&gt;&lt;p style="margin:0;"&gt;Okay, so for the Piface Control and Display we are going to have a different python script running parallel to the GPS python script so that the display doesn&amp;#39;t suffer from any lag caused by the GPS. So we are going to call it geodisp.py.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;This script is going to:&lt;/p&gt;&lt;p style="margin:0;"&gt;1. initialise and set up the control and display&lt;/p&gt;&lt;p style="margin:0;"&gt;Loop&lt;/p&gt;&lt;p style="margin:0;"&gt;2. read the distances file (gpsdata.txt)&lt;/p&gt;&lt;p style="margin:0;"&gt;3. display distance and heading of selected cache&lt;/p&gt;&lt;p style="margin:0;"&gt;4. if nav switch is being pressed or tweaked then change selected cache&lt;/p&gt;&lt;p style="margin:0;"&gt;5. pause a bit to reduce flicker on screen from constant refresh&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;This script is actually a lot shorter than the geodisp.py script. So lets start&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 id="jive_content_id_1_Initialise_and_set_up_the_control_and_display"&gt;1. Initialise and set up the control and display&lt;/h4&gt;&lt;p style="margin:0;"&gt;Okay so here we are going to import the modules we need and set up the piface control and display screen in preparation for displaying the data, and also setting up initial variables.&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;time.sleep(3)          #Allows the gps script to go through boot and get into main loop before this script starts.
import pifacecad
cad=pifacecad.PiFaceCAD()
cad.lcd.backlight_on()
cad.lcd.cursor_off()
cad.lcd.blink_off()
selection=0          #selection var is the variable we will use as the index of the cache we are display on the CaD&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 id="jive_content_id_2_read_the_distances_file_gpsdatatxt" style="font-size:13.3333339691162px;"&gt;2&lt;span style="font-size:13.3333339691162px;"&gt;. read the distances file (gpsdata.txt)&lt;/span&gt;&lt;/h4&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:13.3333339691162px;"&gt;Here we are going to read the gpsdata.txt file into a nested list (YAY! nested lists!).&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:13.3333339691162px;"&gt;Okay so first read the data into a variable then split each line into an element then split each element into the &lt;/span&gt;separate&lt;span style="font-size:13.3333339691162px;"&gt; values.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;while True:              #this is the main run loop
  file=open(&amp;quot;/home/pi/gpsdata.txt&amp;quot;,&amp;quot;r&amp;quot;)    #next 3 lines open and read the data file
  data=file.read()
  file.close()
  if data==&amp;quot;ERRORSIGNAL&amp;quot;:              #if the data file contains the error code for no signal then write error message on CaD
      cad.lcd.home()
      cad.lcd.write(&amp;quot;Error: NO SIGNAL\nNEED VIEW OF SKY&amp;quot;)
  else:
      data=data.split(&amp;quot;\n&amp;quot;)            # if there is no error message in the data file then split the variable at each new line
      for i in range(0,len(data)):          # for each element in the list
            data[i]=data[i].split(&amp;quot;,&amp;quot;)      # Split each element into the ID,distance, (split at each comma)
      dist=list()                          # make a new empty list
      for i in range(0,len(data)-1):        # loop for the number of elements in the data list (the number of caches)
            dist.append(float(data[i][1]))  # adds the distance of each cache to dist&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 id="jive_content_id_3_display_distance_of_selected_cache"&gt;&lt;span style="font-size:13.3333339691162px;"&gt;3. display distance of selected cache&lt;/span&gt;&lt;/h4&gt;&lt;p style="margin:0;"&gt;This is going to display all the information for the currently selected cache on the control and display&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;cad.lcd.home()              #resets the cursor position on the CaD to the first character on the top line
  cad.lcd.write(&amp;quot;ID: &amp;quot;+str(data[selection][0])+str(selection)+&amp;quot;\nDist: &amp;quot;+str(data[selection][1]))          #write the cache&amp;#39;s id number, distance to cache onto the screen&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;"&gt;Wow, that was easy!&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 id="jive_content_id_4_If_nav_switch_is_being_pressed_or_tweaked_then_change_selected_cache"&gt;&lt;span style="font-size:13.3333339691162px;"&gt;4.&amp;nbsp; If nav switch is being pressed or tweaked then change selected cache&lt;/span&gt;&lt;/h4&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:13.3333339691162px;"&gt;This will allow the user to change the selected cache to a different one, for example if they have just completed one then their closest cache will be the one they are at, but they want to know where the next one is. So they can use the nav button to change the selected cache.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;if cad.switches[7].value and selection!=len(dist)-1:                                        # if the nav switch is being tweaked right and the selected cache is not the highest ID then:
    selection+=1                                            #increase the selection ID for which cache to display by 1
    while cad.switches[5].value or cad.switches[6].value or cad.switches[7].value: None    # if the nav switch is being pressed or tweaked at all then wait until it is not
elif cad.switches[6].value and selection&amp;gt;0:                                                  # if the nav switch is being tweaked left and the selected cache is not the lowest ID (0) then:
    selection-=1                                            # decrease the selection ID for which cache to display by 1
    while cad.switches[5].value or cad.switches[6].value or cad.switches[7].value: None    # is the nav switch is being pressed or tweaked at all then wait until it is not
elif cad.switches[5].value and selection!=dist.index(min(dist)):                            # if the nav switch is being pressed  and the currently selected cache is not the closest one then:
    selection=dist.index(min(dist))                          # set the selected cache to the closest cache
    while cad.switches[5].value or cad.switches[6].value or cad.switches[7].value: None    # if the nav switch is being pressed or tweaked at all then wait until it is not&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 id="jive_content_id_5_pause_a_bit_to_reduce_flicker_on_screen_from_constant_refresh"&gt;&lt;span style="font-size:13.3333339691162px;"&gt;5. pause a bit to reduce flicker on screen from constant refresh&lt;/span&gt;&lt;/h4&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:13.3333339691162px;"&gt;This is DEFINITELY the hardest bit of the whole project.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-size:13.3333339691162px;"&gt;Here goes.....&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;time.sleep(0.2)&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;"&gt;This just slows the refresh of the CAD module down so that the screen doesn&amp;#39;t constantly flicker due to it refreshing so quickly.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Okay so now to put everything together. Simply stick it all together in the order above, like so....&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;import sys,time,math
import pifacecad
time.sleep(3)
cad=pifacecad.PiFaceCAD()
cad.lcd.backlight_on()
cad.lcd.cursor_off()
cad.lcd.blink_off()
selection=0
while True:
  file=open(&amp;quot;/home/pi/gpsdata.txt&amp;quot;,&amp;quot;r&amp;quot;)
  data=file.read()
  file.close()
  if data==&amp;quot;ERRORSIGNAL&amp;quot;:
    cad.lcd.home()
    cad.lcd.write(&amp;quot;Error: NO SIGNAL\nNEED VIEW OF SKY&amp;quot;)
  else:
    data=data.split(&amp;quot;\n&amp;quot;)
    for i in range(0,len(data)):
      data[i]=data[i].split(&amp;quot;,&amp;quot;)
      dist=list()
    for i in range(0,len(data)-1):
      dist.append(float(data[i][1]))
    cad.lcd.home()
    cad.lcd.write(&amp;quot;ID: &amp;quot;+str(data[selection][0])+str(selection)+&amp;quot;\nDist: &amp;quot;+str(data[selection][1]))
  if cad.switches[7].value and selection!=len(dist)-1:
    selection+=1
    while cad.switches[5].value or cad.switches[6].value or cad.switches[7].value: None
  elif cad.switches[6].value and selection&amp;gt;0:
    selection-=1
    while cad.switches[5].value or cad.switches[6].value or cad.switches[7].value: None
  elif cad.switches[5].value and selection!=dist.index(min(dist)):
    selection=dist.index(min(dist))
    while cad.switches[5].value or cad.switches[6].value or cad.switches[7].value: None
  elif cad.switches[5].value and dist[selection]&amp;lt;=0:
    #caches=caches.pop(dist.index(min(dist)))
    while cad.switches[5].value or cad.switches[6].value or cad.switches[7].value: None
  time.sleep(0.1)&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 id="jive_content_id_Finishing_off_the_python_and_text_files"&gt;Finishing off the python and text files&lt;/h2&gt;&lt;p style="margin:0;"&gt;Okay so now you need to make sure all of your geocache scripts and files are nice and organised in one place as moving them will be awkward later.&lt;/p&gt;&lt;p style="margin:0;"&gt;You will also need to create the other two files that the data is going to be written in as it may cause errors if these files do not exist when the scripts try to read them&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;I have all my geocache files in a folder called microstack_geocache in my home directory to do this simply go to the place where your files currently are and then type into the terminal&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sudo mkdir ~/microstack_geocache

sudo cp geodisp.py ~/microstack_geocache/
sudo cp  microgps.py ~/microstack_geocache/
sudo cp geocaches.txt ~/microstack_geocache/

sudo vi ~/microstack_geocache/gpsdata.txt&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;"&gt;Then press Esc+shift+; to bring up the vi control at the bottom of the screen then type &amp;quot;wq&amp;quot; and press enter to save and quit&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sudo vi ~/microstack_geocache/currentpos.csv&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;"&gt;Then press Esc+shift+; then &amp;quot;wq&amp;quot; then enter to save and quit&lt;/p&gt;&lt;p style="margin:0;"&gt;You should now have 5 files in ~/microstack_geocache ; 2 python scripts and 3 text files.&lt;/p&gt;&lt;p style="margin:0;"&gt;it may also be worth giving full access to the text files just in case they are limited access at the moment, to do this type in the terminal:&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sudo chmod 777 ~/microstack_geocaches/*.txt&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;"&gt;this will give everyone full access to any text file in ~/microstack_geocaches/&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Okay so that&amp;#39;s all the python scripts and text files sorted. Now let&amp;#39;s talk about the Linux and Raspberry Pi side of things.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 id="jive_content_id_Getting_the_GPS_system_to_auto_run_on_boot"&gt;Getting the GPS system to auto run on boot&lt;/h2&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;This is fairly easy and only involves one file of four lines and three lines of code in the terminal.&lt;/p&gt;&lt;p style="margin:0;"&gt;The general idea is to write an executable file that will run at start and set the two python scripts running.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;So first lets write the executable file.&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sudo vi /etc/init.d/start.sh&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;"&gt;will create a new file in the init.d directory or open the start.sh script if you have one already (I always use start.sh so I almost always already have one)&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;in this file you will need three lines of code&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#!/bin.bash
python3 ~/microstack_geocache/microgps.py &amp;amp;  #this will run the python script in the background, change the file reference if you script is not saved in ~/microstack_geocache/
python3 ~/microstack_geocache/geodisp.py &amp;amp;  #this will also run in the background , REMEMBER to change the file reference if you need to&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;"&gt;no press Esc+chist+; and type &amp;quot;wq&amp;quot; enter to save and quit&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;now we need to tell the Pi to run this start script on boot, if you have already done this then you do not need to go through this process again, but it won&amp;#39;t do any harm if you are unsure.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;In the terminal type:&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sudo chmod +x /etc/init.d/start.sh
sudo update-rc.d start.sh defaults 99&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;"&gt;This will make the start.sh script executable and then tells the Pi to run it on boot.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Simple.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Now make sure everything is plugged in correctly&amp;nbsp; and powered properly, then reboot your board to (hopefully) start your geocaching.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: rpiintermediate, geocaching, raspi, How To, pi_geocaching, raspberry-pi, gps, microstack&lt;/div&gt;
</description></item></channel></rss>