{"id":1891,"date":"2015-11-19T15:07:31","date_gmt":"2015-11-19T15:07:31","guid":{"rendered":"http:\/\/www.daveakerman.com\/?p=1891"},"modified":"2015-11-19T15:25:25","modified_gmt":"2015-11-19T15:25:25","slug":"astro-pi-flight-update","status":"publish","type":"post","link":"http:\/\/www.daveakerman.com\/?p=1891","title":{"rendered":"Astro Pi Flight &#8211; Update"},"content":{"rendered":"<p>I&#8217;ve made some progress on my &#8220;<a href=\"http:\/\/www.daveakerman.com\/?p=1876\">tweet uplink<\/a>&#8221; software, and now all stages in the process are fully automated except for a required manual approval step, in case anyone tries to spam the flight!<\/p>\n<p>The key new element is a Windows program that lists incoming tweets and offers Accept\u00a0and Reject options for each tweet that mentions a particular hashtag, for example:<\/p>\n<p><a href=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/tweet.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1894\" src=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/tweet.png\" alt=\"tweet\" width=\"584\" height=\"102\" srcset=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/tweet.png 584w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/tweet-300x52.png 300w\" sizes=\"(max-width: 584px) 100vw, 584px\" \/><\/a><\/p>\n<p>The tweets are received via a simple Python script using the tweepy library, which saves each as a separate file which the Windows program then sees and displays:<\/p>\n<p><a href=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/incoming.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-1892\" src=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/incoming-1024x223.png\" alt=\"incoming\" width=\"640\" height=\"139\" srcset=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/incoming-1024x223.png 1024w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/incoming-300x65.png 300w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/incoming.png 1186w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>Each accepted\u00a0tweet is then moved to an accepted list (the tweet file is renamed from &lt;Twitter ID&gt;.tweet to\u00a0&lt;Twitter ID&gt;.accepted):<\/p>\n<p><a href=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/accepted.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-1893\" src=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/accepted-1024x220.png\" alt=\"accepted\" width=\"640\" height=\"138\" srcset=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/accepted-1024x220.png 1024w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/accepted-300x65.png 300w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/accepted.png 1190w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>The next step is a bit more complex. \u00a0To make the most of the available radio bandwidth, tweets are combined together into radio packets. \u00a0So whenever there are enough tweets to combine, or the uplink queue is empty, the program seeks to find the best combination of tweets to join together into a single radio packet (max 255 bytes). \u00a0These packets are then placed in a queue on a Raspberry Pi running my LoRa gateway:<\/p>\n<p><a href=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/queue1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-1900\" src=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/queue1-1024x183.png\" alt=\"queue\" width=\"640\" height=\"114\" srcset=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/queue1-1024x183.png 1024w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/queue1-300x54.png 300w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/queue1.png 1175w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>Here we just have a single tweet, because only one was generated in the above example.<\/p>\n<p>Periodically, the balloon tracker stops transmitting down to the ground, and starts listening for an uplink from the gateway. \u00a0If the queue has at least one entry then the gateway program will send one entry to the balloon. \u00a0In turn, the balloon tracker will receive the packet and save it as a file. \u00a0Meanwhile, a small Python script will see that file and\u00a0start displaying it on the Astro Pi LED.<\/p>\n<p><iframe loading=\"lazy\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/v4IbGx-muzI?feature=oembed\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<p>The gateway needs to know if the uplink was received OK or not, so the tracker includes a &#8220;last message ID received&#8221; value in the telemetry packets that it sends to the ground:<\/p>\n<p><a href=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/downlink.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1896\" src=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/downlink.png\" alt=\"downlink\" width=\"194\" height=\"618\" srcset=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/downlink.png 194w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/downlink-94x300.png 94w\" sizes=\"(max-width: 194px) 100vw, 194px\" \/><\/a><\/p>\n<p>The gateway then parses this information and removes the matching message from the queue (renames &lt;ID&gt;.sms as &lt;ID&gt;.ack). \u00a0The final step is for the Windows program to then remove the message from its list of queued messages\u00a0and add it to the list of acknowledged messages:<\/p>\n<p><a href=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/acked.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-1897\" src=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/acked-1024x297.png\" alt=\"acked\" width=\"640\" height=\"186\" srcset=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/acked-1024x297.png 1024w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/acked-300x87.png 300w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/acked.png 1174w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve made some progress on my &#8220;tweet uplink&#8221; software, and now all stages in the process are fully automated except for a required manual approval step, in case anyone tries to spam the flight! The key new element is a Windows program that lists incoming tweets and offers Accept\u00a0and Reject [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[],"_links":{"self":[{"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=\/wp\/v2\/posts\/1891"}],"collection":[{"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1891"}],"version-history":[{"count":3,"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=\/wp\/v2\/posts\/1891\/revisions"}],"predecessor-version":[{"id":1901,"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=\/wp\/v2\/posts\/1891\/revisions\/1901"}],"wp:attachment":[{"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1891"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1891"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1891"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}