Taggle IoT Corella + Raspberry Pi


What we're trying to achieve

This document walks you through the steps required to get this all running, but we'll also point out how you can extrapolate -- to set up different sensors, multiple data sources, compress data, and how to encode/decode using Python and Javascript.

Taggle Systems provides the Corella as a great starting point for developing IoT solutions.


What you'll need

You'll need a PC connected to the internet. Or a linux box. Or better still, a mac.
It would be handy if you're familiar with Linux on the command line, and with the basics of Python. And for the front-end reporting, there's a little bit of javascript to deal with.
But I'm sure you can follow the instructions here, step by step - and if nothing peculiar goes wrong, you'll be up and running in a very short time.

In the meantime, gather these bits of hardware...

parts

Taggle Corella LPWA transmitter

Raspberry Pi

SD card (min 8GB Class 4 recommended)

Atmospheric Sensors

If your Corella came without header pins

If your Corella has header pins


Getting the Raspberry Pi working

If you already have an RPi set up, and you can connect via ssh or you've got a monitor, mouse, and keyboard - all well and good. You can skip this section, but make sure to check the bit about freeing up GPIOs 14 and 15, and disabling the system service that initialises the modem.

Download RASPBIAN

raspbian

I chose RASPBIAN STRETCH WITH DESKTOP

Create the SD card

Etcher is a graphical SD card writing tool that works on Mac OS, Linux and Windows, and is the easiest option for most users.

etcher

As a rough indicator, this took me about 15 minutes on a 2015 iMac running macOS High Sierra version 10.13.4 (17E199) with 24GB RAM.

Enable SSH

step1 Place a file named “ssh” (without any extension) onto the boot partition of the SD card.

Connect UART0/ttyAMA0 to GPIOs 14 and 15.

By default the bluetooth module uses this port, so the simplest way is to disable bluetooth https://www.raspberrypi.org/documentation/configuration/uart.md setup

Use the overlay
pi3-disable-bt

step2 Edit config.txt to add this line :

... # Stop Bluetooth using standard Rx/Tx (GPIO 14/15) dtoverlay=pi3-disable-bt ...

Plug It In

Once the Raspberry Pi has booted, there are 2 ways to connect to it from your PC/laptop

$ ssh pi@raspberrypi.local

If this does not work, you need to find the IP address of the Raspberry Pi
(in this example, we're on network 10.1.1. and the router is 10.1.1.1
-- you might find yourself with a LAN IP of 192.168.1.xxx, so modify this to suit. Download NMAP here)

$ sudo nmap -sn 10.1.1.1/24 | grep -i raspberry -B 2
$ ssh pi@10.1.1.xxx

username: pi
password: raspberry

$ ssh pi@raspberrypi.local

The authenticity of host 'raspberrypi.local (10.1.1.67)' can't be established. ECDSA key fingerprint is SHA256:430q7aXM7fGkVEofCN/LkLaqhqCQDKVV7g60UgiKnEg. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'raspberrypi.local,10.1.1.67' (ECDSA) to the list of known hosts. pi@raspberrypi.local's password: Linux raspberrypi 4.14.34-v7+ #1110 SMP Mon Apr 16 15:18:51 BST 2018 armv7l Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. SSH is enabled and the default password for the 'pi' user has not been changed. This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.

Setup and Configuration

https://www.raspberrypi.org/documentation/configuration/raspi-config.md

$ sudo raspi-config raspi-config

Reboot (this is the default action after raspi-config)

$ sudo reboot now

Once it has rebooted (this only takes a minute), reconnect using the new hostname.

$ ssh pi@corella-pi.local

Disable the system service that initialises the modem

$ sudo systemctl disable hciuart Removed /etc/systemd/system/multi-user.target.wants/hciuart.service.

Now your RPi is configured and ready to rumble.


Wiring up the Corella and Atmospheric Sensors

wiring01 Connect the Corella power.
3.3v connects to RPi pin #01
GND connects to RPi pin #09
circ01

wiring02 Connect the UART as shown.
(GPIO 14/15)
Corella DOUT connects to RPi pin #08
Corella DIN connects to RPi pin #10

wiring03 Connect the DHT11 sensor as shown.
5v connects to RPi pin #04
GND connects to RPi pin #06
S (data) connects to RPi pin #16
circuit2


Installing the Sensor software from Adafruit

