Featured post

Store your TTN node data in a NoSQL database, then show it as a line graph on a webpage…

This blog post is all about building a Node.js server to retrieve your LoRaWAN device data from TheThingsNetwork (TTN), then store the data in a Mongo NoSQL database. The assumption is that you have built a Node.js app before. There is also a very simple client app that displays your data as a line graph on a webpage.

The Things Network (TTN) is an open-source, secure and scalable solution that has around 9,000 gateways and 90,000 developers around the world. It started in August 2015 and just keeps on growing.

TTN manages every aspect of creating and managing a LoRaWAN network except storing your data (note that TTN does offer a storage solution, but provides storage for 7 days only). Also note that there are several integrations available, including EVRYTHNG, AWS IoT, Cayenne and Tago.

The following example is useful if you want to keep your data in-house. Also, if you are like me, you want to understand and have control of the key components of your solution, even if you decide in the future to go with a 3rd-party.

This code runs as two separate Node.js applications on your laptop/desktop, but of course when moving to production, the collector app would need to run on a server and the viewer app is actually a web server that would also need to run continuously.

In addition to the code described below, you need:
Node.js – javascript server-side run-time environment – I used version 10.16.3 LTS
MongoDB – NoSQL database, ideal for json-formatted data – I used a free cloud instance, sign up here (no credit card required) https://www.mongodb.com/cloud/atlas – and of course an active LoRaWAN device, registered within an application configured in your own TTN console – https://console.thethingsnetwork.org/

You can find all the source code, together with the slidedeck I presented at TheThingsConference UK 2019, here:

https://github.com/nicbkw/thingsconf2019

I have split the code into collector and viewer folders. You need to fill out the connection details for your mongodb  instance and your TTN application name and access key (token). Use the config.template as a basis, update with your credentials and then place a copy, called config.js,  into each of the collector and viewer folders on your laptop/desktop.

First, let’s take a look at collector; this uses a Node.js SDK provided by TTN that listens for each new published record, then inserts a document into your database. You can see the code for this in collector.js – note that I have created a separate file, mongo.js, for mongodb connectivity, as this is common code for both collector and viewer.

A quick diversion to talk about nomenclature – both SQL and NoSQL databases use the term ‘database’ – but a ‘table’ in SQL is equivalent to a ‘collection’ in NoSQL and a ‘record’ in SQL is a ‘document’ in NoSQL. What I really like about NoSQL databases is that the underlying format is JSON.

You can check the data is being stored by installing mongodb compass, community edition – https://www.mongodb.com/download-center/compass

OK, so now that we have data in our database, let’s view it in a webpage as a line graph. The viewer folder holds a copy of config.js (note that this only needs to hold the credentials for the database) a copy of mongo.js for database connectivity, the application code in viewer.js and a sub-folder called views that holds index.hbs – a simplified html file.

