LoRa antennelengte voor 868MHz

De LoRa communicatietechnologie is voor een goede werking afhankelijk van antennes. “De beste versterker is een goede antenne,” zei een collega vroeger wel eens tegen me. LoRa werkt in Nederland in twee frequentiebanden, respectievelijk ‘433 MHz’ en ‘868 MHz’ genoemd. De tweede, 868 MHz, wordt het meest gebruikt.

Een antenne is een geleider in de vorm van een staaf of spriet die met een leiding met een communicatiemodule is verbonden. De diameter van de geleider is nauwelijks van belang. Handig is wel als het materiaal waarvan de antenne is gemaakt in staaf- of sprietvorm blijft, dus een enigszins stugge geleider heeft hier de voorkeur. De antenne is het meest effectief als hij precies zo lang is als de gemiddelde frequentie waarvoor hij moet worden gebruikt. Indien dat niet praktisch is dan kan voor de lengte van de antenne ook, met iets mindere resultaten, worden volstaan met een helft of een kwart van de golflengte. Dat laatste wordt het meest toegepast.

De golflengte is gelijk aan v / f, waarbij v de voortplantingssnelheid van de radiogolf is en f de frequentie. In lucht is v gelijk aan de lichtsnelheid c, 299.792.458 m/s. De golflengte voor de 868 MHz band is dan 299.792.458 / 868.000.000 = 34,54 cm. De helft hiervan is 17,27 cm en een kwart is 8,63 cm.

Voor de 433 MHz band is de golflengte 299.792.458 / 433.000.000 = 69,24 cm. De helft hiervan is 34,62 cm en een kwart is 17,31 cm.

Een draadantenne van 8,6 cm volstaat dus voor een LoRa toepassing op de 868 MHz band. Een stukje montagedraad van 8,6 cm is genoeg. De lengte van de antenne is gemeten vanaf de aansluiting. Als een antenne met een leiding wordt verbonden dan moet deze leiding in de vorm van een 50 ohm kabel worden uitgevoerd.

LoRa, KPN en The Things Network met ATtiny85 en RN2483

Een Microchip RN2483 is een degelijke, door de LoRa Alliance gecertificeerde manier om verbinding te maken met een LoRaWAN gateway van KPN of The Things Network. En als het de bedoeling is om af en toe sensorwaarden naar het internet te sturen dan heb je niet veel extra’s nodig. De RN2483 is een SoC dat bestaat uit een Semtech SX1276 LoRa zendontvanger en een Microchip PIC18LF46K22 microcontroller. Deze laatste heeft mogelijkheden genoeg om een sensorwaarde in te lezen, maar om de certificering in stand te houden heeft Microchip ervoor gekozen het lastig te maken om de PIC18LF46K22 te laten herprogrammeren of aan te vullen met extra programmatuur. Maar geen paniek: met een Atmel ATtiny85 kan het ook. Totale kosten van zo’n setje: 20 euro.

In het schema hierboven is een RN2483 met enkele lijnen (GND, RX, TX, RESET) verbonden met de ATtiny85 microcontroller. Beide worden gevoed door een CR2016 knoopcel. Voor de gelegenheid is de RN2483 voorzien van een draadantenne van 8,2 cm, wat voldoende is voor een reikwijdte van een kilometer. De ATtiny85 maakt gebruik van pennen 1 en 3 om de RN2483 serieel aan te sturen en pen 7 om de RN2483 module te herstarten. In de sketch hieronder is het principe weergegeven:

#include 

#define rxPin 4
#define txPin 5
#define rn2483Reset 2

SoftwareSerial rn2483(rxPin, txPin);

byte crlf[2] = {0x0D,0x0A};         // Used to terminate RN2486 commands

void sendCommand(String cmd) {
  rn2483.print(cmd);
  rn2483.write(crlf, 2);
  delay(1000);
}

String getResponse() {
  String response = "";

  while (!rn2483.available()) { // Linger here while no response
  } // Might be better to create a timeout after a few seconds

  while (rn2483.available()) {
    response = response + char(rn2483.read());
  } 
  response = response + "";
  response.trim();
  return response;
}

int initLoRa() {
  String response;
  int code = -1;
  
  sendCommand("mac join otaa"); 
  response = getResponse();
  
  if (response == "ok") {
    code = 0;
    delay(6000);
    response = getResponse();
    if (response == "accepted") {
      // There. A valid LoRa connection
      code = 1;
    } else {
      // Denied. Either no free channels or something else
      code = 2;
    }
  } else {  // not ok
    // Not a wanted response. Something with the hardware
    // We might want to throw a panic here
    code = 3;
  }  
  return code;
}

void setup() {
  pinMode(rn2483Reset, OUTPUT);
  digitalWrite(rn2483Reset, false); // Reset
  delay(100);
  digitalWrite(rn2483Reset, true); // Not reset
  delay(2500);
  rn2483.begin(57600);
  while (!rn2483) {
    delay(100);
  }
  initLoRa();
}

void loop() {
  // put your main code here, to run repeatedly:

}

Het solderen van montagedraden aan een RN2483 is nog niet zo eenvoudig, maar met een soldeerbout met een fijne punt moet het lukken. Het aansturen van de kick-ass PIC18LF46K22 door een ATtiny85 is zoiets als een Tesla model S laten starten met een accu van een lelijke eend, maar LoRaWAN is dan ook niet bedoeld voor iets omvangrijkers dan waar een ATtiny85 toe in staat is.

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

Inregelen en configureren

  • Tijdens de installatie van de software is er in de home directory een directory aangemaakt die ic880-gateway heet. Hiernaast is er een directory in /opt aangemaakt die packet-forwarder heet. 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

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