$ mkdir ~/Desktop/corella
$ cd ~/Desktop/corella
$ sudo apt-get install git-core Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: git-core 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 1,410 B of archives. After this operation, 8,192 B of additional disk space will be used. Get:1 http://raspbian.raspberrypi.org/raspbian stretch/main armhf git-core all 1:2.11.0-3+deb9u2 [1,410 B] Fetched 1,410 B in 1s (925 B/s) Selecting previously unselected package git-core. (Reading database ... 124722 files and directories currently installed.) Preparing to unpack .../git-core_1%3a2.11.0-3+deb9u2_all.deb ... Unpacking git-core (1:2.11.0-3+deb9u2) ... Setting up git-core (1:2.11.0-3+deb9u2) ... $ git clone https://github.com/adafruit/Adafruit_Python_DHT.git Cloning into 'Adafruit_Python_DHT'... remote: Counting objects: 249, done. remote: Total 249 (delta 0), reused 0 (delta 0), pack-reused 249 Receiving objects: 100% (249/249), 77.01 KiB | 0 bytes/s, done. Resolving deltas: 100% (142/142), done. $ cd Adafruit_Python_DHT/
$ sudo python3 setup.py install running install running bdist_egg running egg_info creating Adafruit_DHT.egg-info writing top-level names to Adafruit_DHT.egg-info/top_level.txt writing dependency_links to Adafruit_DHT.egg-info/dependency_links.txt writing Adafruit_DHT.egg-info/PKG-INFO writing manifest file 'Adafruit_DHT.egg-info/SOURCES.txt' reading manifest file 'Adafruit_DHT.egg-info/SOURCES.txt' writing manifest file 'Adafruit_DHT.egg-info/SOURCES.txt' installing library code to build/bdist.linux-armv7l/egg running install_lib running build_py creating build creating build/lib.linux-armv7l-3.5 creating build/lib.linux-armv7l-3.5/Adafruit_DHT copying Adafruit_DHT/platform_detect.py -> build/lib.linux-armv7l-3.5/Adafruit_DHT copying Adafruit_DHT/Raspberry_Pi.py -> build/lib.linux-armv7l-3.5/Adafruit_DHT copying Adafruit_DHT/Raspberry_Pi_2.py -> build/lib.linux-armv7l-3.5/Adafruit_DHT copying Adafruit_DHT/Beaglebone_Black.py -> build/lib.linux-armv7l-3.5/Adafruit_DHT copying Adafruit_DHT/common.py -> build/lib.linux-armv7l-3.5/Adafruit_DHT copying Adafruit_DHT/__init__.py -> build/lib.linux-armv7l-3.5/Adafruit_DHT copying Adafruit_DHT/Test.py -> build/lib.linux-armv7l-3.5/Adafruit_DHT running build_ext building 'Adafruit_DHT.Raspberry_Pi_2_Driver' extension creating build/temp.linux-armv7l-3.5 creating build/temp.linux-armv7l-3.5/source creating build/temp.linux-armv7l-3.5/source/Raspberry_Pi_2 arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fdebug-prefix-map=/build/python3.5-RUbMX3/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.5m -c source/_Raspberry_Pi_2_Driver.c -o build/temp.linux-armv7l-3.5/source/_Raspberry_Pi_2_Driver.o -std=gnu99 arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fdebug-prefix-map=/build/python3.5-RUbMX3/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.5m -c source/common_dht_read.c -o build/temp.linux-armv7l-3.5/source/common_dht_read.o -std=gnu99 arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fdebug-prefix-map=/build/python3.5-RUbMX3/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.5m -c source/Raspberry_Pi_2/pi_2_dht_read.c -o build/temp.linux-armv7l-3.5/source/Raspberry_Pi_2/pi_2_dht_read.o -std=gnu99 arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fdebug-prefix-map=/build/python3.5-RUbMX3/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.5m -c source/Raspberry_Pi_2/pi_2_mmio.c -o build/temp.linux-armv7l-3.5/source/Raspberry_Pi_2/pi_2_mmio.o -std=gnu99 arm-linux-gnueabihf-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,relro -g -fdebug-prefix-map=/build/python3.5-RUbMX3/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-armv7l-3.5/source/_Raspberry_Pi_2_Driver.o build/temp.linux-armv7l-3.5/source/common_dht_read.o build/temp.linux-armv7l-3.5/source/Raspberry_Pi_2/pi_2_dht_read.o build/temp.linux-armv7l-3.5/source/Raspberry_Pi_2/pi_2_mmio.o -lrt -o build/lib.linux-armv7l-3.5/Adafruit_DHT/Raspberry_Pi_2_Driver.cpython-35m-arm-linux-gnueabihf.so creating build/bdist.linux-armv7l creating build/bdist.linux-armv7l/egg creating build/bdist.linux-armv7l/egg/Adafruit_DHT copying build/lib.linux-armv7l-3.5/Adafruit_DHT/platform_detect.py -> build/bdist.linux-armv7l/egg/Adafruit_DHT copying build/lib.linux-armv7l-3.5/Adafruit_DHT/Raspberry_Pi.py -> build/bdist.linux-armv7l/egg/Adafruit_DHT copying build/lib.linux-armv7l-3.5/Adafruit_DHT/Raspberry_Pi_2.py -> build/bdist.linux-armv7l/egg/Adafruit_DHT copying build/lib.linux-armv7l-3.5/Adafruit_DHT/Beaglebone_Black.py -> build/bdist.linux-armv7l/egg/Adafruit_DHT copying build/lib.linux-armv7l-3.5/Adafruit_DHT/Raspberry_Pi_2_Driver.cpython-35m-arm-linux-gnueabihf.so -> build/bdist.linux-armv7l/egg/Adafruit_DHT copying build/lib.linux-armv7l-3.5/Adafruit_DHT/common.py -> build/bdist.linux-armv7l/egg/Adafruit_DHT copying build/lib.linux-armv7l-3.5/Adafruit_DHT/__init__.py -> build/bdist.linux-armv7l/egg/Adafruit_DHT copying build/lib.linux-armv7l-3.5/Adafruit_DHT/Test.py -> build/bdist.linux-armv7l/egg/Adafruit_DHT byte-compiling build/bdist.linux-armv7l/egg/Adafruit_DHT/platform_detect.py to platform_detect.cpython-35.pyc byte-compiling build/bdist.linux-armv7l/egg/Adafruit_DHT/Raspberry_Pi.py to Raspberry_Pi.cpython-35.pyc byte-compiling build/bdist.linux-armv7l/egg/Adafruit_DHT/Raspberry_Pi_2.py to Raspberry_Pi_2.cpython-35.pyc byte-compiling build/bdist.linux-armv7l/egg/Adafruit_DHT/Beaglebone_Black.py to Beaglebone_Black.cpython-35.pyc byte-compiling build/bdist.linux-armv7l/egg/Adafruit_DHT/common.py to common.cpython-35.pyc byte-compiling build/bdist.linux-armv7l/egg/Adafruit_DHT/__init__.py to __init__.cpython-35.pyc byte-compiling build/bdist.linux-armv7l/egg/Adafruit_DHT/Test.py to Test.cpython-35.pyc creating stub loader for Adafruit_DHT/Raspberry_Pi_2_Driver.cpython-35m-arm-linux-gnueabihf.so byte-compiling build/bdist.linux-armv7l/egg/Adafruit_DHT/Raspberry_Pi_2_Driver.py to Raspberry_Pi_2_Driver.cpython-35.pyc creating build/bdist.linux-armv7l/egg/EGG-INFO copying Adafruit_DHT.egg-info/PKG-INFO -> build/bdist.linux-armv7l/egg/EGG-INFO copying Adafruit_DHT.egg-info/SOURCES.txt -> build/bdist.linux-armv7l/egg/EGG-INFO copying Adafruit_DHT.egg-info/dependency_links.txt -> build/bdist.linux-armv7l/egg/EGG-INFO copying Adafruit_DHT.egg-info/top_level.txt -> build/bdist.linux-armv7l/egg/EGG-INFO writing build/bdist.linux-armv7l/egg/EGG-INFO/native_libs.txt zip_safe flag not set; analyzing archive contents... Adafruit_DHT.__pycache__.Raspberry_Pi_2_Driver.cpython-35: module references __file__ creating dist creating 'dist/Adafruit_DHT-1.3.2-py3.5-linux-armv7l.egg' and adding 'build/bdist.linux-armv7l/egg' to it removing 'build/bdist.linux-armv7l/egg' (and everything under it) Processing Adafruit_DHT-1.3.2-py3.5-linux-armv7l.egg creating /usr/local/lib/python3.5/dist-packages/Adafruit_DHT-1.3.2-py3.5-linux-armv7l.egg Extracting Adafruit_DHT-1.3.2-py3.5-linux-armv7l.egg to /usr/local/lib/python3.5/dist-packages Adding Adafruit-DHT 1.3.2 to easy-install.pth file Installed /usr/local/lib/python3.5/dist-packages/Adafruit_DHT-1.3.2-py3.5-linux-armv7l.egg Processing dependencies for Adafruit-DHT==1.3.2 Finished processing dependencies for Adafruit-DHT==1.3.2

