├── docs
├── assets
│ ├── lora1.png
│ ├── lora10.png
│ ├── lora11.png
│ ├── lora12.png
│ ├── lora13.png
│ ├── lora14.png
│ ├── lora15.png
│ ├── lora16.png
│ ├── lora17.png
│ ├── lora18.jpg
│ ├── lora19.png
│ ├── lora2.png
│ ├── lora3.png
│ ├── lora4.png
│ ├── lora5.jpg
│ ├── lora6.jpg
│ ├── lora7.png
│ ├── lora8.png
│ ├── lora9.png
│ ├── stream1.png
│ ├── stream10.png
│ ├── stream11.png
│ ├── stream12.png
│ ├── stream13.png
│ ├── stream14.png
│ ├── stream2.png
│ ├── stream3.png
│ ├── stream4.png
│ ├── stream5.png
│ ├── stream6.png
│ ├── stream7.png
│ ├── stream8.png
│ ├── stream9.png
│ ├── ttn1.png
│ ├── ttn10.png
│ ├── ttn11.png
│ ├── ttn12.png
│ ├── ttn13.png
│ ├── ttn14.png
│ ├── ttn15.png
│ ├── ttn16.png
│ ├── ttn17.png
│ ├── ttn18.png
│ ├── ttn19.png
│ ├── ttn2.png
│ ├── ttn3.png
│ ├── ttn4.png
│ ├── ttn5.png
│ ├── ttn6.png
│ ├── ttn7.png
│ ├── ttn8.png
│ └── ttn9.png
├── index.md
└── intro-to-lora.md
├── mkdocs.yml
└── ttn-node-app
├── .gitignore
├── package.json
├── public
├── ARMmbedLogo.svg
├── helper.js
└── style.css
├── server.js
└── views
└── index.html
/docs/assets/lora1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora1.png
--------------------------------------------------------------------------------
/docs/assets/lora10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora10.png
--------------------------------------------------------------------------------
/docs/assets/lora11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora11.png
--------------------------------------------------------------------------------
/docs/assets/lora12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora12.png
--------------------------------------------------------------------------------
/docs/assets/lora13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora13.png
--------------------------------------------------------------------------------
/docs/assets/lora14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora14.png
--------------------------------------------------------------------------------
/docs/assets/lora15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora15.png
--------------------------------------------------------------------------------
/docs/assets/lora16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora16.png
--------------------------------------------------------------------------------
/docs/assets/lora17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora17.png
--------------------------------------------------------------------------------
/docs/assets/lora18.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora18.jpg
--------------------------------------------------------------------------------
/docs/assets/lora19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora19.png
--------------------------------------------------------------------------------
/docs/assets/lora2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora2.png
--------------------------------------------------------------------------------
/docs/assets/lora3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora3.png
--------------------------------------------------------------------------------
/docs/assets/lora4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora4.png
--------------------------------------------------------------------------------
/docs/assets/lora5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora5.jpg
--------------------------------------------------------------------------------
/docs/assets/lora6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora6.jpg
--------------------------------------------------------------------------------
/docs/assets/lora7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora7.png
--------------------------------------------------------------------------------
/docs/assets/lora8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora8.png
--------------------------------------------------------------------------------
/docs/assets/lora9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/lora9.png
--------------------------------------------------------------------------------
/docs/assets/stream1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream1.png
--------------------------------------------------------------------------------
/docs/assets/stream10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream10.png
--------------------------------------------------------------------------------
/docs/assets/stream11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream11.png
--------------------------------------------------------------------------------
/docs/assets/stream12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream12.png
--------------------------------------------------------------------------------
/docs/assets/stream13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream13.png
--------------------------------------------------------------------------------
/docs/assets/stream14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream14.png
--------------------------------------------------------------------------------
/docs/assets/stream2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream2.png
--------------------------------------------------------------------------------
/docs/assets/stream3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream3.png
--------------------------------------------------------------------------------
/docs/assets/stream4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream4.png
--------------------------------------------------------------------------------
/docs/assets/stream5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream5.png
--------------------------------------------------------------------------------
/docs/assets/stream6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream6.png
--------------------------------------------------------------------------------
/docs/assets/stream7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream7.png
--------------------------------------------------------------------------------
/docs/assets/stream8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream8.png
--------------------------------------------------------------------------------
/docs/assets/stream9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/stream9.png
--------------------------------------------------------------------------------
/docs/assets/ttn1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn1.png
--------------------------------------------------------------------------------
/docs/assets/ttn10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn10.png
--------------------------------------------------------------------------------
/docs/assets/ttn11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn11.png
--------------------------------------------------------------------------------
/docs/assets/ttn12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn12.png
--------------------------------------------------------------------------------
/docs/assets/ttn13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn13.png
--------------------------------------------------------------------------------
/docs/assets/ttn14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn14.png
--------------------------------------------------------------------------------
/docs/assets/ttn15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn15.png
--------------------------------------------------------------------------------
/docs/assets/ttn16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn16.png
--------------------------------------------------------------------------------
/docs/assets/ttn17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn17.png
--------------------------------------------------------------------------------
/docs/assets/ttn18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn18.png
--------------------------------------------------------------------------------
/docs/assets/ttn19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn19.png
--------------------------------------------------------------------------------
/docs/assets/ttn2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn2.png
--------------------------------------------------------------------------------
/docs/assets/ttn3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn3.png
--------------------------------------------------------------------------------
/docs/assets/ttn4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn4.png
--------------------------------------------------------------------------------
/docs/assets/ttn5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn5.png
--------------------------------------------------------------------------------
/docs/assets/ttn6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn6.png
--------------------------------------------------------------------------------
/docs/assets/ttn7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn7.png
--------------------------------------------------------------------------------
/docs/assets/ttn8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn8.png
--------------------------------------------------------------------------------
/docs/assets/ttn9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARMmbed/lora-docs/7452c6ce6f695468b4568f8c318e0b108985e157/docs/assets/ttn9.png
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # LoRa on Arm Mbed OS
2 |
3 | [LoRaWAN](http://lora-alliance.org) is a long range wide-area network technology that combines long range with low power consumption. This space contains documents on how to start building LoRa networks and LoRa appliances using Arm Mbed.
4 |
--------------------------------------------------------------------------------
/docs/intro-to-lora.md:
--------------------------------------------------------------------------------
1 | ## Building your own private LoRa network
2 |
3 | There is a lot of interest in [LoRa](https://www.lora-alliance.org), a wide-area network solution that promises kilometers of range with low power consumption, a perfect fit for the Internet of Things. Telecom operators are rolling out LoRa networks, but because LoRa operates in the [open spectrum](https://en.wikipedia.org/wiki/ISM_band), you can also set up your own network. This article discusses what you need to build a private LoRa network and how to use the network to send data from an Arm Mbed end node to the cloud.
4 |
5 | **Note on LoRa vs. LoRaWAN:** Technically, this article explains how to build a LoRaWAN network. LoRa is the modulation technique used (PHY), and LoRaWAN is the network protocol on top of the physical layer (MAC).
6 |
7 | ### 1. What you need
8 |
9 | A typical LoRa network consists of four parts: devices, gateways, a network service and an application:
10 |
11 | Topology of a LoRa network
12 |
13 | For hardware, you need devices and gateways, similar to how you would set up a Wi-Fi network. Gateways are simple: they scan the spectrum and capture LoRa packets. There is no gateway pinning here. Devices are not associated with a single gateway; thus, all gateways within range of a device receive the signal. The gateways then forward their data to a network service that handles the packet.
14 |
15 | The network service deduplicates packets when multiple gateways receive the same packet, decrypts the message (everything is end-to-end encrypted) and handles LoRa features, such as adaptive data rating. It then forwards the decrypted data to your application. Often, network service providers allow you to run parts of the network - such as the application server, which decrypts the messages - yourself.
16 |
17 | You need hardware:
18 |
19 | - Gateways.
20 | - Devices.
21 |
22 | And software:
23 |
24 | - Device firmware.
25 | - A network service.
26 | - An app.
27 |
28 | This guide shows you:
29 |
30 | - Which hardware you can buy.
31 | - How to configure a gateway.
32 | - How to write device firmware.
33 | - How to set up a web application to show your LoRa traffic.
34 |
35 | **Note:** The frequency that LoRa uses differs among regions. Make sure your gateways and devices are legal in your jurisdiction. For example, use 915 MHz radios in the United States and 868 MHz radios in Europe. You can find more information in the [LoRaWAN regional parameters](http://net868.ru/assets/pdf/LoRaWAN-Regional-Parameters-v1.1rA.PDF) specification.
36 |
37 | #### 1.1 - Choosing a gateway
38 |
39 | You have [many choices in the gateways](https://www.loriot.io/lora-gateways.html) you can use, but we've had good experience with these three:
40 |
41 | - [Kerlink Wirnet station](https://www.kerlink.com/product/wirnet-station/). Expensive (around 1,200 euros) but great build quality and range.
42 | - [MultiTech conduit](http://www.multitech.com/brands/multiconnect-conduit). About 1/3 of the price of the Kerlink (about 450 euros) and good for smaller setups. MultiTech also has a [rugged outdoor](http://www.multitech.com/brands/multiconnect-conduit-ip67) version. Make sure you also order the LoRa mCard.
43 | - Building your own with a Raspberry Pi and an [IMST iC880A](http://shop.imst.de/wireless-modules/lora-products/8/ic880a-spi-lorawan-concentrator-868-mhz) concentrator. At about 150 euros, this is a cost-efficient option.
44 |
45 | Self-built LoRa gateway based on Raspberry Pi 2 and IMST iC880A. Total cost is about 150 euros.
46 |
47 | For development purposes, one gateway is enough, but in a production deployment, you need at least two because there will always be dark spots in your network.
48 |
49 | Kerlink Wirnet station overlooking the Oslo fjord.
50 |
51 | #### 1.2 - Choosing a device
52 |
53 | You also need to build devices. If you use Mbed OS (and you should), you can either use:
54 |
55 | - A development board with a LoRa transceiver:
56 | - [L-Tek FF1705](https://os.mbed.com/platforms/L-TEK-FF1705/).
57 | - [MultiTech xDot](https://os.mbed.com/platforms/MTS-xDot-L151CC/).
58 | - [MultiTech mDot](https://os.mbed.com/platforms/MTS-mDot-F411/) and the [UDK2 board](http://www.digikey.com/product-detail/en/multi-tech-systems-inc/MTUDK2-ST-MDOT/591-1278-ND/5247463).
59 | - [MultiTech mDot EVB](https://os.mbed.com/platforms/mdotevb/).
60 | - [B-L072Z-LRWAN1 LoRa®Discovery kit](https://os.mbed.com/platforms/ST-Discovery-LRWAN1/).
61 | - An Mbed OS 5 Enabled development board together with a LoRa shield:
62 | - [SX1272MB2xAS](https://os.mbed.com/components/SX1272MB2xAS/) - shield based on the SX1272 transceiver.
63 | - [SX1276MB1xAS](https://os.mbed.com/components/SX1276MB1xAS/) - shield based on the SX1276 transceiver.
64 |
65 | This tutorial applies to all combinations listed above.
66 |
67 | **Note:** When ordering hardware, always make sure you get the variant that works in your region (for example 868 MHz in Europe and 915 MHz in the US).
68 |
69 | #### 1.3 - Network server
70 |
71 | For software, you need a server that understands the LoRa protocol and can interpret the data the device sends. It's possible to use your own (Semtech can give you its reference implementation if you sign an NDA), but there are also companies building LoRa network servers as a service, handling everything on your behalf. This article uses [The Things Network](https://www.thethingsnetwork.org), an open source, globally distributed network service that also has a free hosted community edition.
72 |
73 | Because a network server only processes your data and doesn't store it, you need a somewhere to store your messages, as well. The Things Network allows you to hook into its service through an MQTT client and forward your data to the cloud service of your choice (or straight to your application).
74 |
75 | ### 2. Setting up the gateway
76 |
77 | You now need to configure the gateway by installing software to scan the spectrum and forward all LoRa packets to the network server. Below are setup instructions for the three gateways suggested earlier.
78 |
79 | #### 2.1 - Prerequisites
80 |
81 | ##### Kerlink Wirnet stations
82 |
83 | Follow the instructions in [this document](https://www.thethingsnetwork.org/docs/gateways/kerlink/config.html).
84 |
85 | ##### MultiTech Conduit
86 |
87 | The conduit is configured with DHCP disabled, so you need to enable this first. There are two options to do this: either through Ethernet or through micro-USB.
88 |
89 | **Using Ethernet**
90 |
91 | 1. Connect to the conduit over Ethernet (from the conduit to your computer).
92 | 1. Set a static IP address of 192.168.2.2 for your computer.
93 | 1. Set a static IP address of 192.168.2.1 as your router.
94 | 1. Log in through SSH to 192.168.2.1 with the username `root` and password `root`.
95 |
96 | **Over micro-USB**
97 |
98 | 1. Connect to the conduit using a micro-USB cable.
99 | 1. The gateway appears as a serial device.
100 | 1. You can use a program such as [GNU Screen](https://www.gnu.org/software/screen/) or [PuTTY](http://putty.org) to log into the gateway with the username `root` and password `root`.
101 |
102 | **Note if logging in fails:** If logging in as `root` fails but you can log in with the username `admin` and the password `admin`, you are running the AEP firmware. To proceed, update your gateway firmware to mLinux. Use [these instructions](http://www.multitech.net/developer/software/mlinux/using-mlinux/flashing-mlinux-firmware-for-conduit/).
103 |
104 | Now that you are connected, you can set up the gateway:
105 |
106 | 1. Enable DHCP by following Step 4 in [this document](http://www.multitech.net/developer/software/mlinux/getting-started-with-conduit-mlinux/).
107 | 1. Connect the gateway over Ethernet to your router.
108 | 1. Verify that the gateway is connected to the internet (for example, by running `ping 8.8.4.4`).
109 |
110 | ##### Raspberry Pi
111 |
112 | Follow the instructions in [this document](https://github.com/ttn-zh/ic880a-gateway/wiki).
113 |
114 | #### 2.2 - Registering the gateway
115 |
116 | 1. [Sign up](https://console.thethingsnetwork.org) for an account at The Things Network.
117 | 1. You're redirected to the dashboard page.
118 | 1. Click **Gateways**.
119 |
120 | 
121 |
122 | 1. Click **Register gateway**.
123 |
124 | 
125 |
126 | 1. Fill in the details of your gateway.
127 |
128 | Gateway details: The Things Network uses the gateway location to create coverage maps, so make sure the location is set correctly.
129 |
130 | 1. If you use the Kerlink Wirnet station:
131 | - Tick **I'm using the legacy packet forwarder**.
132 | - Under **Gateway EUI**, enter the EUI of the gateway (printed on the box).
133 |
134 | 1. If you use the Raspberry Pi:
135 | - Tick **I'm using the legacy packet forwarder**.
136 | - Under **Gateway EUI**, enter the EUI that printed when you called `install.sh` in step 2.1.
137 |
138 | 1. Click **Register gateway**.
139 | 1. You have created the gateway.
140 |
141 | If you use the MultiTech conduit, you need the 'Gateway key' to authenticate the gateway to the network. Copy it.
142 |
143 | 
144 |
145 | #### 2.3 - Installing the packet forwarder
146 |
147 | ##### Kerlink Wirnet station or Raspberry Pi
148 |
149 | No further action required. The gateway shows as 'Connected' in the TTN console.
150 |
151 | Connected!
152 |
153 | ##### MultiTech conduit
154 |
155 | 1. On the gateway, run:
156 |
157 | ```
158 | $ wget https://github.com/kersing/multitech-installer/raw/master/installer.sh
159 | $ sh installer.sh
160 | ```
161 |
162 | 1. A wizard starts. Answer the questions.
163 |
164 | Wizard for configuring the MultiTech Conduit.
165 |
166 | 1. After the gateway reboots, log back in.
167 | 1. Then run (again):
168 |
169 | ```
170 | $ sh installer.sh
171 | ```
172 |
173 | 1. Fill in the remaining questions.
174 |
175 | Wizard (2) for configuring the MultiTech Conduit.
176 |
177 | 1. After this, the gateway shows as **Connected** in the TTN console.
178 |
179 | Connected!
180 |
181 | ### 3. Building a device
182 |
183 | This section explains how to build a device that can send sensor data over the LoRa network. For example, you can create a motion sensor using a [PIR sensor](https://www.adafruit.com/products/189) (less than 10 euros). Of course, you can use any other sensor.
184 |
185 | PIR sensor hooked up to a Nordic Semiconductor nRF51-DK with a SX1276 LoRa shield
186 |
187 | #### 3.1 - Some notes on writing firmware
188 |
189 | ##### Restrictions on sending data
190 |
191 | You cannot send data constantly because of spectrum regulations. Although the spectrum that LoRa uses is unlicensed, it is regulated. For example, in Europe, there are duty cycle limitations of 1% - meaning you can only send 1% of the time. In the US, there's dwell time, which requires you to wait at least 400 ms between transmissions. If you violate these regulations, your data transmission fails. How fast you are allowed to send data depends on the spread factor you use. With a higher spread factor, it takes longer to send a message - though the chance that a gateway receives it increases. However, you need to wait longer before you can send data again. During development, you can set the spread factor to SF7 (the lowest), so you can send every 6-7 seconds.
192 |
193 | LoRaWAN has a feature called Adaptive Data Rating (ADR), through which the network can control the spread factor. You probably want this enabled.
194 |
195 | ##### Blocked pins
196 |
197 | A disadvantage of the SX1272 and SX1276 LoRa shields is that they block a lot of pins. You can solder new headers on the back of the shield to add new peripherals, or use a microcontroller such as the nRF51-DK or a NUCLEO board that has more pins available than just the Arduino headers.
198 |
199 | #### 3.2 - Registering the device on The Things Network
200 |
201 | LoRaWAN uses an end-to-end encryption scheme that uses two session keys. The network server holds one key, and the application server holds the other. (In this tutorial, TTN fulfils both roles). These session keys are created when the device joins the network. For the initial authentication with the network, the application needs its device EUI, the EUI of the application it wants to join (referred to as the application EUI) and a preshared key (the application key).
202 |
203 | The device EUI and application EUI are globally unique identifiers. You can buy a block of EUIs from the [IEEE](http://standards.ieee.org/develop/regauth/tut/eui.pdf). Modules often already come with an EUI, which is printed on the device. If you're using a radio shield you can use an EUI from The Things Network's block.
204 |
205 | **Note:** In LoRaWAN 1.1, the join key replaces the application key, and the join server handles the initial authentication. However, at the time of writing, this is not implemented on The Things Network.
206 |
207 | Register the device in The Things Network, and generate some keys:
208 |
209 | 1. Go to [The Things Network console](https://console.thethingsnetwork.org).
210 | 1. Click **Applications**.
211 | 1. Click **Add application**.
212 |
213 | 
214 |
215 | 1. Fill in the details of your application, and click **Add application**.
216 |
217 | Filling in the application details in The Things Network.
218 |
219 | 1. You're redirected to the application page. Under **Devices**, click **Register device**.
220 |
221 | 
222 |
223 | 1. If your device has an EUI printed on it, enter this in **Device EUI**.
224 |
225 | The device EUI is often printed on the module or on the box.
226 |
227 | 1. If your device does not have an EUI printed on it, press the **generate** button to allocate an EUI from a block owned by The Things Network. Do **not** make an EUI up; it must be globally unique.
228 |
229 | 
230 |
231 | 1. Fill in the rest of the details, and click **Register**.
232 |
233 | 
234 |
235 | 1. The device page opens. It contains the keys that your device uses when authenticating with the network. Click the `<>` button to get the keys as a byte array. This makes it easy to copy the keys into code.
236 |
237 | 
238 |
239 | Now that the device is registered in The Things Network, you can start writing code!
240 |
241 | #### 3.3 - Importing the demo application
242 |
243 | Mbed comes with the Arm Mbed Online Compiler, which you can use to build applications without needing to install anything on your computer. (Mbed also has [offline tools](https://os.mbed.com/docs/latest/tools/index.html)).
244 |
245 | 1. [Sign up](https://os.mbed.com/account/signup/?next=%2F) for an account on Arm Mbed, which hosts the Online Compiler.
246 | 1. Find your development board on [the platforms page](https://os.mbed.com/platforms/).
247 | 1. Click **Add to your Mbed Compiler**.
248 | 1. Go to [mbed-os-example-lorawan](https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-lorawan/).
249 | 1. Click **Import this program**.
250 | 1. You're redirected to the Online Compiler, where you can give the program a name.
251 |
252 | Importing a program to get started
253 |
254 | **Note:** Make sure you select the correct board in the top right corner of the compiler.
255 |
256 | Selecting the correct board
257 |
258 | #### 3.4 - Setting keys
259 |
260 | In the Online Compiler:
261 |
262 | 1. Open `mbed_app.json`. This file contains the configuration for the application and holds the authentication keys.
263 | 1. If you have a SX1272 or SX1276 **shield** (not if you have a module), set your radio type under `lora-radio`.
264 | 1. Under `lora.device-eui`, enter the device EUI from the TTN console.
265 | 1. Under `lora.application-eui`, enter the application EUI from the TTN console.
266 | 1. Under `lora.application-key`, enter the application key from the TTN console.
267 |
268 | Correct keys set in `mbed_app.json`
269 |
270 | 1. Under `lora.phy` specify the channel plan for your region. A list of possible values is listed under '[Selecting a PHY'](https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-lorawan#selecting-a-phy) in the docs.
271 |
272 | ##### Sending the value of the PIR sensor
273 |
274 | To send the current value of the PIR sensor (whether it sees movement), in the Online Compiler:
275 |
276 | 1. Open `main.cpp`.
277 | 1. Replace the function `send_message()` with:
278 |
279 | ```cpp
280 | static void send_message() {
281 | static InterruptIn pir(D5); // If you hooked the sensor up to a different pin, change it here
282 |
283 | // create a one-byte payload which contains whether the PIR sensor is *high* or *low*
284 | uint8_t buffer[] = { pir.read() };
285 | int16_t retcode = lorawan.send(LORAWAN_APP_PORT, buffer, sizeof(buffer), MSG_CONFIRMED_FLAG);
286 |
287 | if (retcode == 0) {
288 | printf("Sent message over LoRaWAN successfully!\n");
289 | }
290 | else {
291 | printf("Failed to send message (duty-cycle violation?) (%d)\n", retcode);
292 | }
293 | }
294 | ```
295 |
296 | #### 3.5 - Verifying the setup
297 |
298 | Now you can verify whether the setup works by flashing this application to your board.
299 |
300 | 1. In the Online Compiler, click the **Compile** button.
301 |
302 | Compile button
303 |
304 | 1. When compilation succeeds, the compiler sends a file to your computer.
305 | 1. Plug your development board into the computer (over micro-USB) to mount it as a USB mass storage device. In most cases, you do not need a driver, but you can find drivers [here](https://os.mbed.com/docs/latest/tutorials/windows-serial-driver.html).
306 | 1. Once the device mounts, drag the compiled file onto the board. This causes the device to boot. You can then see the device joining and then sending messages in the The Things Network console, under the **Data** tab:
307 |
308 | We've got data!
309 |
310 | **Note 1:** You can hook a [serial monitor](https://os.mbed.com/docs/latest/tutorials/serial-comm.html) up to the development board (baud rate 115,200) to see debugging messages.
311 |
312 | **Note 2:** No data in the **Data** tab? Verify that the gateway can receive messages. In the TTN console, go to your gateway, and see if any data comes through under the **Traffic** tab. If you see your device there but not under the device page, the keys are probably wrong.
313 |
314 | ##### Sending manually
315 |
316 | By default, the application sends data automatically. If you want to change this, remove this line from `main.cpp`:
317 |
318 | ```cpp
319 | ev_queue.call_every(TX_TIMER, send_message);
320 | ```
321 |
322 | Call `send_message` whenever you want (for example after the state of the sensor changes). Note that you still need to adhere to the duty cycle, so you may not be able to send data immediately.
323 |
324 | #### 3.6 - Relaying data back to the device
325 |
326 | You can also send data back to the device. Because LoRaWAN (in Class-A mode, which you're using here) is not continuously connected to the network, you need to wait for a receive (RX) window to occur to receive data. An RX window opens after a transmission. So you need to *send* to the network before you can receive a message. If you send a message from The Things Network to your device, the network automatically queues the message and delivers it in the next RX window.
327 |
328 | You can toggle the LED on your development board over LoRa. In the Online Compiler:
329 |
330 | 1. Open `main.cpp`.
331 | 1. Replace the `receive_message` function with:
332 |
333 | ```cpp
334 | static void receive_message() {
335 | static DigitalOut led(LED1, 0); // the LED under control, default value of 0
336 |
337 | int16_t retcode = lorawan.receive(LORAWAN_APP_PORT, rx_buffer,
338 | LORAMAC_PHY_MAXPAYLOAD,
339 | MSG_CONFIRMED_FLAG|MSG_UNCONFIRMED_FLAG);
340 |
341 | // ignore errors while retrieving
342 | if (retcode < 0) return;
343 |
344 | led = rx_buffer[0]; // set the value of the LED depending on the first byte in the message
345 |
346 | printf("Received %d bytes: ", retcode);
347 | for (uint8_t i = 0; i < retcode; i++) {
348 | printf("%x", rx_buffer[i]);
349 | }
350 | printf("\n");
351 | }
352 | ```
353 |
354 | **Note:** On some development boards, writing `0` to the LED turns them on. On others, writing `1` does this. It depends on the wiring of the board.
355 |
356 | 1. Compile, and flash the application.
357 | 1. When the device is back online, use the The Things Network console to queue a message. Go to your device page, and under **Downlink**, select port **21** and data `01`. Then press **Send**.
358 |
359 | Queuing a downlink message over port 21
360 |
361 | 1. After the next transmission, the LED toggles, and a message appears on the serial console. Try the same thing now by sending `0`.
362 |
363 | ### 4. Getting your data out of the The Things Network
364 |
365 | The system works and sends data in two directions, but the data is not stored anywhere. You can change that. The Things Network offers a data API to get the data out of the network. You can then store it on your own servers or forward it to a cloud service.
366 |
367 | For this tutorial, we built a small web application that listens for events from the movement sensors and shows an overview of all sensors. To use this application, you need a recent version of [Node.js](https://nodejs.org) installed on your computer.
368 |
369 | Demo application
370 |
371 | To build this application, first grab an access key from The Things Network:
372 |
373 | 1. Go to your application in the TTN console.
374 | 1. Locate your **Application ID**, and make note of it.
375 |
376 | 
377 |
378 | 1. Locate your **Access Key**, click the **show** button and make note of it, as well.
379 |
380 | 
381 |
382 | Now clone, the demo application, and run it.
383 |
384 | 1. [Download the demo application](https://github.com/ARMmbed/lora-docs/archive/master.zip), and extract it.
385 | 1. In the unzipped application, locate `ttn-node-app/server.js`, and paste your Application ID and Access Key on lines 1 and 2.
386 | 1. Open a terminal - or command prompt - and navigate to the folder where you unzipped the application.
387 | 1. Run:
388 |
389 | ```
390 | $ cd ttn-node-app
391 | $ npm install
392 | $ node server.js
393 | ```
394 |
395 | This shows:
396 |
397 | ```
398 | Connecting to the The Things Network data channel...
399 | Connected to The Things Network data channel
400 | Retrieving devices...
401 | Retrieved devices (2)
402 | Web server listening on port 5270!
403 | ```
404 |
405 | 1. Now, open a web browser, and navigate to http://localhost:5270 to see the application running.
406 |
407 | ### 5. Recap
408 |
409 | LoRa/LoRaWAN is a technology with which anyone can set up a network and start building long-range IoT devices with a relatively small investment. We hope this guide helped you get started, and we would love to see what you build with LoRa and Mbed.
410 |
411 | #### More material
412 |
413 | - [Webinar: getting started with LoRa using Arm Mbed and The Things Network](https://pages.arm.com/2017-10-29-webinar-registration.html).
414 | - [Mbed OS LoRaWAN stack documentation](https://os.mbed.com/docs/latest/reference/lorawan.html).
415 | - [Firmware updates over LoRaWAN](https://os.mbed.com/blog/entry/firmware-updates-over-lpwan-lora/).
416 | - [Presentations from The Things Conference](https://www.youtube.com/playlist?list=PLM8eOeiKY7JUhIyxWWU2-qziejDbBg-pf).
417 |
--------------------------------------------------------------------------------
/mkdocs.yml:
--------------------------------------------------------------------------------
1 | site_name: Getting started with LoRa on mbed
2 |
3 | docs_dir: docs
4 |
5 | pages:
6 | - ['index.md','LoRa on mbed']
7 | - ['intro-to-lora.md','Building your own private LoRa network']
8 |
--------------------------------------------------------------------------------
/ttn-node-app/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
3 |
--------------------------------------------------------------------------------
/ttn-node-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mbed-ttn-node-app",
3 | "version": "1.0.0",
4 | "description": "Simple web application showing data from The Things Network",
5 | "main": "server.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/armmbed/lora-docs.git"
12 | },
13 | "keywords": [
14 | "lora",
15 | "ttn",
16 | "the things network",
17 | "mbed",
18 | "lorawan"
19 | ],
20 | "author": "Jan Jongboom ",
21 | "license": "Apache-2.0",
22 | "bugs": {
23 | "url": "https://github.com/armmbed/lora-docs/issues"
24 | },
25 | "homepage": "https://github.com/armmbed/lora-docs#readme",
26 | "dependencies": {
27 | "express": "^4.16.2",
28 | "hbs": "^4.0.1",
29 | "socket.io": "^2.0.4",
30 | "ttn": "^2.3.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ttn-node-app/public/ARMmbedLogo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ttn-node-app/public/helper.js:
--------------------------------------------------------------------------------
1 | var notificationTo;
2 | function showNotification(msg) {
3 | clearTimeout(notificationTo);
4 |
5 | var el = document.querySelector('#notification');
6 | el.textContent = msg;
7 | el.style.opacity = 1;
8 | el.style.visibility = 'visible';
9 |
10 | notificationTo = setTimeout(function() {
11 | el.style.opacity = 0;
12 | el.style.visibility = 'hidden';
13 | }, 6000);
14 |
15 | el.onclick = function() {
16 | clearTimeout(notificationTo);
17 | el.style.opacity = 0;
18 | el.style.visibility = 'hidden';
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/ttn-node-app/public/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Lato');
2 |
3 | #header { margin-top: 20px; }
4 | #logo { width: 167px; }
5 | body {
6 | font-family: "Lato", sans-serif;
7 | margin: 0;
8 | padding: 0 20px;
9 | font-weight: 300;
10 | color: rgb(80, 79, 77);
11 | font-size: 16px;
12 | }
13 | h1 {
14 | background: linear-gradient(45deg, #0091BD, #002B49);
15 | color: white;
16 | font-weight: 400;
17 | font-size: 48px;
18 | margin: 20px -20px;
19 | padding: 30px 20px;
20 | }
21 | a {
22 | color: #0091BD;
23 | text-decoration: none;
24 | }
25 | a:hover { color: #333E48; }
26 | p, li {
27 | line-height: 23px;
28 | }
29 | h2 {
30 | font-weight: 300;
31 | }
32 | #sensors { padding: 0; margin-top: -20px; }
33 | #sensors li {
34 | display: flex;
35 | flex-direction: column;
36 | margin: 0;
37 | padding: 20px 0;
38 | border-bottom: solid 1px lightgray;
39 | }
40 | #sensors li p {
41 | margin: 0;
42 | }
43 | #sensors li label {
44 | display: inline-block;
45 | width: 100px;
46 | font-weight: bold;
47 | }
48 |
49 | #notification {
50 | position: fixed;
51 | bottom: 20px;
52 | background: rgba(0,0,0,0.6);
53 | color: white;
54 | border-radius: 10px;
55 | display: inline-block;
56 | padding: 10px 20px;
57 | cursor: pointer;
58 | transition: all 0.6s ease-out;
59 | left: 50%;
60 | transform: translateX(-50%);
61 | }
62 |
--------------------------------------------------------------------------------
/ttn-node-app/server.js:
--------------------------------------------------------------------------------
1 | let TTN_APP_ID = 'YOUR_APP_ID';
2 | let TTN_ACCESS_KEY = 'YOUR_ACCESS_KEY';
3 |
4 | const express = require('express');
5 | const app = express();
6 | const server = require('http').Server(app);
7 | const io = require('socket.io')(server);
8 | const hbs = require('hbs');
9 | const ttn = require('ttn');
10 |
11 | // Some options for express (node.js web app library)
12 | hbs.registerPartials(__dirname + '/views/partials');
13 | app.use(express.static(__dirname + '/public'));
14 | app.set('view engine', 'html');
15 | app.set('views', __dirname + '/views');
16 | app.engine('html', hbs.__express);
17 |
18 | TTN_APP_ID = process.env['TTN_APP_ID'] || TTN_APP_ID;
19 | TTN_ACCESS_KEY = process.env['TTN_ACCESS_KEY'] || TTN_APP_ID;
20 |
21 | // Store some state about all devices, you probably want to store this in a database
22 | let devices = {};
23 |
24 | // And handle requests
25 | app.get('/', function (req, res, next) {
26 | let d = Object.keys(devices).map(k => {
27 | let o = {
28 | devId: k,
29 | last_seen: new Date(devices[k].last_seen).toLocaleString(),
30 | state: devices[k].state
31 | };
32 | return o;
33 | })
34 | // Render index view, with the devices based on mapToView function
35 | res.render('index', { devices: d });
36 | });
37 |
38 | // Connect to TTN
39 | console.log('Connecting to the The Things Network data channel...');
40 |
41 | ttn.data(TTN_APP_ID, TTN_ACCESS_KEY).then(client => {
42 | client.on('uplink', (devId, payload) => {
43 | console.log('retrieved uplink', devId, payload);
44 |
45 | let device = devices[devId] = devices[devId] || {};
46 |
47 | if (payload.port === 21) { // PIR sensor data
48 | device.state = payload.payload_raw[0]; // check first byte
49 | device.last_seen = Date.now();
50 |
51 | // send to all connected browsers, so they can update their state
52 | io.emit('movement-change', devId, device.state);
53 | }
54 | });
55 |
56 | console.log('Connected to The Things Network data channel');
57 | console.log('Retrieving devices...');
58 | }).then(() => {
59 | return ttn.application(TTN_APP_ID, TTN_ACCESS_KEY);
60 | }).then(app => {
61 | return app.devices();
62 | }).then(ttn_devices => {
63 | console.log('Retrieved devices (' + ttn_devices.length + ')');
64 |
65 | for (let t of ttn_devices) {
66 | if (devices[t.devId]) continue;
67 |
68 | devices[t.devId] = {
69 | state: -1,
70 | last_seen: 0
71 | };
72 | }
73 |
74 | // Now we can start the web server
75 | server.listen(process.env.PORT || 5270, process.env.HOST || '0.0.0.0', function () {
76 | console.log('Web server listening on port %s!', process.env.PORT || 5270);
77 | });
78 | }).catch(err => {
79 | console.error('Could not authenticate with TTN...', err);
80 | });
81 |
82 |
--------------------------------------------------------------------------------
/ttn-node-app/views/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LoRaWAN intruder detection
6 |
7 |
8 |
9 |
10 |
11 |