Success with LoRa workshop in Trondheim

On Monday 23rd May we organized a LoRa workshop at DIGS. About 20 participants joined the meetup.

The purpose of this 2-hour workshop was to get hands-on experience with using the LoRa network in Trondheim. LoRa is a new radio standard for connecting things to the internet. Its features are long range and low battery. It is useful to power the internet of things.

We had two visitors from Semtech:

Bernt-Olov gave us a small tour of his company and their products.

One interesting fact from Bernt regarding LoRa is that it is very resilient to jammers. The reason is because LoRa uses spread-spectrum techniques in which a particular bandwidth is deliberately spread in the frequency domain.

semtech-bern

We put together a guide over at a Github repository, for the participants to follow: https://github.com/TradloseTrondheim/lora-workshop

At least two groups were able to send data to the network and then fetch it with an MQTT client.

Others struggled with related technological issues.

lora-workshop-digs

In all, a very successful workshop. It feels good to be working with bleeding edge technology.

The natural next step after mastering this technology is to identify areas that can profit from it.

Examples:

  • Measuring air quality
  • Automatic measuring of garbage cans levels
  • Antibike theft
  • Anticar theft
  • Optimized road usage
  • Monitoring of parking spaces
  • Monitoring vibrations in buildings
  • Monitoring traffic congestion. Increase price when it becomes congested.
  • Detecting fire/temperature levels.
  • Measuring radiation levels
  • Animal tracking
  • Home intrusion detection systems

LoRaWAN gateways up and running in Trondheim

lora-logo-transp-400x231

For a few months we have had two lora gateways up and running in Trondheim. One on the roof of olavskvartalet. Its gateway_ID is AA555A0008060353.

Another one is located on the roof of samfundet. Its gateway_ID is AA555A0008060252.
They are both forwarding data packets to The Things Network.

LoRaWAN is a Low Power Wide Area Network (LPWAN) specification intended for wireless battery operated Things. The intention is to provide infrastructure for the internet of things. More and more devices will be connected to the internet.

The gateways are publicly accessible. This means they will accept all packets and ship them off to The Things Network. To grab the data you use the http api.

To understand the data flow and architecture, visit the The Things Network wiki.

Two NTNU students are already using our lora network to measure co2 emissions in Elgeseter gate.

Feel free to contact us at hei@tradlosetrondheim.no if you find this interesting!

Let’s setup MultiConnect Conduit

multiconnect-conduit

The following guide assumes you have basic computer and basic linux knowledge. Hardware required:

  • MTCDT-210L-US-EU-GB Multitech mLinux Conduit (non-cellular)
  • MTAC-LORA-868 accessory card

For console access I plugged into the USB device port behind the device.
To access the device I use minicom(1):

minicom -D /dev/ttyACM0 -b 9600

This gives me the following:

            _     _                  
  _ __ ___ | |   (_)_ __  _   ___  __
 | '_ ` _ \| |   | | '_ \| | | \ \/ /
 | | | | | | |___| | | | | |_| |>  < 
 |_| |_| |_|_____|_|_| |_|\__,_/_/\_\
                                     
MultiTech Systems mLinux GNU/Linux
mLinux 3.1.0 mtcdt /dev/ttyGS0

mtcdt login: 

The username and password is root and root. That should be changed immediately.
I use openssl to produce a password with sufficient entropy:

openssl rand -base64 16

A new root password is set with passwd(1).

The mLinux distribution is based upon busybox, which is a minimal linux environment.

The distro version can be shown with:

cat /etc/mlinux-version

For me it displayed:

cat /etc/mlinux-version
mLinux 3.1.0
Built from branch: (detachedfrom4fd069b)
Revision: 4fd069b97a2354995920b52f731d661f0bacb39a

Network

mLinux has a static IP 192.168.2.1 as defined in /etc/network/interfaces.
A DHCP client is not enabled.

Instead of setting a static IP adress, use DHCP instead. Add the following to /etc/network/interfaces:

auto eth0             
iface eth0 inet dhcp

For changes to take effect issue:

ifdown eth0 && ifup eth0

This gives output:

udhcpc (v1.22.1) started
Sending discover...
Sending discover...
Sending select for 10.9.12.234...
Lease of 10.9.12.234 obtained, lease time 36000
/etc/udhcpc.d/50default: Adding DNS 10.9.0.11
/etc/udhcpc.d/50default: Adding DNS 10.9.0.10

Udhcpc is a very small DHCP client program geared towards embedded systems. If you have control over the DHCP server you can consistently offer a same ip by configuring the MAC address of the device.

Date and time

Set correct timezone:

ln -fs /usr/share/zoneinfo/Europe/Oslo /etc/localtime

Set date and time:

date "2016-03-07 11:17:40"

Update the hardware clock:

hwclock -u -w

Configuring packet forwarder