Installing the Taggle Corella software

$ cd ~/Desktop/corella
$ wget http://corella.taggle.com.au/rpi/custom_downloads/examples.tar.gz
$ tar xzvf examples.tar.gz
$ chmod +x DHT11*
$ ls -la

drwxr-xr-x 4 pi pi 4096 Apr 30 02:33 . drwxr-xr-x 3 pi pi 4096 Apr 29 23:25 .. drwxr-xr-x 11 pi pi 4096 Apr 29 23:27 Adafruit_Python_DHT -rwxr-xr-x 1 pi pi 483 Apr 30 01:36 DHT11-keepalive.sh -rwxr-xr-x 1 pi pi 13643 Apr 30 01:36 DHT11.py -rw-r--r-- 1 pi pi 176 Apr 30 01:37 corella-cron.txt -rw-r--r-- 1 pi pi 7821 Apr 30 02:33 examples.tar.gz drwxr-xr-x 3 pi pi 4096 Apr 30 02:18 frontend

Confirm that it works

Check the python 3 version

$ python3 -V
Python 3.5.3

Try running the software from the command line

$ python3 /home/pi/Desktop/corella/DHT11.py

The example DHT11 python script starts by running through the basic introspection commands.

Then it begins a cycle of reporting the Temp/Humidity from the DHT11 sensor.

