You know that feeling, right?
A big 2 day hike that we have planned for some time has somehow crept up on us. And it turns out it's actually happening this very weekend. Oops. Are we prepared? Are our muddy boots (just about) dry from our last outdoor adventure? Do we have sufficiently waterproof gear to counter the inevitably atrocious UK weather? And most importantly, is that Raspberry Pi we converted into a GPS logger really ready for service?
Yes, we remember the age old wisdom. That a weekend away in the wilderness is an opportunity to get away from all the modern amenities that we have grown so dependent on. And a chance to appreciate mother nature in all its beauty and glory. But a titchy, single-board computer - named partly after a fruit - doesn't count as real technology, right? After all, it's apparently made not too far in South Wales from our proving ground, so it could almost be described as a respectful homage (albeit a completely unintended one).
We have some gear to urgently pack, and a Pi to soup up, so there's the short and sweet introduction. 2 days. 10 peaks of the Brecon Beacons National Park. Over 50 kilometres of walking, and close to 3000 metres of climbs (if we are to believe our mostly trustworthy Pi). Will this brave little device survive an adventure away from civilisation, and prove to be - once and for all - a useful travel companion?
All jokes aside, any outdoor activity that involves being... well... outdoors for an extended duration is likely to prove a challenge for any number of reasons. And hiking in the hills is no exception.
In other words: please don't overly rely on a suspicious-looking, DIY GPS receiver to help you navigate the ranges. You will receive little sympathy from the mountain rescue team when they find you huddled under a rock with a 3D-printed "gadget" housing a Raspberry Pi. We took along with us plenty of useful gear; including mobile phones (with GPS), Ordnance Survey digital and paper maps, along with all the usual hiking apparel to prepare us for bad weather and darkness.
Remember; you cannot eat your Raspberry Pi either to top up your energy levels.
In other words: please don't overly rely on a suspicious-looking, DIY GPS receiver to help you navigate the ranges. You will receive little sympathy from the mountain rescue team when they find you huddled under a rock with a 3D-printed "gadget" housing a Raspberry Pi. We took along with us plenty of useful gear; including mobile phones (with GPS), Ordnance Survey digital and paper maps, along with all the usual hiking apparel to prepare us for bad weather and darkness.
Remember; you cannot eat your Raspberry Pi either to top up your energy levels.
You don't want to be the tool without the tooling:
- We'll be using a SSD1306-based OLED with a resolution of 128×32. It is monotonously monochrome, and considerately compact. Perfect, it turns out, for fitting into some sort of dubious "travel-sized" mountaineering gadget. We can
interfereinterface with our model using I2C. - A DS18B20 temperature sensor, with a pull-up resistor (4.7kΩ) inserted between VDD and DQ. As you'll know by now, this is our favourite digital temperature sensor, and it works using the super simple 1-Wire protocol.
- To geolocate ourselves on Planet Earth, we're using a GPS receiver USB dongle thingummy. It is powered by a U-Blox UBX-G7020 chip that worked well for us last time. If it ain't broke, don't fix it.
- Clearly, we'll be using a Raspberry Pi running Raspbian OS to bring this all together. Could we have used a different, more compact and austere system? Possibly. But with a USB GPS receiver in hand (and no more time left to ponder), we chose the only system currently in our Rosie lab toolkit equipped with a USB port. Non-USB GPS receivers are available on the market.
- For power, we used a 20,000mAh / 5V / 2.1A USB battery pack, which is - admittedly - quite a bulky gizmo. We discovered this to be more than adequate to power the Pi for over 2 days of walking (with plenty of charge still left to spare). We would not be amused if our little experiment came to a premature end due to the battery being depleted. And it's why we're playing it safe with power.
Chequered history:
Building Rosie 2.0 - naturally - assumes that there is a Rosie 1.0. For that reason, casting your eyes over the organised chaos that was Rosie and Rosie Patrol is highly recommended.Specifically, this post is a natural continuation of a previous episode - Beam me up, Rosie!
There's also been the following episodes of Rosie 2.0:
- PiAMI HEAT
- Crawly creepy
- 2 crawly 2 creepy
- Balancing the books
- Shaken not steered
- El-oh-wire
- Raspberry bye, hello
- Red current and serial
Bit by byte:
- Prep the Raspberry Pi by re-living all of the previous GPS shenanigans; that includes everything from connecting the GPS receiver, to setting up gpsd as a service to allow us to interrogate GPS data from the receiver using Python. We used a USB extension cable for the GPS receiver as this allowed it to be precariously dangled outside of the final case.
- Connect the SSD1306 OLED screen to the Raspberry Pi using I2C connections (power, data and clock), and install the brilliant SSD1306 OLED driver
- Claim a rather small victory by displaying meaningless data on the OLED screen
- Connect the DS18B20 temperature sensor (with pull-up resistor) to the GPIO pins of the Raspberry Pi. Yes - we've done this a gazillion times before.
- Write a Python app to take GPS and DS18B20 readings, and to display them on-screen, as well as write them out to a timestamped CSV file. Use supervisor to make sure the application starts automatically when the Pi powers up without human intervention. Remember the rule: no other computers are allowed when you're at one with nature. Ok, except the two smartphones.
- Quite literally, take a hike. Pray that none of this fails miserably on the day (or two).
Besides, no-one will be interested in knowing our location in real-time. Except the emergency services, perhaps. And the helicopter they dispatch.
You ain't seen nothing yet:
When we last visited the Brecon Beacons National Park back in July, the weather was glorious. The sun was out. Sky was blue. Birds were singing. Other friendly walkers were out in force. Life was great in this divine part of South Wales.4 months on, and with Winter imminent, we're doing it again. Except the weather now looks like this. It's cold. There's rain, hail and winds that attempt to blow you off the edge. And we're seriously starting to wonder if it was such a great idea to pack a small computer in the rucksack.
Notably, this time, we're basing our trek on the Brecon Beacons 10 peaks ultramarathon event (short course version), because we have aspirations to enter the event some day, with or without the Pi.
Here is what the website of the official event tells us about the route:
In other words, there's 10 peaks in total. They need to be tackled in a specific order. And it's probably quite painful.
We aren't quite ready to complete this all in one go yet. We'll also tinker with the order (so that we can start on the main A470 road at the beginning of each day). But we'll still aim to conquer all 10. And better still, get the Raspberry Pi to tell us all about it.
Happy Pi-hiking!
Detail:
This journey starts where the earlier one ended.We built a semi-acceptable "GPS tracker" using a Raspberry Pi and a U-Blox GPS receiver over a year ago. But it wasn't equipped to tell us anything about what it was observing - in real-time. Or whether it was, in fact, observing anything at all.
This is where we felt that the first enhancement was very much needed: a tiny window into our Pi's clever brain - an OLED. An organic variant of the LED tech which sounds aptly green.
We chose a very small SSD1306-based OLED screen with a teeny resolution of 128×32. Why? Because it looked small enough not to be in anyone's way, and perhaps it wasn't going to be very power hungry. After all, we won't be looking at it most of the time. We would actually like to concentrate on not getting lost for the majority of the weekend.
Our model uses an I2C interface, so it was connected like this to the Pi:
Raspberry Pi | SSD1306 OLED | ...Used for? |
---|---|---|
GPIO 3 (BCM 2) | I2C SDA | I2C data line |
GPIO 5 (BCM 3) | I2C SCL | I2C clock line |
5V | 5V | 5V |
0V (Ground) | 0V | 0V |
The excellent luma.oled driver allows us to interact with the OLED in a hassle-free fashion using Python. Let's install it.
sudo pip3 install luma.oled
All installed? Any time we have an I2C device attached, we generally check if it is visible to the operating system. To do this, we'll run i2cdetect.
i2cdetect -y 1
There it is, with an I2C address of "3c". That's all we need to know about it for now. Let's delve straight into Python, with the intention of showing something witty on screen.
from luma.core.interface.serial import i2c from luma.core.render import canvas from luma.oled.device import ssd1306 from PIL import ImageFont serial = i2c(port=1, address=0x3C) device = ssd1306(serial, 128, 32) font = ImageFont.truetype("FreeMonoBold.ttf", 16, encoding="unic") with canvas(device) as draw: draw.text((0, 0), "This: line 1", fill="white", font=font) draw.text((0, 16), "This: line 2", fill="white", font=font)
We are effectively importing required luma modules, instantiating our I2C object with the designated address, then using it to create a SSD1306 object representing our 128×32 OLED screen. Then using the canvas() method, we can easily output stuff on screen (including text). There's plenty to play around with here if you would like to tinker with the font, font size or positioning of the text.
How do we know all this? Because the brilliant documentation tells us so.
Not a lot of coding right there, but it does have immediate visual results that fill us with confidence.
And with the OLED screen now under our control, we'll go and conquer the next hill.
There should be very little left for us to learn about the DS18B20 temperature sensor. We've used them on Pi's, and we've used them with ESP8266's. Therefore there is not a lot of preamble required here, other than that we'll connect the sensor up to designated Pi GPIO pins, along with the pull-up resistor. Using the 1-Wire protocol and its Python module, we can take temperature readings.
And that's about it. Happy random temperature measuring!
We're speeding along, as we have an entire rucksack to populate with (arguably more useful) trekking paraphernalia.
Note that we need gpsd installed and working from this point onwards. Hopefully, gpsd is already running as a service and has detected your GPS receiver. This can all be verified using the single cgps command:
cgps -s
If everything is all connected and working, the receiver should be detecting a GPS signal. And - as a result - there should be some interesting data being displayed on-screen about where the satellites think you are on the surface of Planet Earth.
And all that is left is for us to write a Python application that attempts to do the following things:
- ...obtains GPS data and temperature readings...
- ...displays them on the OLED screen...
- ...logs the values in a CSV file for later inspection...
- ...does all of this without breaking down...
Our app would then run in a never-ending loop, with measurements taken at predefined intervals. They will be displayed across two "views" that toggle between each other (first, showing date, time, elevation and temperature, second, showing latitude and longitude positional information).
Most critical - and we thankfully realised this before the trip - is to build some basic exceptions handling. In order for the application not to crash because of data not being available (such as if the GPS signal is lost) we will choose to detect those events and handle them accordingly.
This is the code that survived the weekend.
Here is the "home" page showing the current date, time, temperature and elevation. Nice and bright in the darkness.
...And here it is showing latitude and longitude positional information. We need the entire length of the screen, as these digits can get quite long. And it's probably the screen we need the most when the the helicopter gets dispatched. Help! Here is where you can find us.
It's almost time to set off on our journey.
Do we really want to carry our brave Pi around the hills in its most naked form, dangerously exposed to the elements? It's unlikely to survive 1 hour in the rucksack, next to the leaking bottle of water and smelly socks from the day before. Oh yes, and the rain and hail.
For this reason, we 3D-printed a nondescript box. It's large enough to house the Pi and the temperature sensor. It also has a narrow slit for the OLED screen (which will be covered by a transparent acrylic sheet), and holes in the side for the USB power and GPS dongle cables. We'll seal it shut with (allegedly) "weatherproof" Gorilla Tape... although in our unscientific opinion, the end result is far from waterproof.
Is everything all nicely packaged up? Tough! There's no time left for further improvements. This will just have to do.
At no point was it our intention to give out the impression that this was a "professional" bit of mountaineering kit. And if someone still felt misled on this fact after inspecting what looks like a tampered mains wall socket box with some suspicious cables sticking out, there is a pretty explicit reminder to set the record straight once and for all: "TRACKER TEST".
Here is the complete setup we are packing into a (waterproof) compartment in the rucksack. It is simply powered on by connecting the power lead to the USB battery pack. And (ungracefully) powered off by yanking it out. We ought to have addressed this with a shutdown switch, as we're running the risk of corrupting the storage by powering it off through a disorderly shutdown.
Before we set off on our hike, we need to be mindful that our USB battery pack requires a decent charge. It is rated at 20,000mAh, and can supply 5V at up to 2.1A. In fact, once charged, it was happily able to power the Pi for the entirety of the 2 day walk. Comfortably.
We also need to ensure that our Python application starts up automatically when the Pi does... and for that we used Supervisor. We won't be taking any laptops or means to connect to the Pi for the weekend. We are therefore expecting the GPS logger app to start working the moment the Pi is cabled into the USB battery pack and powered up.
Without any networking, we were also horrified to discover that our Pi had an incorrect system time. We were used to it being connected to the Internet all the time at home, and being able to synchronise its time using NTP. Without the Internet, and access to a NTP server, Raspbian OS on the Pi quickly reverted back to its incorrect hardware time. And this explains why the photos show a time that doesn't appear to correlate with the time of day. Easily fixed in the data afterwards, of course. But still, pretty annoying.
And lastly, while we're still being honest about our failures upfront, we must confess that it was a terrible idea placing the DS18B20 temperature sensor inside the 3D-printed box. It wasn't being exposed to the elements at all. Consequently, all it was monitoring was the heat being generated by the Pi, while being trapped in a well insulated box. Pretty pointless, we admit.
Now, for the shameless opportunity to showcase the Brecon Beacons landscape. Here are some of the memorable scenery from the weekend (on the rare occasions that the sky had cleared):
And if you were in any doubt that our fearless Pi saw some action on the hills, here it is on the very first peak - Fan Fawr. The OLED confidently displays an elevation of 734.8 meters - which happens to be precisely what the official guide tells us it should be (give or take it being held at waist height).
This is looking quite promising.
Roll forward 2 days. Back in civilisation.
We were elated when we discovered CSV files on the Pi containing readings that seemed seemingly intact and trustworthy.
All things considered, GPS data was surprisingly accurate. There were no outliers, no noise, no gaps in recordings, nor any anomalies that had to be explained away. Pretty much from the moment that it detected a GPS signal at the start of the day, it recorded GPS data continuously, and accurately. A great result overall! Repeated in a busy urban environment, its accuracy is likely to suffer. And this may warrant the use of algorithms to neutralise the noise.
There are plenty of sites out there that allow you to plot a route using a series of GPS coordinates. We used GPS Visualizer in this instance, as it has a cool feature to toggle between different maps.
Here are the results (and spot where we got slightly lost trying to find a crossing of the reservoir).
Similarly, elevation readings appear to be in line with what we were expecting. We can evidence all the peaks that we claim to have conquered - and they roughly match up with the altitudes we were expecting.
Here is a little graphic we put together based on all the data collected by the Pi.
Some of these metrics were extrapolated afterwards from the data (as we had no need for it during the day, in real-time).
- Total time is an easy one to establish, it is the finish time - start time. Done.
- Total climb is the sum of all increases in elevation between recordings (in other words; add to total climb if elevation has increased from last measurement, add nothing if decreased).
- Total distance is an interesting one; as it requires us to be able to calculate distance between 2 GPS coordinates on Earth's surface. Sounds complicated, right?
Thankfully, there is an accepted, mathematical method for doing just that, and it's called the Haversine method.
In Python, this can be done using the haversine module:
from haversine import haversine haversine((lat_before, long_before), (lat_now, long_now))
Example below shows a distance of 0.66 meters. Not a lot of progress was made in this particular interval.
So all in a good weekend's work. All 10 peaks climbed. Pi survived. Data was intact. So were our legs (well, just about). And we were never quite required to recite out our GPS coordinates to the emergency services... which was a result in itself.
...And, most importantly, we can draw some pretty graphs that we can use to pad out a curiously hybrid blog post about hiking and hacking a Pi, based on our little companion's findings.
Update - November 2018
Use of the luma.oled driver means that it's pretty simple to adapt the code to output to a different OLED display. Here it is, with a SSD1327-based 128×128 OLED display.Update - March 2019
Fast forward several months, and an enhanced version of this GPS-makery was relentlessly carried around the Brecon Beacons Nation Park (again). You can read all about it in this["orientated"].Update - September 2019
This intrepid Raspberry Pi was eventually carried around the official Brecon Beacons 10 Peaks Ultramarathon event, and was used by the family to spy on our progress.Read all about it in the sequel: Taking a Peak: Xtreme² Edition.
Go and see the doc:
We're heavily reliant on the excellent luma.oled driver available here:The library is further documented here:
SSD1306 documentation is found here:
The Python haversine module is described here:
Our USB GPS receiver is based on the U-blox UBX-G7020 chipset:
The gpsd-py3 library can be found on GitHub here:
And, finally, extensive GPSD documentation is available here:
Comments
Post a Comment