Arduino communicatie met een RN2483 LoRaWAN module aan The Things Network

Ik heb vandaag geprobeerd een RN2483 LoRaWAN module met een Arduino aan de praat te krijgen. Het parsen van de communicatie van en naar de mdule ging niet gemakkelijk: de RN2483 module heeft soms een precieze timing, variaties in de antwoorden en de TheThingsNetwork.h bibliotheek is op de meeste combinaties van Arduino’s en uitbreidingen niet te gebruiken (Arduino Diecimila bijvoorbeeld, of Arduino Leonardo met Xbee Shield). En als je moeite hebt om het werkend te krijgen dan heb je met TheThingsNetwork.h als abstractielaag vervolgens ook geen idee wat er verkeerd gaat. Met een terminal daarentegen is het vrij gemakkelijk om een RN2486 met The Things Network aan de gang te krijgen:

> sys reset
RN2486...
> mac join otaa
ok
accepted
> mac tx cnf 1 1234
ok
mac_tx_ok

Bovenstaande instructies is genoeg om data te versturen. Ik heb vandaag daarom een paar uur besteed om de abstractielaag weg te poetsen en de module direct via de seriële Arduino poort aan te sturen.

// Routine that uses the SoftwareSerial library to communicatie
// with an RN2483 LoRaWAN module
// Apart from SoftwareSerial there is no abstraction layer, thus
// all steps and code are visible.
// Note: although this code does work, it is not complete. Take this
// code as an example how to communicate with the RN2483 module

// SoftwareSerial can hook up to any two digital pins. More than
// one serial port can exist, but only one can be open at any time
#include <SoftwareSerial.h>

// Connect the RN2486 module to the following pins
#define LoraRX 8 // Yellow
#define LoraTX 9 // White

// Some variables to set right
byte crlf[2] = {0x0D,0x0A};
String r;
SoftwareSerial lora (LoraRX, LoraTX);

// This is the main send routine
void sendCommand(String cmd) {
  lora.print(cmd);
  lora.write(crlf, 2);
}

// This is the main receive routine
String getResponse() {
  r = "";
  while (!lora.available()) { // Linger here while no response
  } // Might be better to create a timeout

  // There is data to get, get it while it lasts
  while (lora.available()) {
    r = r + char(lora.read());
  } 
  r = r + "";
  r.trim();
  return r;
}

void setup() {
  lora.begin(57600);  // RN2486 default baud rate
  delay(100);  // Short delay to make sure the comms are up

  // Reset the module 
  sendCommand("sys reset");  // Reset the module
  r = getResponse();  // We expect a long string here
  // Containing module version information

  // Connect with the network 
  sendCommand("mac join otaa");  // Join OTAA
  r = getResponse();
  if (r == "ok") {  // That is the response we would like to have
    r = getResponse();  // There is going to be a follow-up
    if (r == "accepted") {
      // We're joined with the network
    } else {
      // 'denied'. No free channel, or max usage exceeded
      // Safe to try again later
    }
  } else { // not ok
    // Something went wrong, might be hardware
    // This should be thrown higher up
  }
  lora.end();
}