Here's what you should expect to see...

pi@corella-pi:~/Desktop/corella $ python3 /home/pi/Desktop/corella/DHT11.py TIMESTAMP 1525093976.207 : Serial connection is confirmed. TIMESTAMP 1525093977.227 : Device ID : 130067 TIMESTAMP 1525093978.285 : Device Type : TAGGLE CORELLA TIMESTAMP 1525093978.285 : CORELLA #130067 Hardware Version : REV_A TIMESTAMP 1525093978.286 : CORELLA #130067 Firmware Version : 1.0.31 TIMESTAMP 1525093979.352 : CORELLA #130067 Maximum Recorded Temperature : 62 deg C TIMESTAMP 1525093979.352 : CORELLA #130067 Minimum Recorded Temperature : 31 deg C TIMESTAMP 1525093979.352 : CORELLA #130067 Current Power Supply : 3.12V TIMESTAMP 1525093980.382 : LED STATUS : LEDS OFF TIMESTAMP 1525093981.409 : LED STATUS : LEDS ON sending Code_Restart on channel 1 TIMESTAMP 1525093982.432 : CORELLA #130067 is ready to transmit. TIMESTAMP 1525093983.674 : Transmission successful : TYPE [1] : DATA [Code_Restart] sending Humid:75.0% on channel 3 TIMESTAMP 1525093984.207 : Warning : Original message padded to 12 bytes ! TIMESTAMP 1525093985.240 : Sleeping now - required for 8 seconds before sending the message. TIMESTAMP 1525093995.484 : Transmission successful : TYPE [3] : DATA [Humid:75.0% ] sending 23.0/75.0 on channel 4 TIMESTAMP 1525093995.485 : Warning : Original message padded to 12 bytes ! TIMESTAMP 1525093996.517 : Sleeping now - required for 9 seconds before sending the message. TIMESTAMP 1525094007.766 : Transmission successful : TYPE [4] : DATA [23.0/75.0 ] sending Temp:23.0C on channel 5 TIMESTAMP 1525094007.767 : Warning : Original message padded to 12 bytes ! TIMESTAMP 1525094008.800 : Sleeping now - required for 9 seconds before sending the message. TIMESTAMP 1525094020.050 : Transmission successful : TYPE [5] : DATA [Temp:23.0C ]