The Node.js app actually runs the minimum form of express framework to host a simple web page. Our web page is served using ‘hbs’ as it’s default view engine (https://www.npmjs.com/package/hbs) and we use handlebar nomenclature {{JSON string}} to pass data arrays. So, take a look at viewer.js and see that we retrieve a number of documents from the database with ‘getArray’ and then push the relevant data into an array in ‘pushData’ to pass to the web page where we render it. We are going to plot the ‘rssi’ and ‘snr’ as seen by the first gateway to respond to your LoRaWAN device.

The file index.hbs contains the minimal html and javascript to display the data as two line graphs, using the Google charts libraries – more information here: https://developers.google.com/chart

So, in summary:
TTN provides an excellent platform to move your node data to the cloud
TTN enables simple data access with a Node.js SDK
MongoDB is a NoSQL db, good for JSON data
Node.js is a simple way to build a headless server app

Now, it’s down to you to do something useful with your LoRaWAN device!

k3s – kubernetes for IoT on Arm processors

I have been working with Docker for some time and run several network-linked containers on a ubuntu server, somewhere in Amsterdam. I am running a pilot project, requiring a single container for each function and so just script the build and connection with docker-compose – here is an example of docker-compose.yml for a project that runs nginx, wordpress, mysql and Node.js

version: '3.7'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
      - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:mainline-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - ../certs/:/etc/nginx/certs/
    networks:
      - app-network

  nodeapi:
    build:
      context: ./nodeapi
      dockerfile: Dockerfile
    image: nodeapi
    container_name: nodeapi
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - ./nodeapi:/usr/src/app
    networks:
      - app-network

volumes:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge  

The next step would be to scale on-demand and make the solution resilient by spreading the containers across multiple machines. This is what kubernetes is designed to do, and it’s about time I learnt more…

So, to build a simple kubernetes multiple machine cluster, I could have spun up multiple x86 VMs or cloud servers – but i was fascinated by an article from Alex Ellis – https://blog.alexellis.io/test-drive-k3s-on-raspberry-pi/ – it introduced me to a stripped down version of kubernetes that can run in a restrained environment and on Arm.

I looked around my home office and found a pair of NanoPi Neo2 from FriendlyArm – 4 x A53 core AllWinner CPU, 512MB RAM, Gigabit Ethernet – and this, rather unusual offering from globalscale, that I bought from a KickStarter promotion – the espressobin that features 3 Gigabit Ethernet ports, SATA and 1 mini PCIe with 1GB RAM and 2 x A53 core Marvell CPU.

To keep everything stable and provide a heatsink of sorts, I mounted the SBCs on a spare piece of ACM Aluminium Composite Sheet

I installed the current version of Armbian, based on Debian Buster, as a stable ARM64 linux distribution. All 3 are running off 16GB micro SD cards. The default install for the espresso configures Ethernet ports 1 and 2 as LAN, 3 as WAN, so plugging cables between it and the NanoPi just works!

Armbian comes with armbian-config that makes it easy to check for updates, change hostname, etc. I added my default ssh key to each SBC from my Mac using the following command:

ssh-copy-id <username>@<SBC_URL>

Following the the blog I mentioned earlier, the k3s master install on the espresso SBC was simply:

curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v0.9.1 sh -

Note that I had to install a specific version as the current build failed with an error – something you get used to when pulling the latest version of code from an early stage linux app. This should ask for your sudo password (you’re not installing as root, are you?) and then install a whole raft of essential tech, including TLS certs, Traefik and Helm – look at k3s.io for more detail. Next, copy the K3S_TOKEN to your clipboard using:

sudo cat /var/lib/rancher/k3s/server/node-token

Now, on each NanoPi, create two environment variables, K3S_URL and K3S_TOKEN, then run the same curl script as before. This time, it will install the k3s worker code:

export K3S_URL="https://espresso.home:6443"
export K3S_TOKEN="<the K3S_TOKEN is that you copied from the master>"
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v0.9.1 sh -

Move back to your espresso client and try the following command – note that it took a few seconds for the workers to attain ‘Ready’ status

sudo kubectl get nodes -o wide
[sudo] password for <username>:
NAME         STATUS   ROLES    AGE     VERSION         INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                       KERNEL-VERSION    CONTAINER-RUNTIME
k3slave001   Ready    worker   5h25m   v1.15.4-k3s.1   192.168.1.83    <none>        Debian GNU/Linux 10 (buster)   4.19.63-sunxi64   containerd://1.2.8-k3s.1
k3slave002   Ready    worker   4h45m   v1.15.4-k3s.1   192.168.1.85    <none>        Debian GNU/Linux 10 (buster)   4.19.63-sunxi64   containerd://1.2.8-k3s.1
espresso     Ready    master   2d19h   v1.15.4-k3s.1   192.168.1.252   <none>        Debian GNU/Linux 10 (buster)   4.19.59-mvebu64   containerd://1.2.8-k3s.1

Alex Ellis is the developer behind openfaas and as such, provides a simple example in the blog post that enables us to test the k3s cluster we have just created. So, just follow the section in that blog, entitled ‘Deploy a Microservice’ and you should see something like this

So, that’s it. try k3s with any available Arm-based SBCs you may have to hand – make it easy for yourself by running Armbian on each. I intend to write a subsequent post, showing some of the automated app deployment, scalability and resilience made possible even out to the IoT computing edge of your solution – happy coding!

Yet another linux on Chromebook post…

I have written about crouton that provides chroot installs of popular linux distributions like ubuntu, debian and kali. I followed that up by installing the official linux on Chromebook offering.

Now I just have to tell you about my new favourite solution – chromebrew

The reason I like chromebrew is that it simply extends chromeos to run like any other linux distribution – “…Chromebooks with Chrome OS run a Linux kernel. The only missing pieces to use them as full-featured Linux distro were gcc and make with their dependencies. Well, these pieces aren’t missing anymore…”

The biggest advantage with chromebrew is that it takes so little space, which is a limited quantity on most Chromebooks. It also has a good package manager, crew.

With crew, it is easy to add the apps you need, try ‘crew install nano’. Package installer scripts are written in ruby and support aarch64, arm7l, i686 & x86_64 processor architectures.Check out crew packages

Have fun!

Quick & dirty antenna comparison for LoRaWAN

One problem working  with LPWAN is having confidence that the antenna you just bought is effective.  From my experience, it is not reasonable to expect similar-looking antennae to be equally efficient, or even tuned for the same frequency band.

I decided to make a quick comparison of 6 antennae I had acquired over time from various suppliers. The method shown below is intended to simply identify the resonant frequency(ies) of each. The idea of the test rig is that the RF bridge enables matched connection of a white noise source, receiver (RTL-SDR) and the antenna under test. The RTL-SDR scans a suitable frequency band and the signal strength is plotted against frequency. The picture shows the 6 samples numbered 1 to 6 from left to right.

I based this test on the following article: – https://www.rtl-sdr.com/rtl-sdr-tutorial-measuring-filter-characteristics-and-antenna-vswr-with-an-rtl-sdr-and-noise-source/

The RF bridge and noise source can be bought cheaply from ebay –  as of posting, UK item numbers 232943112992 and 202335272932. The 50ohm terminator came from my parts bin, a relic from the days of ethernet over coax (10base2)…

The idea of the test is first to scan the the rig with no antenna connected. The 50ohm terminator ensures a matched circuit. I chose to scan from 50MHz to 1.5GHz in 1MHz steps and stored the signal strength  for each step as the baseline column in a Google spreadsheet – please don’t try this in Excel as manipulating so many values in a single spreadsheet will grind to a halt on a Windows PC.

Now each antenna is attached in turn and the scan repeated, giving columns Antenna1 to Antenna6. Next, each frequency step’s baseline value is subtracted from each Antenna’s corresponding signal strength. This results in  a lot of data that effectively indicates the resonant frequency(ies) of each antenna – as shown by the overlaid plots.

So, as an indication, it can be seen that Antenna1 (brown trace) is well-tuned for the European LoRaWAN band, whereas Antenna6 (pink trace) is pretty useless.

Note that this test cannot be used alone to determine best antenna, which would require real field trials, monitoring actual RSSI and SNR at a distance from an installed node/antenna. Resonant frequency, for example can be detuned by the node’s enclosure, mounting and/or large metal objects, such as batteries. An effective ground plane will dramatically improve both receive and transmission characteristics.

However, this test does give a quick comparison in the lab and can lead you to reduce the number of antennae used in field trials.

Running Docker on a docker-based OS

I have been following  RancherOS for quite some time, but somehow never got past just running the example as a VM. However, I have now installed on bare-metal and I have to say that it is a revelation.

To understand the basics, please take time to read the page and watch the video  https://rancher.com/rancher-os

The ISO is less than 100MB and there are versions for both Intel and ARM-based platforms and I set mine up on nothing fancy (a HP Compaq 8200 ultra-slim desktop with Core i3 and 8GB RAM). It took around 30 minutes to have running the current CE version of docker, together with a ubuntu console (more of which, later).

So, the idea is to boot off the ISO, install to hard drive and then access remotely via ssh – so I can hide the ancient HP box under my desk.

First, create a config file containing the public part of an ssh-key, something similar to this, taking care to indent the 2nd line

cloud-config.yml

#cloud-config
  ssh_authorized_keys:
  - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6KLZr...PT9I2rVkySlT7UmiFl rancher@rancher.local

Note: If you don’t yet have an ssh key-pair, take a look at this document: generate an ssh key-pair

Now, make your cloud-config.yml available via an HTTP server on your local network. A quick way to do this is in python:


python -m SimpleHTTPServer

This runs a simple HTTP server on port 8000, by default.

So, now switch to your target machine and boot from the Rancher OS ISO, available here: https://github.com/rancher/os

While booting, start reading this: https://rancher.com/docs/os/v1.x/en/

You will see that Rancher have provided a very useful tool, called ros

So to install Rancher OS, is as easy as


sudo ros install -c http://[your-server-IP]:8000/cloud-config.yml -d /dev/sda

A word of caution – this didn’t work for me the first couple of times I tried it; the problem was the layout of the .yml file. Rancher must have seen this before, because they provide a yml file validator.
So, pull the .yml file to your local shell with:


wget http://[your-server-IP]:8000/cloud-config.yml

and run


sudo ros config validate -i cloud-config.yml

OK, so run the install command as above, answer yes when asked and Rancher OS will be installed to your hard drive.

Congratulations! You now have the bare minimum of OS on which to run your docker containers.

But wait – Rancher OS can be made even more useful by swapping out the default busybox console:

First, find out what consoles are available on your hardware:


$ sudo ros console list
disabled alpine
disabled centos
disabled debian
current  default
disabled fedora
disabled ubuntu

Then install your favourite – it’s just a docker container:

sudo ros console switch ubuntu

This action will drop your ssh connection, so log in again and go have some docker-based fun…

Technical overview of LoRa, LoRaWAN and The Things Network

The Radio Spectrum

Radio-connected devices work within a certain frequency range. The radio spectrum is allocated by government and licensed for specific functions.

For example, broadcast radio currently has a reserved VHF band from 88 to 108 MHz.

Cellular phones have several reserved frequency bands around 900 MHz and 1800 MHz.

The licensees pay for use within these bands. However, there are some specific bands that are made available for low power use, license-free.

2.4GHz is a global band that allows low power unlicensed operation; this is where WiFi and Bluetooth co-exist.

Some license-free bands are allocated differently by each country and LoRa is designed to work in the appropriate band for each country or region. For example, Europe is covered by 863-870MHz, North America, Canada & South America by 902-928MHz. TTN provide details of global frequency plans – https://www.thethingsnetwork.org/docs/lorawan/frequency-plans.html

LoRa radio technology

LoRa is a technology that works well within a crowded radio spectrum.

It uses a technique called chirp spread spectrum that creates a signal which is distinguishable by the receiver from the atmospheric noise and signals created by other devices that use simpler modulation techniques, such as On Off Keying (OOK) and Frequency Shift Keying (FSK).

LoRa also takes advantage of a feature called Spreading Factor (SF) where the spreading factors are the duration of the chirp. LoRa operates with SF7-12. SF7 is the shortest time on air, SF12 the longest. Each step up in spreading factor doubles the time on air to transmit the same amount of data.

With the same bandwidth, longer time on air obviously results in less data transmitted per unit of time.

So, with very little output power, the LoRa signal can be detected at great distance or through infrastructure that attenuates the signal. Typically, this could be 1-3km in an urban environment. The current record distance is just over 700km from a node under a helium balloon at a height of 40km, at an output power of only 25mw. For comparison your car key fob works at 2mw for a couple of metres and your phone at up to 1W to the nearest cellphone mast, at most 30km distant.

The trade-off for LoRa is that low power and long distance is traded for limited data rate. Maximum data rate at SF7 is 6kbits/s, reducing to 300bits/s at SF12. One key figure RF engineers discuss is “link budget”, bigger is better and Spreading Factor affects the number where SF12 gives the best chance to receive data. For more information – https://www.semtech.com/uploads/documents/an1200.22.pdf

There are payload size limitations for LoRa – in EU it’s 230 bytes per transmission at SF7, 59 bytes at SF12. Consider LoRa only for telemetry data, such as location, heading, height, temperature, pressure and humidity values or simple on-off actions.

The LoRaWAN protocol

LoRaWAN is a communication protocol that runs on LoRa hardware.

LoRaWAN operates in a star of stars network with ability for multiple gateways to receive and forward data from any nearby node to The Things Network.

Each multi-channel LoRaWAN gateway can scan 8 channels simultaneously and decode up to 8 data packets at the same time. Several packets using different data rates may be demodulated simultaneously even on the same channel.

LoRaWAN provides several modes of operation – modes A, B & C, where B is allocated a time slot and C devices are permanently powered on and receiving.

Most nodes run as mode A devices where they occasionally wake up to transmit a small amount of data and listen for a short time after transmission for any received data. Working like this, it is possible to construct a node that can transmit an update every 30 minutes and run off 2 ‘C’-size alkaline batteries for more than 5 years.

Each mode A node is free to transmit at any time, with the limitation in Europe that each node should not exceed a 1% duty cycle.

There are predictive formulae available to show that the combination of multi-channel gateways, small data packets, operational modes and Spreading Factors results in the capability to handle thousands of nodes per gateway. See “Understanding the Limits of LoRaWAN (Adelantado, Vilajosana et al, IEEE magazine January 2017)” – https://arxiv.org/pdf/1607.08011.pdf

The Things Network originally provided complete LoRaWAN coverage for the city of Amsterdam with just 10 gateways – https://www.thethingsnetwork.org/community/amsterdam/

The Things Network

The Things Network is an open-source, free-to-use solution that provides all functions necessary to:

  • Register a gateway
  • Register a node
  • Handle encryption and decryption of payload data.
  • Route the data between node and the internet using MQTT-broker technology.
  • Queue data for transmission to each node.
  • Monitor and action the process through API

The Things Network does all this and more on a scalable, resilient platform with regional bridge access globally.

https://www.thethingsnetwork.org/docs/network/architecture.html

The Things Network is provided as open-source solution by The Things Industries. Gateways are being made available worldwide by The Things Network community – see https://www.thethingsnetwork.org/community and try it for yourself! it costs less than £200 to setup your own.

The Things Industries also deliver private LoRaWAN solutions with guaranteed SLA, so be assured that you can develop a solution and build it out to a stable product.

For more information, please get in touch – take a look at https://thinnovation.com/remon.html

Linux on Chromebook just became extremely simple…


My previous post “My new go-to linux dev machine is a Chromebook…” seems now to be obsolete. Google have released a “linux mode” in Chrome version 69 for Chrome OS. This is the project “crostini” that was first made available on the Pixelbook.

There are a couple of gotchas, such as it is only beta so far and is only supported on certain Chromebooks – see here for more information: linux mode capable chromebooks – note it says that Chromebooks like the HP 14 G3 running 32-bit ARM and others using Baytrail x86 CPU devices will never support linux mode.

Luckily, my ASUS Chromebook Flip C101PA is on the list. So, no need to reset and set developer mode, just simply select Settings -> Linux(Beta) and go for lunch – this is definitely more than a coffee install.

You will see a new app on your Chromebook – “Terminal”. The username and password are those of your Google account – so, launching Terminal, I see a prompt of “nicbkw@penguin:~$”. Click  (touch & hold) on the Terminal icon in the appfinder and you have the options to uninstall and shutdown Linux(Beta). Clicking on the launched Terminal icon, you will see the option to open new windows, meaning it is possible to run multiple terminal session windows as well as browser and your other chromebook apps.

The distribution is debian stretch and installing apps is as simple as “sudo apt-get install gimp”. The GUI runs natively in the Chrome OS environment and this linux app appears alongside other ordinary Chrome OS/Android apps – see the header image.

The linux virtual machine, together with any data you store while using it persists between sessions, so you can quit apps, logout, etc without worrying about resetting anything. All data is stored in the same encrypted storage as other Chrome OS data.

My new go-to linux dev machine is a Chromebook…


The other day I arrived at work to discover I had left my laptop at home. I hot-desk some days each week in Liverpool in fabulous SensorCity (@SensorCityUK) and was lost without a keyboard and ability to geek. Fortunately, just 5 minutes walk away is the local branch of a well-known UK “previously-loved” chain, so I went for a meander. I returned with an ASUS C101PA ChromeBook for less than half-price. It has a 10.1″ 1200×800 touchscreen with 6-core ARM CPU, 4GB RAM, 16GB eMMC, USB-C charging and a 9-hour battery – what should a geek do???

The answer is to enable Chrome Developer mode and install xenial ubuntu, of course – note that you should backup before enabling as this will factory reset your chromebook and delete all your data. Warning over.

It is possible to run a full linux desktop (something lightweight, like xfce, bearing in mind the free space on the eMMC), but I like working with a command line and you will see that you end up with linux running in one or more Chrome Tabs, while retaining full access to the Chrome/Android side of things – browser, email, 6Music on BBC Radio iPlayer, etc.

So, The best instructions are those available from the master – take a look at https://github.com/dnschneid/crouton

Here are the basics:

1. Enable developer mode – https://www.howtogeek.com/210817/how-to-enable-developer-mode-on-your-chromebook/
2. Download the current version of crouton from here – crouton
3. Open a shell (Ctrl+Alt+T, type shell and hit enter)
4. Run sudo sh ~/Downloads/crouton -t core – wait patiently and answer the prompts to add user, etc.
5. Done! Run sudo enter-chroot

The result is an arm64 install of ubuntu xenial that has access to serial over USB, USB and SD card storage

So far, I have:

1. mbed-cli to build and flash code to STMicro Nucleo boards – this installed build-essential, git, python, etc.
2. go version go1.10.3

I am very impressed. So, don’t dismiss chromebooks as over-sized androids, poor iPad substitutes, especially if you can pick up a bargain…

STMicro DISCO-L072CZ-LRWAN1 quickstart with mbed-os

There is a great article on the ARM mbed website about their support of LoRaWAN.
https://os.mbed.com/blog/entry/Adding-a-LoRaWAN-stack-to-Mbed-OS-58/

Their code has improved a lot this year. Previously, it was a little tricky to work with – there is now a clean install available on github that can be built locally from the command line on Mac, Windows or linux. using the GNU ARM embedded toolchain and mbed-os.

I describe below a simple recipe to use this code with the STMicro DISCO-L072CZ-LRWAN1 evaluation board (pictured). The code can be simply adapted to run with the sx1272 mbed shield on STMicro Nucleo boards and there is also support for the RAKWireless RAK811 node.

I am assuming that you have already registered your device in your application in your TTN console:
https://console.thethingsnetwork.org/applications/[your application name]/devices

1. Setup the GNU ARM embedded toolchain and install mbed-cli:

On a Windows 10 PC – just use the installer that you can download from here:
mbed-cli installer

The Windows installer for Mbed CLI includes the following components:

  • Python – Mbed CLI is a Python script, so you need Python to use it. The installer installs version 2.7.13 of Python. It is not compatible with Python 3
  • Mbed CLI version 1.2.2 – Mbed CLI
  • Git and Mercurial – Mbed CLI supports both Git and Mercurial repositories. Both Git and Mercurial are being installed. git and hg are added to system’s PATH
  • GNU Arm Embedded Toolchain – GNU Embedded Toolchain for Arm
  • Mbed Windows serial port driver – serial port driver

Note that the Windows installer sets all paths and even configures some MBED variables
Check the path to the gcc compiler:
mbed config -L

On a Mac – use homebrew – remember to brew update && brew upgrade before installing
If you need to install homebrew first, then
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Otherwise, just:

brew tap ArmMbed/homebrew-formulae
brew install arm-none-eabi-gcc
brew install python@2
brew install mercurial
brew install git
git clone https://github.com/ARMmbed/mbed-cli
cd mbed-cli
python setup.py install

Check the version of mbed-cli and that it is installed OK – version should be =>1.8.2
mbed-cli --version
Check the install location of arm-none-eabi-gcc with
which arm-none-eabi-gcc
Set path for mbed
mbed config -G GCC_ARM_PATH "/usr/local/bin"

On a linux machine, here is a typical install (I used ubuntu xenial)

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa
sudo apt-get update
sudo apt-get install gcc-arm-embedded
sudo apt-get install build-essential libssl-dev libffi-dev libxml2-dev libxslt1-dev
sudo apt-get install mercurial git python-dev python-pip
pip install mbed-cli
mbed-cli --version
which arm-none-eabi-gcc
mbed config -G GCC_ARM_PATH "/usr/bin"

2. Pull the example code from the mbed github and create the local mbed-os environment in the folder, using mbed-cli (note that ‘mbed-cli’ also works using just ‘mbed’)

mbed import mbed-os-example-lorawan
cd mbed-os-example-lorawan/

3. Configure for your node
edit mbed_app.json to configure lora.device-eui, lora.application-eui, lora.application-key

4. compile and send to evaluation board (assumes there is only one ST-Link/Nucleo/DISCO board connected)
mbed compile -m DISCO_L072CZ_LRWAN1 -t GCC_ARM --flash

5. use mbed as your terminal emulator:
mbed sterm --baudrate 115200

Note that on linux, it may be necessary to change user permissions for the serial port, similar to:
sudo chmod 666 /dev/ttyACM0

6. press the black reset button on the DISCO board
You should see this:

 Mbed LoRaWANStack initialized
 CONFIRMED message retries : 3
 Adaptive data  rate (ADR) - Enabled
 Connection - In Progress ...

After a few seconds, this should appear:

 Connection - Successful
 Dummy Sensor Value = 2.1
 25 bytes scheduled for transmission
 Message Sent to Network Server

Any questions? Please get in touch…

Using node-red with ST NUCLEO L073RZ Sx1272

I have been working with the great LoRaWAN combo from STMicroelectronics – a low-cost dev board based on a ARM®32-bit Cortex®-M0+ CPU, coupled with the Sx1272 on an Arduino-compatible shield.

Using the online mbed compiler – https://developer.mbed.org/compiler/ , I modded the demo code – LoRaWAN-demo-72 – to add simple output to an OLED display – see attached photo.

My node-red install runs on a server hosted by https://www.scaleway.com/ that costs around €3/month. I designed a very simple activity monitor – the design of which may help others.

To the basic node-red install, I added node-red-contrib-ttn and node-red-dashboard.

file

The dashboard output looks like this:

file

Here is the node-red code:

[{"id":"cd89d617.a9d0e8","type":"function","z":"546def68.3e374","name":"Extract data","func":"count = {}\nrssi = {}\nsnr = {}\n\n//var b = new Buffer(msg.payload_raw);\n//count.payload = (b[1] << 8 | b[2]).toString();\n//var r = b[3] << 8 | b[4];\n//if ((r & 0x8000) > 0) {\n// r = r - 0x10000;\n//}\n//rssi.payload = r.toString();\n//snr.payload = (b[5]).toString();\n\ncount.payload = msg.counter;\n\nrssi.payload = msg.metadata.gateways[0].rssi;\nsnr.payload = msg.metadata.gateways[0].snr;\n\nreturn [count, rssi, snr];","outputs":"3","noerr":0,"x":230,"y":280,"wires":[["6de8dcb1.29b284"],["72787db7.d4bdf4","a262c4ea.068798"],["21f1441a.e028fc","e6796eca.3e2ec"]]},{"id":"6de8dcb1.29b284","type":"ui_text","z":"546def68.3e374","group":"3d90cd90.e1c9c2","order":7,"width":0,"height":0,"name":"txtCount","label":"Count","format":"{{msg.payload}}","layout":"row-spread","x":440,"y":220,"wires":[]},{"id":"72787db7.d4bdf4","type":"ui_text","z":"546def68.3e374","group":"3d90cd90.e1c9c2","order":5,"width":0,"height":0,"name":"txtRssi","label":"RSSI","format":"{{msg.payload}}","layout":"row-spread","x":430,"y":260,"wires":[]},{"id":"21f1441a.e028fc","type":"ui_text","z":"546def68.3e374","group":"3d90cd90.e1c9c2","order":6,"width":0,"height":0,"name":"txtSnr","label":"SNR","format":"{{msg.payload}}","layout":"row-spread","x":430,"y":340,"wires":[]},{"id":"69c26716.6f6598","type":"ui_text","z":"546def68.3e374","group":"3d90cd90.e1c9c2","order":1,"width":0,"height":0,"name":"txtDevice","label":"Device","format":"{{msg.dev_id}}","layout":"row-spread","x":440,"y":60,"wires":[]},{"id":"89e50c80.55a11","type":"ui_text","z":"546def68.3e374","group":"3d90cd90.e1c9c2","order":3,"width":0,"height":0,"name":"txtDataRate","label":"Data Rate","format":"{{msg.metadata.data_rate}}","layout":"row-spread","x":450,"y":140,"wires":[]},{"id":"d312c0a6.afb48","type":"ui_text","z":"546def68.3e374","group":"3d90cd90.e1c9c2","order":4,"width":0,"height":0,"name":"txtCodingRate","label":"Coding Rate","format":"{{msg.metadata.coding_rate}}","layout":"row-spread","x":460,"y":180,"wires":[]},{"id":"2065149f.497fbc","type":"ui_text","z":"546def68.3e374","group":"3d90cd90.e1c9c2","order":2,"width":0,"height":0,"name":"txtFrequency","label":"Freq.","format":"{{msg.metadata.frequency}}","layout":"row-spread","x":450,"y":100,"wires":[]},{"id":"a262c4ea.068798","type":"ui_chart","z":"546def68.3e374","name":"","group":"3d90cd90.e1c9c2","order":8,"width":0,"height":0,"label":"Signal Strength","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"-150","ymax":"0","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":true,"x":460,"y":300,"wires":[[],[]]},{"id":"e6796eca.3e2ec","type":"ui_chart","z":"546def68.3e374","name":"SNR","group":"3d90cd90.e1c9c2","order":9,"width":0,"height":0,"label":"Signal:Noise Ratio","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"10","removeOlder":1,"removeOlderPoints":"500","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":true,"x":430,"y":380,"wires":[[],[]]},{"id":"7819848e.fd117c","type":"ttn uplink","z":"546def68.3e374","name":"unosx1272","app":"c7f29eb8.f2f1f","dev_id":"unosx1272","field":"","x":120,"y":60,"wires":[["cd89d617.a9d0e8","69c26716.6f6598","2065149f.497fbc","89e50c80.55a11","d312c0a6.afb48"]]},{"id":"3d90cd90.e1c9c2","type":"ui_group","z":"546def68.3e374","name":"unosx1272","tab":"a104b487.87dca8","order":2,"disp":true,"width":"6","collapse":false},{"id":"c7f29eb8.f2f1f","type":"ttn app","z":"","appId":"<app-id>","accessKey":"<app-key>","discovery":"discovery.thethingsnetwork.org:1900"},{"id":"a104b487.87dca8","type":"ui_tab","z":"546def68.3e374","name":"devices","icon":"dashboard"}]