The lora network server is used if you want to run your own cloud. Since we are using the things network we only really need the packet forwarder to be running.

People have reported that the poly pkt forwarder works better than the basic pkt forwarder. Fetch the poly-packet-forwarder_2.1-r1. Install with:

opkg install poly-packet-forwarder_2.1-r1_arm926ejste.ipk

Change /etc/init.d/lora-network-server so that the variable pkt_fwd
is assigned pkt_fwd=/opt/lora/poly_pkt_fwd

Inside /var/config/lora/global_conf.json you have to add some changes. Here are a few of mine:

"gateway_ID": "008000000000A447",
...
"servers":
        [ { "server_address": "croft.thethings.girovito.nl",
            "serv_port_up": 1700,
            "serv_port_down": 1700,
            "serv_enabled": true }
        ],
...
"fake_gps": true,
 "ref_latitude": 63.43,
 "ref_longitude": 10.40,
...
/* Email of gateway operator, max 40 chars*/
"contact_email": "drift@tradlosetrondheim.no", 
/* Public description of this device, max 64 chars */
"description": "This is wireless trondheims multiconnect conduit number 1" 

Restart network server:

/etc/init.d/lora-network-server restart

Tail log for debug info:

tail -f /var/log/lora-pkt-fwd.log

My gateway is now available at The Things Network.

Data fetching and visualization using d3.js

complex-664440_1280

Data fetching is the process of grabbing data from a data source. In our lora network, packets are shipped off to The Things Network API.

On the web, javascript is what we got for doing computation in a browser. Ajax is a set of techniques used on the client-side to create asynchronous web applications.

ALSO READ: Temperature monitoring with lora

To fetch resources asynchronously, utilize the XMLHttpRequest object:

var trtHttp = (function (my) {
    var http = new XMLHttpRequest();

    my.getJson = function (url, cb) {
        http.onreadystatechange = function () {
            if (http.readyState === XMLHttpRequest.DONE) {
                if (http.status === 200) {
                    cb(JSON.parse(http.responseText));
                }
            }
        };

        http.open("GET", url, true);
        http.send();
    }

    return my;
}(trtHttp || {}));

The wrapping of getJson inside trtHttp is a javascript way of namespacing functions.
With this pattern, member functions of trtHttp can be spread out in different files.

Fetch data from our temperature sensor:

var url = 'http://thethingsnetwork.org/api/v0/nodes/02031003/?limit=200&format=json';

trtHttp.getJson(url, function (data) {
    console.log(data);
});

If you don’t feel the need for going this lowlevel, you can use jQuery:

$.getJSON(url, function (data) {
    console.log(data);
});

This achieve the same thing.

ALSO READ: Sending text with lorawan towards the things network

Data visualization

D3.js is a javaScript library for manipulating documents based on data. Let’s create a bar chart from a dataset containing integers between 0 and 10.

barchart-integers-2

var data = [1,2,3,4,5,6,7,8,9]

var margin = {
    bottom: 10,
    top: 10,
    left: 50,
    right: 20
};

var width = 500;
var height = 300;

var chartWidth = width - margin.left - margin.right;
var chartHeight = height - margin.top - margin.bottom;

var yScale = d3.scale.linear()
    .domain([0, 10])
    .range([chartHeight, margin.bottom + margin.top])

var yAxis = d3.svg.axis()
    .scale(yScale)
    .orient('left');

var svg = d3.select('body')
    .append('svg')
    .attr('width', width)
    .attr('height', height)

var chart = svg.append('g')
    .attr('width', chartWidth)
    .attr('height', chartHeight)
    .attr('transform', "translate(" + margin.left + ",0)")

svg.append('g')
    .attr('transform', "translate(30,0)")
    .attr("class","axis")
    .call(yAxis)

chart.selectAll('rect')
    .data(data)
    .enter()
    .append('rect')
    .attr('fill', function (d) {
        return "rgb(0, 0, " + (d * 30) + ")";
    })

    .attr('x', function (d, i) {
        return i * chartWidth / data.length
    })

    .attr('y', function (d) {
        return yScale(d);
    })

    .attr('width', chartWidth / data.length-1)

    .attr('height', function (d) {
        return yScale(0) - yScale(d);
    })

To fit our data of integers onto an svg we need to convert the integer range [0, 10] to [0, 300]. This is needed because otherwise the bars would be very small since the height of the svg is 300 pixels.
The d3.scale function performs the conversion. We need only provide it with an input domain and an output range.

To use the data from our temperature node, we simply wrap the code inside a json data fetch block:

trtHttp.getJson(url, function (data) {

    var data = data.map(function (item) {
        return item.data_json;
    })

    [...]
})

The temperature node location is in our office right now, so temperature values vary between 22 and 23 celcius.
The graph is not particurlarly exciting. Here it is:

barchart-temperatures