First time you run this from the command line, you will most likely get an error - if that happens, just stop and rerun (once it's under cron these will be taken care of).

Add a cron job to start and keep alive

$ crontab -e

Add this line to the crontab (you can copy it from corella-cron.txt that you just downloaded)

# check to make sure this process is kept running even after powerdown * * * * * /bin/bash /home/pi/Desktop/corella/DHT11-keepalive.sh >> ~/Desktop/corella/DHT11-keepalive.log

Within a minute, you should see the keepalive log created from the cron job. You can monitor this to see that the process is working correctly.

$ tail -f DHT11-keepalive.log

Mon 30 Apr 13:30:01 UTC 2018 : Keepalive could not find running DHT11 : restarting TIMESTAMP 1525094762.798 : Serial connection is confirmed. TIMESTAMP 1525094763.818 : Device ID : 130067 TIMESTAMP 1525094764.876 : Device Type : TAGGLE CORELLA TIMESTAMP 1525094764.876 : CORELLA #130067 Hardware Version : REV_A TIMESTAMP 1525094764.876 : CORELLA #130067 Firmware Version : 1.0.31 Mon 30 Apr 13:31:01 UTC 2018 : Keepalive found running DHT11 : PID 2824 Mon 30 Apr 13:32:02 UTC 2018 : Keepalive found running DHT11 : PID 2824 Mon 30 Apr 13:33:02 UTC 2018 : Keepalive found running DHT11 : PID 2824 Mon 30 Apr 13:34:02 UTC 2018 : Keepalive found running DHT11 : PID 2824 Mon 30 Apr 13:35:02 UTC 2018 : Keepalive found running DHT11 : PID 2824

To stop the background script running, first comment out the cronjob
$ crontab -e

Then stop the currently running process -- you'll find the PID in the DHT11-keepalive.log
$ kill -9 2824


Power off ?

By having the python keepalive in cron, you can switch off your RPi, and it will start running again as soon as the RPi reboots. Just plug it into battery/power and it will start transmitting - no need for a monitor or keyboard!

No local internet ?

No problems. The Corella broadcasts via LPWA radio to the Taggle network, not via the internet.

Now that it's all set up, you can disconnect your RPi from ethernet.

As long as your Corella device is within range of a Taggle basestation, your data will be sent, and you can monitor it via the Corella Portal, or via MQTT with a dedicated /corella/ topic.


Viewing the MQTT data feed

Sign in to the Corella Data Portal.

portal-login

The raw messages are seen in near-real time.
The packet_type and payload parameters can be seen in the JSON data.

portal-2


Decoding and displaying your data

The data payloads that your Corella is sending are originally (in these examples) written as plain-text ASCII.

However, they are encoded to HEX for transmission.

The Corella Portal displays this raw HEX as the payoad (which technically it is), so it's up to you to decode the information
- which will be the "inverse" of how you encoded it in the first place.

Which means that the most obvious decoding, and the one we'll show you first, is hex-to-ascii.

A simple front-end decoder

When you downloaded and unpacked the examples.tar.gz, you created a folder called "frontend", containing 2 files

corella_mqtt.js is a simple javascript(+jQuery) library that allows you to easily

monitor.html is a standalone local HTML file that you can open in any browser.

It's specifically written to display the information that the DHT11.py script running on your RPi is sending.
It's also written to show you a few different ways to deal with the MQTT feeds - so you should play with it, make changes, and do magic.

You'll need to be connected to the internet, but you don't need to run monitor.html from a webserver.
You'll definitely need a Corella Portal login - where you will discover the configurations to make it run (for your device[s] only).

// ---------------------------------------------------------- // Taggle Corella Module and Portal credentials global // ---------------------------------------------------------- var corella_config = { 'rfid': 130067, 'name': "David's Atmospherics", 'portal_username': 'davo123', 'portal_password': 'xxxxxxx', 'local_history': 100, 'verbose': true };
Actually, that's all you neeed do - to start with.

monitor

Transmission credits

Your Corella device ships with credits for 10,000 transmissions on the Taggle IoT network.

After that, you'll need to pay to access more data -- so it's smart to do a few calculations before you leave it running.

The example code we've given you here is close to the practical limits (the Corella is throttled to transmit no more than every 10 seconds)

We're sending the same data in 3 different packets so you can see how to deal with it on the receiving end.

3 transmissions per minute 3 x 60 = 180 per hour 180 x 24 = 4,320 per day

Which means you'll burn through your credits in 2 or 3 days.

A more practical setup would only send one packet of encoded/compressed data every 10 minutes.

1 transmissions every 10 minutes = 6 per hour 6 x 24 = 144 per day

Which means you'll have a lot longer - about 2 months.

But maybe that's not going to give you the immediate feedback while you're debugging and developing new projects.

You need to find the right balance for your project/budget.

If you devise a way to collate/encode/compress data, you could send a daily summary in a series of maybe 10 packets (that's about 240 Bytes).

10 packets transmitted at midnight = 10 per day

Credits will last about 3 years.

Packet Types (a.k.a. Packet ID)

You specify a packet_type whenever you send data.

Use the packet_type to differentiate between data types.

If you desperately need to deal with more than 9 data types, or you're using the packet_type for a large number of individual sensors, you could consider using the first byte of your payload to further divide them... or whatever other scheme you can think of. It's your data, so you can deal with it however you want. The Taggle network is agnostic and simply passes the payloads from end to end.


About Taggle Systems

Taggle is an Australian based and owned developer of Low Power Wide Area (LPWA) radio technology offering low-cost, low-power, long range communications for many types of sensors and devices.

With a rapidly expanding international network, we service high-rise and urban centres, regional utilities, remote communities and farm monitoring. We work with our customers to deliver tailored solutions.

The Corella project enables experimentation, innovation, small-scale or specialized projects to be implemented without fuss or large investment.