{"id":1876,"date":"2015-11-13T22:43:14","date_gmt":"2015-11-13T22:43:14","guid":{"rendered":"http:\/\/www.daveakerman.com\/?p=1876"},"modified":"2015-11-19T16:19:08","modified_gmt":"2015-11-19T16:19:08","slug":"tweeting-above-the-clouds","status":"publish","type":"post","link":"http:\/\/www.daveakerman.com\/?p=1876","title":{"rendered":"Tweeting Above The Clouds"},"content":{"rendered":"<p>Following my recent <a href=\"http:\/\/www.daveakerman.com\/?p=1850\">successful test<\/a> of balloon-to-balloon communications, I had the idea of uploading messages from the ground to a balloon (via LoRa radio), and then have those messages displayed on the LED matrix of an &#8220;Astro Pi&#8221; Sense HAT, as will be used by Tim Peake during his stay on the International Space Station.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone\" src=\"https:\/\/www.raspberrypi.org\/wp-content\/uploads\/2015\/06\/astro-pi-hat.png\" alt=\"\" width=\"688\" height=\"361\" \/><\/p>\n<p>You may well be asking who is likely to see those messages, so here&#8217;s the plan:<\/p>\n<ul>\n<li>Launch a weather balloon before Tim flies to the ISS on\u00a0Soyuz TMA-19M<\/li>\n<li>Encourage people to send messages to Tim Peake via tweets to a specific hashtag<\/li>\n<li>Those tweets will be automatically uploaded to the balloon via a radio link<\/li>\n<li>Tweets will then be scrolled on the Astro Pi LED matrix<\/li>\n<li>A\u00a0video camera which will record the entire flight and the scrolling messages<\/li>\n<li>Download sense HAT data during the flight<\/li>\n<li>After the flight is recovered, selected camera footage will be uploaded to YouTube and sent to Tim.<\/li>\n<\/ul>\n<p>There&#8217;s nothing particularly complicated in the above, but there are quite a few steps involved to make it work.<\/p>\n<h2>Astro Pi + Pi In The Sky + LoRa Board<\/h2>\n<p>For the balloon tracker to perform the above tasks, it needs an Astro Pi of course, plus a Pi In The Sky board for GPS and power, plus a LoRa board to allow for uploads from the ground. \u00a0The first thing to do then was check to see if there are any I\/O conflicts between the above.<\/p>\n<p>The only conflicts were to do with one of the 2 LoRa modules on the LoRa board. \u00a0Since we only need 1 LoRa module, we can just put that in the non-conflicting position (CE1).<\/p>\n<p>So, I built a stack with a Pi B+ on the bottom, then a Pi In The Sky (PITS) board, LoRa board and finally an Astro Pi board which, of course, has to be on top otherwise the LED matrix won&#8217;t be visible!<\/p>\n<p><a href=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro2.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-1880\" src=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro2-1024x679.jpg\" alt=\"astro2\" width=\"640\" height=\"424\" srcset=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro2-1024x679.jpg 1024w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro2-300x199.jpg 300w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<h2>Reading Tweets<\/h2>\n<p>The first part of the sequence is to search Twitter for messages to upload, and for this Iwrite a short Python script using the <a href=\"http:\/\/www.tweepy.org\">Tweepy<\/a> library. \u00a0The following function and main code show the process:<\/p>\n<pre><code>def SearchHashtag(HashTag, LastID, Count):\r\n  c = tweepy.Cursor(api.search, since_id=LastID, q=HashTag).items(Count)\r\n  for tweet in c:\r\n    text = tweet.text.encode('ascii',errors='ignore').decode(\"utf-8\")\r\n    print(str(tweet.id) + \" - @\" + tweet.user.screen_name + \": \" + text)\r\n    if tweet.id &gt; LastID:\r\n      LastID = tweet.id\r\n  return LastID\r\n\r\n LastID = 0\r\n Count = 10\r\n HashTag = '#AstroPiTest'\r\n while 1:\r\n   LastID = SearchHashtag(HashTag, LastID, Count)\r\n   print (\"LastID = \", LastID)\r\n   time.sleep(5)\r\n<\/code><\/pre>\n<h2><\/h2>\n<p>The complete script reads each matching tweet:<\/p>\n<p><a href=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro1.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1878\" src=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro1.jpg\" alt=\"astro1\" width=\"611\" height=\"98\" srcset=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro1.jpg 611w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro1-300x48.jpg 300w\" sizes=\"(max-width: 611px) 100vw, 611px\" \/><\/a><\/p>\n<p>and creates a separate text file for each such tweet:<\/p>\n<pre>@daveake: Just testing for a project ....<\/pre>\n<p>For the actual flight then will be more filtering, both programmatic and human, to ensure that only real\/polite\/sane messages are uplinked!<\/p>\n<h2>Uplink<\/h2>\n<p>For the radio uplink I have modified my <a href=\"http:\/\/www.daveakerman.com\/?p=1719\">LoRa Gateway<\/a>, which is normally tasked with receiving LoRa transmissions from balloons and then uploading the data (telemetry and\/or images) to a web server. \u00a0For this flight though we need it to be able to send messages up to the balloon. \u00a0That&#8217;s a straightforward task, using GPS timing to decide when the balloon can transmit and the gateway should listen, and then when the gateway can transmit and the balloon should listen. \u00a0For testing I&#8217;ve set a short period each minute for the uploads, but this may change for the flight (to allow more messages to be uploaded).<\/p>\n<p>The gateway has to monitor a folder, looking for messages to upload. \u00a0Those messages are produced by the Python script mentioned earlier, so the gateway just has to read the messages, and send them to the balloon. \u00a0Sometimes tweets may come in faster than they can be uploaded, so the code will need to be able to cope with that.<\/p>\n<p>Here&#8217;s a screenshot of the gateway uploading the above message:<\/p>\n<p><a href=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro3.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1882\" src=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro3.png\" alt=\"astro3\" width=\"644\" height=\"398\" srcset=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro3.png 644w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro3-300x185.png 300w\" sizes=\"(max-width: 644px) 100vw, 644px\" \/><\/a><\/p>\n<h2>Receiving Messages At The Tracker<\/h2>\n<p>For this I modified the PITS software so that it can accept and process these uplinked messages. \u00a0To keep the PITS changes simple, all it does is receive the message:<\/p>\n<p><a href=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro4.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1883\" src=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro4.png\" alt=\"astro4\" width=\"610\" height=\"125\" srcset=\"http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro4.png 610w, http:\/\/www.daveakerman.com\/wp-content\/uploads\/2015\/11\/astro4-300x61.png 300w\" sizes=\"(max-width: 610px) 100vw, 610px\" \/><\/a><\/p>\n<p>and then create a small file containing the text to display:<\/p>\n<pre>Just testing for a project ....<\/pre>\n<p>&nbsp;<\/p>\n<h2>Displaying The Message<\/h2>\n<p>This is done by a simple Python script that uses the Astro Pi library. \u00a0The following snippet shows how it works:<\/p>\n<pre>def process_file(file):\r\n  print (\"File found: \", file)\r\n  f = open(file, 'rt')\r\n  line = f.read()\r\n  f.close()\r\n  os.remove(file)\r\n\r\n  sense = SenseHat()\r\n  sense.show_message(line)\r\n \r\nwhile 1:\r\n  for file in os.listdir('.'):\r\n    if fnmatch.fnmatch(file, '*.sms'):\r\n      process_file(file)\r\n      time.sleep(1)\r\n  time.sleep(1)<\/pre>\n<p>&nbsp;<\/p>\n<h2>The Result<\/h2>\n<p><iframe loading=\"lazy\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/cjk1FQIRW3k?feature=oembed\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Following my recent successful test of balloon-to-balloon communications, I had the idea of uploading messages from the ground to a balloon (via LoRa radio), and then have those messages displayed on the LED matrix of an &#8220;Astro Pi&#8221; Sense HAT, as will be used by Tim Peake during his stay [&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\/1876"}],"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=1876"}],"version-history":[{"count":10,"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=\/wp\/v2\/posts\/1876\/revisions"}],"predecessor-version":[{"id":1902,"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=\/wp\/v2\/posts\/1876\/revisions\/1902"}],"wp:attachment":[{"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1876"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1876"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.daveakerman.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1876"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}