A LoRaWAN enabled HDMI display that can be updated from up to 15km away.
This post takes a look at how the Raspberry Pi Compute Module 3 can be combined with LoRaWAN technology to create powerful, remote digital signage solutions. Using The Things Network for connectivity, the Raspberry Pi Compute Module IO Board and Microchip RN2483 PICTail for hardware prototyping, and some simple Python scripts.
There is no shortage of IO on the Compute Module and in addition to HDMI, DPI, 4x camera interfaces and two each of I2C, SPI, UART and SDIO interfaces, there are also 48x GPIO pins. In our case all we need is a single UART to interface the RN2483 LoRaWAN module, but a finished product might have buttons, power supply monitoring or other features that create additional value.
The following connections were made between the IO Board and RN2483 PICTail module:
- 3v3 →26
- GND → 28
- 14 (UART 0 Tx) → 17 (RN2483 Rx)
- 15 (UART 0 Rx) → 21 (RN2483 tx)
Since there is no wired or wireless LAN connectivity — there will be many applications with no need for either — a USB Ethernet adapter was used to provide network access for development.
Writing onboard flash
So how do you load an operating system onto a flash chip that is soldered to the Compute Module? Quite easily as it turns out, thanks to a little utility of some ~500 lines of C that will boot the Pi over USB when it fails to boot from flash or a jumper is set to disable this. The rpiboot utility comes supplied with firmware that is loaded by default and turns the Pi into a Mass USB Mass Storage Device (MSD), so that the flash can then be written to just as you would a USB memory stick.
After loading Raspbian Lite the /etc/hostname and /etc/hosts files were edited to assign a unique hostname and make it easier to find on the network. SSH is now disabled by default in Raspbian, but is easily enabled by simply creating an empty file on the boot partition.
$ sudo touch /boot/ssh
Since we wanted to use the first UART for connecting up the RN2483, it was necessary to first disable use of the port for console messages and login.
$ sudo raspi-config
Interfacing Options → P6 Serial (disable).
Followed by enabling the port for use by editing
/boot/config.txt and adding the line:
After rebooting the first UART was available as /dev/ttyAMA0.
Software update and install
Always a good idea to update the Raspbian system software to the latest available. The only software we need to drive the RN2483 and Pi framebuffer are a couple of Python libraries.
$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ sudo apt-get install python-serial python-pygame
The Things Network configuration
First a new application was configured via The Things Network console. Following which a device could be registered to this, but for which the DevEUI was required.
A Python script was used to get the DevEUI for the RN2483 module, but a terminal emulator could have been used instead and the command is simply:
mac get deveui
When an Over-the-Air Activation (OTAA) device is registered we are provided with:
On start-up the module will need to be configured with these before it can request to join the network and following which, if successful, it will then be allocated a network address and session encryption keys will be configured. This can be thought of as roughly analogous to DHCP and SSL.
At this point the configuration was tested by running a Python script that joins the network before performing uplink — that is, sends messages up to the network.
TTN Console was then used to confirm that the device had succeeded in joining and that messages were indeed being received.
The LoRaWAN Class C mode of operation that we are using is highly optimised for off-grid applications which may require a battery life of many years. This is achieved by, rather than constantly listening for downlink — which would quickly drain the battery — instead just opening up two short receive windows at 1 and 2 seconds after performing network uplink. If the device has no need for uplink this is fine and all it needs to do is to perform an empty uplink.
The Python code below was used to receive downlink test messages and once again for uplink a single byte was sent up to the network, which could be observed via the TTN Console for debug.
# -*- encoding: utf-8 -*-
p = serial.Serial("/dev/ttyAMA0" , 57600 , timeout=5)
# Uplink message to send
writeconfig = 1
# Write to the RN2483 and if downlink is received, return it
down = None
if rdata[:6] == "mac_rx":
if rdata == "":
# Reset the RN2483 module
# Configure the network parameters
if writeconfig is 1:
send("mac set appeui 70B3D57EF0003723")
send("mac set appkey EAB52037FAD7BA6C6EDC191341DC6FCF")
send("mac set adr off")
# Do an OTAA join
send("mac join otaa")
# Send uplink and if we get downlink, print it out
down = send("mac tx uncnf 1 "+up)
print "DOWNLINK: "+down
The only difference between this and the uplink-only test is that we now look for the RN2483 returning the string “mac_rx” and upon finding this, extract and print the downlink message.
The TTN Console was again used in testing, but this time to enqueue a downlink message.
Writing to the framebuffer
Adafruit provide an excellent tutorial for getting started with Pygame and above can be seen the first test of this, which simply paints the screen red. Rather than repeat details of how this works here, I would recommend heading over to the Adafruit website.
Putting it all together
The example Pygame class provided in the tutorial was integrated into the OTAA downlink script, with a new method that would be called upon receiving a downlink message and which would first clear the display, before then writing text to it. Once again the TTN Console was used in testing.
Upon receiving the downlink message this was printed out to the terminal and attached screen.
Scope for improvement
This basic demonstration shows what is possible when you combine the Raspberry Pi Compute Module and LoRaWAN technology. Of course, any Raspberry Pi could have been used, but it’s easy to see here how a small custom PCB could be made with a low component count, that integrates the Compute Module, RN2483 module and a simple power supply. Resulting in a powerful, self-contained display solution that can be updated remotely from a distance of up to 15km or so.
The software used was quickly hacked together and all this did was to display bytes sent over the LoRaWAN link. Potential improvements to this include:
- Checking that the OTAA join was successful and retrying if this fails
- Using Pygame to also display network debug output upon start-up
- Sending data via a more convenient TTN client or app, e.g. a Node-RED based
- Making use of TTN fields to specify font size, position and colour etc.
With the basic infrastructure in place there is no shortage of ways that the usefulness of a remotely updated display solution such as this could be greatly increased.
The Python scripts are available on GitHub and can be used as a starting point for your own projects, but you will need to configure the appropriate network parameters.