void transmitData(int payload) {
  lora.begin(57600);
  delay(100); // Short delay to make sure the comms are up

  // Send the payload confirmed, group 1
  sendCommand("mac tx cnf 1 " + String(payload));
  r = getResponse();
  if (r == "ok") {
    r = getResponse();
    if (r != "mac_tx_ok") {
      // We got data back! Parse the values from r
    } else {
      // 'mac_tx_ok'. No data back, just a succesful send
  } else {
    // 'invalid params'. Invalid parameters, programming error
  }
  lora.end();
}
void loop() {
  // This would be the place to send data, if the
  // connection with The Things Network succeeded

  // transmitData(measureSomeSensor());
}

LoRaWAN gateway construeren en verbinden met The Things Network

The Things Network timmert hard aan de weg om wereldwijde LoRaWAN dekking te realiseren. Ze zijn hiervoor volledig afhankelijk van avonturiers en bedrijven die LoRaWAN gateways doneren. Dat hoeven er nog niet eens zo veel te zijn ook: met een stuk of tien gateways heb je Groningen op de kaart.

Onze waddeneilanden hebben nog weinig tot geen LoRaWAN dekking: op drie geplande (maar nog niet aanwezige) gateways op Terschelling na is het on-ontgonnen gebied. Met één zorgvuldig geplaatste gateway heb je op een eiland op de meeste plaatsen wel bereik, dus dat leek ons een mooi doel: Texel op de TTN-kaart zetten. Stap 1: een LoRaWAN gateway construeren. Stap 2: Texel verbinden met The Things Network. Stap 3: Verschillende eiland-toepassingen realiseren.

De TTN-wiki heeft een goed bouwverhaal over het maken van een gateway. Het verhaal eindigt echter wat abrupt na de bouw en installatie van de software: hoe je de gateway aan de praat krijgt blijft onbesproken. Mooie gelegenheid om het verhaal aan te vullen en van wat ervaringen te voorzien.

Bouw

  • Sourcen van onderdelen: een IMST ic880A-concentrator board, een Raspberry Pi B+, een wifi-dongle, een antenne en verbindingskabeltje (‘SMA pigtail’), een waterdichte doos en wat verbindingsdraadjes
  • Bodemplaat voor in de waterdichte doos passend gemaakt en voorzien van gaten voor de ic880A en de Raspberry Pi
  • Printplaten, antenne en bodemplaat monteren
  • Bedrading leggen
  • Alle aansluiting controleren (en nog een keer controleren)
  • Raspberry Pi verbinden met een USB-voeding. Ook de ic880A wordt hiermee van stroom voorzien. Beide bordjes hebben verschillende leds die nu gaan branden
  • Raspberry Pi voorzien van de meest recente software (apt-get install en apt-get upgrade)
  • Raspberry Pi voorzien van de ic880A software met git clone -b spi https://github.com/ttn-zh/ic880a-gateway.git ~/ic880a-gateway
  • De software installeren met het install.sh shellscript dat in de /home/pi/ic880a-gateway directory is neergezet (sudo ./install.sh)
  • Het installatiescript toont nu het MAC adres van het ic880A concentrator board. Noteer dit, deze moet later in de console van TTN worden ingevoerd
  • Antwoord n op de vraag ‘Do you want to use remote settings file?’ en accepteer de default waardes voor ‘Host name’ en ‘Descriptive name’. Vul een bestaand email adres in bij ‘Contact email’. Zoek de coordinaten van de locatie waar de gateway wordt geplaatst op en vul deze bij ‘Latitude’ en ‘Longitude’ in. Geef de antennehoogte aan bij ‘Altitude’. De installatie wordt nu verder automatisch uitgevoerd

Inregelen en configureren

  • Tijdens de installatie van de software is er in de home directory een directory aangemaakt die /home/pi/ic880-gateway heet. Hiernaast is er een directory /opt/packet-forwarder aangemaakt. Beide softwaremodules hebben hun functie: de gateway regelt het verkeer aan de LoRa (radio) kant, de packet-forwarder zorgt voor het ontvangen en versturen van internetverkeer aan de backhaul (wifi) kant
  • Bij de installatie is de EUI van de gateway getoond. Deze moet aan de TTN kant bij het aanmaken van een nieuwe gateway worden ingevoerd

Testen

  • Een werkende gateway meldt zich binnen enkele seconden met zijn EUI op de staging pagina van The Things Network. Staat de gateway hier niet? Dat verbindt hij niet met TTN
  • Een werkende gateway waarvan de EUI bekend is op TTN wordt op de gateway pagina getoond en de doorvoer wordt gemonitord

Mogelijk problemen en oplossingen hiervoor

  • De gateway wordt bij het booten van de Raspberry Pi opgestart met /lib/systemd/system/ttn-gateway.service. Als alternatief is er een opstartscript genaamd /opt/ttn-gateway/bin/start.sh. Raspbian lijkt systemd niet geheel te ondersteunen. Neem dan start.sh op in /etc/rc.local
  • Voor alle vormen van foutzoeken is het handmatig opstarten van de gateway met start.sh verruit het handigst, omdat deze alle verbindingsinformatie over de terminal laat lopen

Test PIR sensor

ledpen = 0 -- D0/GPIO16

gpio.mode(ledpen, gpio.OUTPUT)
gpio.write(ledpen, gpio.HIGH) -- led uitzetten
pirsensorpen = 2 -- D2/GPIO4
gpio.mode(pirsensorpen, gpio.INT, gpio.PULLUP)

function beweging()
 print("PIR sensor detecteerde beweging")
 gpio.write(ledpen, gpio.LOW) -- led AAN
 tmr.alarm(0,2000, tmr.ALARM_SINGLE, function()
 gpio.write(ledpen, gpio.HIGH) -- led UIT na 2s
 end)
end

-- Roep de functie aan als het signaal begint ("up")
gpio.trig(pirsensorpen, "up", beweging)

LoRaWAN node verbinden met The Things Network

Een LoRaWAN node kan op twee manieren voor het eerst met The Things Network verbinden: Over The Air (OTAA) en Activation By Personalisation (ABP). Deze instructie gaat uit van OTAA, een RN2483 node en een bestaand account op TTN:

  • Maak verbinding met de RN2483. Het gemakkelijkst gaat dat met een seriële verbinding: de RN2483 heeft een terminal waar commando’s uitgewisseld kunnen worden. Voer een algehele factory restore uit: sys factoryRESET
  • Vraag het hardware adres op: mac get deveui
  • Voer het Device EUI in TTN in bij de node administratie
  • Kopieer de gegenereerde App Key uit TTN en voer deze in de node in met mac set appkey <appkey>
  • Kopieer de gegenereerde App EUI uit TTN en voer deze in de node in met mac set appeui <appeui>
  • Bewaar alle sleutels in de RN2483 met mac save
  • Maak verbinding met The Things Network met mac join otaa
  • De RN2483 komt direct terug met ok en na enkele seconden met accepted
  • Verstuur data met mac tx cnf 1 <databyte>

Als er geen gateway met een vrij kaneel in de buurt is zal er geen verbinding gemaakt kunnen worden. De RN2483 komt dan terug met de melding no_free_ch. Afgelopen week midden in Zwolle vastgesteld dat daar geen bruikbare LoRa dekking was, maar in Groningen is overal wel een kanaal vrij.

“Gesloopte” NodeMCU weer herstellen

Gisteren heb ik klaarblijkelijk twee NodeMCU’s “gesloopt”. De eerste wilde niet meer reageren door een combinatie van de automatisch ladende init.lua en een programmeerfout die de NodeMCU na een halve seconde deed herstarten. Normaal voldoet dan het opnieuw laden van de firmware, maar na het opwaarderen van de firmware ging de blauwe LED van de ESP12 in hoog tempo knipperen en spuwde met een baudrate van 74880 herhaald het volgende bericht uit:

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 26096, room 16 
tail 0
chksum 0x0c
load 0x3ffe8000, len 2232, room 8 
tail 0
chksum 0x7a
load 0x3ffe88b8, len 8, room 8 
tail 0
chksum 0x5f
csum 0x5f
rf_cal[0] !=0x05,is 0xFF

Da’s niet goed. Ik dacht direct aan een elektrisch defect en heb een tweede (nieuwe, goed werkende maar met een verkeerde firmware) NodeMCU voorzien van dezelfde firmware. En ook deze gaf “de blauwe flitsende LED ter bevestiging van een totale ondergang”. Zucht. En dat kost je dan een halve dag om dat uit te zoeken. Ik heb, na het halve internet te consulteren, de volgende dingen tevergeefs geprobeerd om de boel weer opnieuw aan de gang te krijgen:

  • Het 4MB flashgeheugen eerst volledig wissen met
    python ./esptool.py --port=/dev/cu.wchusbserial1420
     erase_flash
  • Andere firmware laten aanmaken via de NodeMCU custom firmware build service en die installeren
  • Andere instellingen voor de flasher gebruikt: de gebruikte NodeMCU’s hebben 4MB flashgeheugen (32mbit) en werken met de “Dual IO SPI” (DIO) flash methode, maar toch maar met andere instellingen geprobeerd, zoals 4m en “detect”; flashmode veranderd van dio naar qio
  • Andere USB kabel
  • Eerst een niet-NodeMCU firmware geladen, zoals de oorspronkelijke boot_v1.1.bin. Deze deed het prima en maakte na het booten een sprong naar het
  • Andere firmware flasher (ik gebruikte esptool.py onder OS X, maar heb een Windows tool van electrodragon geprobeerd onder Windows 10 op de PC

Uiteindelijk bleek de oplossing erg simpel en bleek het probleem goed gedocumenteerd, echter zonder het noemen van de symptomen. In het 4MB geheugen van de NodeMCU zijn blokken voor zowel de firmware als voor instellingen gereserveerd. Deze instellingen hangen samen met de versie van de ESP12. De firmware en de instellingen hebben een grote samenhang en blijkbaar zat daar iets in verkeerd. Door het uploaden van instellingen die beter bij de master build van de NodeMCU firmware passen, namelijk die uit SDK patch 1.5.4.1, kon ik de NodeMCU weer terug naar het land der levenden brengen. Bij het laden van die instellingen nog even om de juiste parameters van het esptool.py denken, en wel specifiek de geheugenplaats 0x3fc000 waar de instellingen moeten landen:

python ./esptool.py --port=/dev/cu.wchusbserial1420 write_flash -fm=dio -fs=32m 0x3fc000 ./esp_init_data_default.bin

En dan de gewenste versie van de firmware (in mijn geval de 20 modules variant met floating point ondersteuning) flashen op geheugenplaats 0x00000:

python ./esptool.py --port=/dev/cu.wchusbserial1420 write_flash -fm=dio -fs=32m 0x00000 ./nodemcu-m20-float.bin

Een van beide NodeMCU’s leek het in eerste instantie niet goed te doen. Toen ik van 74880 bits/seconde overschakelde naar een baudrate van 115200 bits per seconde zag ik de melding “Formatting file system. Please wait…” voorbij komen. Dat duurde een minuutje en vervolgens kwam de melding:

NodeMCU custom build by frightanic.com
	branch: master
	commit: 7b83bbb2ea134cd85ac9d63108603cc02c4e20f7
	SSL: false
	modules: adc,bit,cjson,coap,dht,file,gpio,i2c,mqtt,net,node,ow,pwm,rtctime,sntp,spi,tmr,uart,wifi,ws2812
 build 	built on: 2016-11-25 08:30
 powered by Lua 5.1.4 on SDK 1.5.4.1(39cb9a32)
lua: cannot open init.lua

>

Blijkbaar was de gebruikte Geekcreit Doit NodeMcu voorzien van een oudere versie van de NodeMCU firmware die niet (meer) compatible was met de SPIFFS versie die voor het bestandsbeheer zorgt. Probleem opgelost!

PocketC.H.I.P. = Linux terminal met Pokémon scanner

‘C.H.I.P.’ is een mini computerbordje dat in oktober in productie gaat. C.H.I.P. is wat vorm en functie betreft vergelijkbaar met een Raspberry Pi, het heeft bijvoorbeeld ook een Linux besturingssysteem. Wat prijs (9 dollar) en hardware betreft lijkt het bordje wat meer voor makers te zijn bedoeld, zoals bijvoorbeeld een Arduino MKR1000.

handycomp

De add-on met beeldscherm en toetsenbord levert een handzame Linux terminal op. Het geheel spreekt tot de verbeelding en de eerste projecten zijn al onderweg. Zoals een ‘live Pokémon tracking device‘.

IMG_1914-1024x768

De servers van Niantic, de makers van de Pokémon Go app, hebben de beschikking over een API die bevraagd kan worden over de aanwezigheid van Pokémons in de buurt. Een handig scriptje kan die informatie op een Google maps kaart tonen en dat is precies wat er is gebeurd.

Uitgekristalliseerde, praktische gereedschapskist

Voor een ieder die een gereedschapskist wil samenstellen heb ik een lijst van gereedschappen die niet mogen ontbreken voor kleine, ongeplande klussen in en rond het huis. Vorig jaar heb ik al eens een poging gedaan de inhoud van een goede gereedschapskist te beschrijven, maar nu is de lijst getest en akkoord bevonden. Ik heb een basis set gereedschap in een kist gedaan en voor iedere nieuwe klus gekeken wat er nog aan gereedschap ontbrak en zo nodig aangevuld. Resultaat: een praktische set van onontbeerlijke hulpjes zonder al te veel onnodige poespas.

IMG_1047

Meer waddeneilanden dan je wist!

Wij komen met regelmaat op Texel, het eerste en grootste van de Nederlandse waddeneilanden. Onze kinderen kennen het ‘TVTAS’ ezelsbruggetje. Maar wist je dat die sinds een tijdje niet meer klopt, dat het eigenlijk ‘NTVTAS’ zou moeten zijn? En welke eilanden komen er na Schiermonnikoog? En hoe heten die zandplaten die tussen de eilanden verstopt liggen? Vandaag maar eens een onderzoekje gedaan. Er zijn meer dan 50 waddeneilanden waar meer dan 80 duizend mensen wonen!

Noorzee- en waddeneilanden

“Waddeneilanden,” zegt Wikipedia, “liggen in de Noordzee, ten noorden van Nederland en Duitsland en ten westen van Denemarken. Tussen de eilanden en het vasteland ligt de Waddenzee. Het grootste eiland is het Nederlandse Texel, gevolgd door het Deense Rømø en het Duitse Sylt. Sylt heeft met ongeveer 21.000 inwoners de grootste bevolking van alle eilanden.” Huh? Maar de Waddenzee lag toch zo’n beetje tussen Den Helder en Termunterzijl? Nee dus: “de Waddenzee (Fries: Waadsee, Duits: Wattenmeer, Deens: Vadehavet) is de binnenzee tussen de Waddeneilanden en de Noordzee aan de ene kant, en aan de andere kant het vasteland van Nederland, Duitsland en Denemarken.”

Er wordt onderscheid gemaakt tussen eilanden en zandplaten. Eilanden staan (bij gemiddeld hoog water) voor tenminste 1,6 km2 boven water. Wikipedia: “Als de platen droogliggen kan er zich zand afzetten, waardoor ze steeds hoger worden. Sommige platen kunnen zo groeien dat ze alleen nog bij springvloed onder komen te staan of bij extreem hoogwater. Zo kunnen ze uitgroeien tot kleine eilanden.”

Door de wind en de zee is er een hoop beweging in de Waddenzee. Zandplaten groeien, verkleinen en verplaatsen, eilanden ontstaan en verdwijnen. Het meest recente nieuwe eiland is het Duitse Kachelotplate, dat in 2003 ontstond. Gaswinning lijkt daar overigens geen rol bij te spelen.

In de tabel hieronder heb ik alle eilanden en zandplaten in de Waddenzee opgenomen. Veel eilanden zijn gewoon wat je zou verwachten: een stuk land in zee, huizen erop, strand en toegankelijk per veerboot. Maar er zijn er, die met een dijk toegankelijk zijn. Of waar héél weinig mensen wonen. Of slechts ééntje.

Nr Naam Type Land Oppervlakte Inwoners
1 Noorderhaaks Eiland Nederland 4 km² 0
2 Texel Eiland Nederland 161 km² 13614
3 Vlieland Eiland Nederland 36 km² 1072
4 Richel Zandplaat Nederland < 1 km² 0
5 Griend Zandplaat Nederland < 1 km² 0
6 Terschelling Eiland Nederland 86 km² 4832
7 Ameland Eiland Nederland  59 km²  3617
8 Rif Zandplaat Nederland < 1 km² 0
9 Engelsmanplaat Zandplaat Nederland  < 1 km² 0
10 Schiermonnikoog Eiland Nederland  44 km² 914
11 Simonszand Zandplaat Nederland  < 1 km² 0
12 Rottumerplaat Eiland Nederland 8 km²  0
13 Rottumeroog Eiland Nederland  3 km² 0
14 Borkum Eiland Duitsland 31 km²  5225
15 Lütje Hörn Zandplaat Duitsland  < 1 km²  0
16 Kachelotplate Eiland (2003) Duitsland  6 km²  0
17 Memmert Eiland Duitsland  5 km²  0
18 Juist Eiland Duitsland  16 km²  1.589
19 Norderney Eiland Duitsland 26 km² 5.875
20 Baltrum Eiland Duitsland  7 km²  617
21 Langeoog Eiland Duitsland  20 km²  1.757
22 Spiekeroog Eiland Duitsland 18 km² 773
23 Wangerooge Eiland Duitsland 5 km²  1.055
24 Minsener-Oldoog Eiland Duitsland 4 km² 0
25 Mellum Eiland Duitsland 8 km²  0
26 Langlutjen I & II Eilanden Duitsland 3 km²  0
27 Neuwerk Eiland Duitsland 3 km²  33
28 Scharhörn Zandplaat Duitsland < 1 km²  0
29 Nigehörn Zandplaat Duitsland < 1 km²  0
30 Trischen Eiland Duitsland 3 km²  1
31 Blauort Zandplaat Duitsland < 1 km²  0
32 Pellworm Eiland Duitsland 37 km²  1158
33 Nordstrand Schiereiland Duitsland 40 km²  2218
34 de Halligen (10) Eilandengroep Duitsland 23 km²  256
35 Amrum Eiland Duitsland 20 km²  2300
36 Föhr Eiland Duitsland 82 km²  8600
37 Sylt Schiereiland Duitsland 99 km²  21000
38 Rømø Schiereiland Denemarken 130 km²  1000
39 Mandø Schiereiland Denemarken 8 km²  30
40 Fanø Eiland Denemarken 56 km²  3207
41 Langli Zandplaat Denemarken < 1 km²  0

Musical Medley “Alles overboord” groepen 8 Joseph Haydnschool

Groepen 8 Joseph Haydnschool naar Schiermonnikoog