Skip to content

Commit 91175a7

Browse files
Update README
This adds a lot more documentation, and reflects the fact that this library should now be usable for actual projects as well, not just for node-node prototypes.
1 parent 1b796c1 commit 91175a7

File tree

1 file changed

+309
-31
lines changed

1 file changed

+309
-31
lines changed

README.md

Lines changed: 309 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,327 @@
1-
Arduino-LMIC proof-of-concept library
2-
=====================================
1+
Arduino-LMIC library
2+
====================
33
This repository contains the IBM LMIC (LoraMAC-in-C) library, slightly
4-
modified to run in the Arduino environment, allowing using the SX1272
5-
LoRa tranceiver with an Arduino.
4+
modified to run in the Arduino environment, allowing using the SX1272,
5+
SX1276 tranceivers and compatible modules (such as some HopeRF RFM9x
6+
modules).
67

7-
This repository is just a proof-of-concept to send data between two
8-
SX1272 modules. It is not intended as a complete library and was not
9-
tested in a full LoraWAN setup with a gateway (though feel free to fork
10-
it and turn it into one if you want).
8+
This library mostly exposes the functions defined by LMIC, it makes no
9+
attempt to wrap them in a higher level API that is more in the Arduino
10+
style. To find out how to use the library itself, see the examples, or
11+
see the PDF file in the doc subdirectory.
1112

12-
If you want to actually use this code, note that it contains version 1.4
13-
of the library, but there are newer versions available already. Also,
14-
the LMIC library needs to be modified to not invert IQ signals, in order
15-
to allow device-to-device communication as used in the raw.ino example,
16-
at the same time breaking device-to-gateway communication.
13+
This library requires Arduino IDE version 1.6.6 or above, since it
14+
requires C99 mode to be enabled by default.
1715

18-
If you need device-to-device communication, make sure you reapply commit
19-
7561aa74c (Do not invert I/Q signals to allow communication between
20-
nodes), which was reverted in master.
16+
Installing
17+
----------
18+
To install this library:
2119

22-
At this time, this code needs an hourly build of the Arduino IDE (or
23-
1.6.6 once it is released), since that enables C99 code to be compiled.
20+
- install it using the Arduino Library manager ("Sketch" -> "Include
21+
Library" -> "Manage Libraries..."), or
22+
- download a zipfile from github using the "Download ZIP" button and
23+
install it using the IDE ("Sketch" -> "Include Library" -> "Add .ZIP
24+
Library..."
25+
- clone this git repository into your sketchbook/libraries folder.
26+
27+
For more info, see https://www.arduino.cc/en/Guide/Libraries
28+
29+
Features
30+
--------
31+
The LMIC library provides a fairly complete LoRaWAN Class A and Class B
32+
implementation, supporting the EU-868 and US-915 bands. Only a limited
33+
number of features was tested using this port on Arduino hardware, so be
34+
careful when using any of the untested features.
35+
36+
What certainly works:
37+
- Sending packets uplink, taking into account duty cycling.
38+
- Encryption and message integrity checking.
39+
- Receiving downlink packets in the RX2 window.
40+
- Custom frequencies and datarate settings.
41+
42+
What has not been tested:
43+
- Receiving downlink packets in the RX1 window.
44+
- Receiving and processing MAC commands.
45+
- Class B operation.
46+
- Over-the-air activation (OTAA / joining).
47+
48+
If you try one of these untested features and it works, be sure to let
49+
us know (creating a github issue is probably the best way for that).
50+
51+
Supported hardware
52+
------------------
53+
This library is intended to be used with plain LoRa transceivers,
54+
connecting to them using SPI. In particular, the SX1272 and SX1276
55+
families are supported (which should include SX1273, SX1277, SX1278 and
56+
SX1279 which only differ in the available frequencies, bandwidths and
57+
spreading factors). It has been tested with both SX1272 and SX1276
58+
chips, using the Semtech SX1272 evaluation board and the HopeRF RFM92
59+
and RFM95 boards (which supposedly contain an SX1272 and SX1276 chip
60+
respectively).
61+
62+
This library contains a full LoRaWAN stack and is intended to drive
63+
these Transceivers directly. It is *not* intended to be used with
64+
full-stack devices like the Microchip RN2483 and the Embit LR1272E.
65+
These contain a transceiver and microcontroller that implements the
66+
LoRaWAN stack and exposes a high-level serial interface instead of the
67+
low-level SPI transceiver interface.
68+
69+
This library is intended to be used inside the Arduino environment. It
70+
should be architecture-independent, so it should run on "normal" AVR
71+
arduinos, but also on the ARM-based ones, and some success has been seen
72+
running on the ESP8266 board as well. It was tested on the Arduino Uno,
73+
Pinoccio Scout, Teensy LC and 3.x, ESP8266.
74+
75+
This library an be quite heavy, especially if the fairly small ATmega
76+
328p (such as in the Arduino Uno) is used. In the default configuration,
77+
the available 32K flash space is nearly filled up (this includes some
78+
debug output overhead, though). By disabling some features in `config.h`
79+
(like beacon tracking and ping slots, which are not typically needed),
80+
some space can be freed up. Some work is underway to replace the AES
81+
encryption implementation, which should free up another 8K or so of
82+
flash in the future, making this library feasible to run on a 328p
83+
microcontroller.
2484

2585
Connections
2686
-----------
87+
To make this library work, your Arduino (or whatever Arduino-compatible
88+
board you are using) should be connected to the transceiver. The exact
89+
connections are a bit dependent on the transceiver board and Arduino
90+
used, so this section tries to explain what each connection is for and
91+
in what cases it is (not) required.
92+
2793
Note that the SX1272 module runs at 3.3V and likely does not like 5V on
28-
its pins, so make sure to use a level shifter, or an Arduino running at
29-
3.3V (this library was tested using a Pinoccio, which is an Arduino-like
30-
board running at 3.3V). The evaluation board has 100 ohm resistors in
94+
its pins (though the datasheet is not say anything about this, and my
95+
transceiver did not obviously break after accidentally using 5V I/O for
96+
a few hours). To be safe, make sure to use a level shifter, or an
97+
Arduino running at 3.3V. The Semtech evaluation board has 100 ohm resistors in
3198
series with all data lines that might prevent damage, but I would not
3299
count on that.
33100

34-
The pins to use are shown (and can be changed) in the pinmap in example
35-
.ino files. It seems that connecting RST is not needed, and RXTX output on the
36-
Arduino side (which controls the RX/TX antenna switch) can be connected
37-
to the antenna switch (pin FEM\_CTX on the evaluation board).
38-
Alternatively, you can connect the RXTX pin of the SX1272 directly to
39-
the antenna switch (by connecting RXTX and FEM\_CTX together on the
40-
evaluation board, or moving R2 to R1). I'm not sure why you wouldn't
41-
always want this connection to be made, but apparently there is a reason
42-
to control the switch from the Arduino instead of from the SX1272.
101+
### Power
102+
The SX127x transceivers need a supply voltage between 1.8V and 3.9V.
103+
Using a 3.3V supply is typical. The SX127x chips have various supply
104+
lines (*VR_ANA*, *VR_DIG* and *VR_PA*), all of which need the same
105+
supply voltage. Some modules (like the Semtech evaluation board) expose
106+
these pins separately, just connect them all together to a 3.3V source.
107+
Some boards, like the HopeRF boards just have a single supply pin
108+
labeled *3.3V*. Any *GND* pins need to be connected to the Arduino *GND*
109+
pin(s).
110+
111+
### SPI
112+
The primary way of communicating with the transceiver is through SPI
113+
(Serial Peripheral Interface). This uses four pins: MOSI, MISO, SCK and
114+
SS. The former three need to be directly connected: so MOSI to MOSI,
115+
MISO to MISO, SCK to SCK. Where these pins are located on your Arduino
116+
varies, see for example the "Connections" section of the [Arduino SPI
117+
documentation](SPI).
118+
119+
The SS (slave select) connection is a bit more flexible. On the SPI
120+
slave side (the transceiver), this must be connect to the pin
121+
(typically) labeled *NSS*. On the SPI master (Arduino) side, this pin
122+
can connect to any I/O pin. Most Arduinos also have a pin labeled "SS",
123+
but this is only relevant when the Arduino works as an SPI slave, which
124+
is not the case here. Whatever pin you pick, you need to tell thlibrary what pin you used through the pin mapping (see below).
125+
library what pin you used through the pin mapping (see below).
126+
127+
[SPI]: https://www.arduino.cc/en/Reference/SPI
128+
129+
### DIO pins
130+
The DIO (digitial I/O) pins on the transceiver board can be configured
131+
for various functions. The LMIC library uses them to get instant status
132+
information from the transceiver. For example, when a LoRa transmission
133+
starts, the DIO0 pin is configured as a TxDone output. When the
134+
transmission is complete, the DIO0 pin is made high by the transceiver,
135+
which can be detected by the LMIC library.
136+
137+
The LMIC library needs only access to DIO0, DIO1 and DIO2, the other
138+
DIOx pins can be left disconnected. On the Arduino side, they can
139+
connect to any I/O pin, since the current implementation does not use
140+
interrupts or other special hardware features (though this might be
141+
added in the feature, see also the "Timing" section).
142+
143+
In LoRa mode the DIO pins are used as follows:
144+
* DIO0: TxDone and RxDone
145+
* DIO1: RxTimeout
146+
147+
In FSK mode they are used as follows::
148+
* DIO0: PayloadReady and PacketSent
149+
* DIO2: TimeOut
150+
151+
Both modes need only 2 pins, but the tranceiver does not allow mapping
152+
them in such a way that all needed interrupts map to the same 2 pins.
153+
So, if both LoRa and FSK modes are used, all three pins must be
154+
connected.
155+
156+
The pins used on the Arduino side should be configured in the pin
157+
mapping in your sketch (see below).
158+
159+
### Reset
160+
The transceiver has a reset pin that can be used to explicitely reset
161+
it. The LMIC library uses this to ensure the chip is in a consistent
162+
state at startup. In practice, this pin can be left disconnected, since
163+
the transceiver will already be in a sane state on power-on, but
164+
connecting it might prevent problems in some cases.
165+
166+
On the Arduino side, any I/O pin can be used. The pin number used must
167+
be configured in the pin mapping (see below).
168+
169+
### RXTX
170+
The transceiver contains two separate antenna connections: One for RX
171+
and one for TX. A typical transceiver board contains an antenna switch
172+
chip, that allows switching a single antenna between these RX and TX
173+
connections. Such a antenna switcher can typically be told what
174+
position it should be through an input pin, often labeled *RXTX*.
175+
176+
The easiest way to control the antenna switch is to use the *RXTX* pin
177+
on the SX127x transceiver. This pin is automatically set high during TX
178+
and low during RX. For example, the HopeRF boards seem to have this
179+
connection in place, so they do not expose any *RXTX* pins and the pin
180+
can be marked as unused in the pin mapping.
181+
182+
Some boards do expose the antenna switcher pin, and sometimes also the
183+
SX127x *RXTX* pin. For example, the SX1272 evaluation board calls the
184+
former *FEM_CTX* and the latter *RXTX*. Again, simply connecting these
185+
together with a jumper wire is the easiest solution.
186+
187+
Alternatively, or if the SX127x *RXTX* pin is not available, LMIC can be
188+
configured to control the antenna switch. Connect the antenna switch
189+
control pin (e.g. *FEM_CTX* on the Semtech evaluation board) to any I/O
190+
pin on the Arduino side, and configure the pin used in the pin map (see
191+
below). It is not entirely clear why would *not* want the transceiver to
192+
control the antenna directly, though.
193+
194+
### Pin mapping
195+
As described above, most connections can use arbitrary I/O pins on the
196+
Arduino side. To tell the LMIC library about these, a pin mapping struct
197+
is used in the sketch file.
198+
199+
For example, this could look like this:
200+
201+
lmic_pinmap lmic_pins = {
202+
.nss = 6,
203+
.rxtx = LMIC_UNUSED_PIN,
204+
.rst = 5,
205+
.dio = {2, 3, 4},
206+
};
207+
208+
The names refer to the pins on the transceiver side, the numbers refer
209+
to the Arduino pin numbers (to use the analog pins, use constants like
210+
`A0`). For the DIO pins, the three numbers refer to DIO0, DIO1 and DIO2
211+
respectively. Any pins that are not needed should be specified as
212+
`LMIC_UNUSED_PIN`. The nss and dio0 pin is required, the others can
213+
potentially left out.
214+
215+
The name of this struct must always be `lmic_pins`, which is a special name
216+
recognized by the library.
217+
218+
Examples
219+
--------
220+
This library currently provides two examples:
221+
222+
- `ttn.ino` shows a basic transmission of a "Hello, world!" message
223+
using the LoRaWAN protocol. It contains some frequency settings and
224+
encryption keys intended for use with The Things Network, but these
225+
also correspond to the default settings of most gateways, so it
226+
should work with other networks and gateways as well. This example
227+
uses "personalization" (preconfiguring a device address and
228+
encryption keys), and does not employ over-the-air activation.
229+
230+
Reception of packets (in response to transmission, using the RX1 and
231+
RX2 receive windows is also supported).
232+
233+
- `raw.ino` shows how to access the radio on a somewhat low level,
234+
and allows to send raw (non-LoRaWAN) packets between nodes directly.
235+
This is useful to verify basic connectivity, and when no gateway is
236+
available, but this example also bypasses duty cycle checks, so be
237+
careful when changing the settings.
238+
239+
Timing
240+
------
241+
Unfortunately, the SX127x tranceivers do not support accurate
242+
timekeeping themselves (there is a sequencer that is *almost* sufficient
243+
for timing the RX1 and RX2 downlink windows, but that is only available
244+
in FSK mode, not in LoRa mode). This means that the microcontroller is
245+
responsible for keeping track of time. In particular, it should note
246+
when a packet finished transmitting, so it can open up the RX1 and RX2
247+
receive windows at a fixed time after the end of transmission.
248+
249+
This timing uses the Arduino `micros()` timer, which has a granularity
250+
of 4μs and is based on the primary microcontroller clock. For timing
251+
events, the tranceiver uses its DIOx pins as interrupt outputs. In the
252+
current implementation, these pins are not handled by an actual
253+
interrupt handler, but they are just polled once every LMIC loop,
254+
resulting in a bit inaccuracy in the timestamping. Also, running
255+
scheduled jobs (such as opening up the receive windows) is done using a
256+
polling approach, which might also result in further delays.
257+
258+
Fortunately, LoRa is a fairly slow protocol and the timing of the
259+
receive windows is not super critical. To synchronize transmitter and
260+
receiver, a preamble is first transmitted. Using LoRaWAN, this preamble
261+
consists of 8 symbols, of which the receiver needs to see 4 symbols to
262+
lock on. The current implementation tries to enable the receiver for 5
263+
symbol times at 1.5 symbol after the start of the receive window,
264+
meaning that a inacurracy of plus or minus 2.5 symbol times should be
265+
acceptable.
266+
267+
At the fastest LoRa setting supported by the tranceiver (SF5BW500) a
268+
single preamble symbol takes 128μs, so the receive window timing should
269+
be accurate within 320 μs. This is certainly within a crystal's
270+
accuracy, but using the internal oscillator is probably not feasible
271+
(which is 1% - 10% accurate, depending on calibration). This accuracy
272+
should also be feasible with the polling approach used, provided that
273+
the LMIC loop is run often enough.
274+
275+
It would be good to properly review this code at some point, since it
276+
seems that in some places some offsets and corrections are applied that
277+
might not be appropriate for the Arduino environment. So if reception is
278+
not working, the timing is something to have a closer look at.
279+
280+
The LMIC library was intended to connect the DIO pins to interrupt
281+
lines and run code inside the interrupt handler. However, doing this
282+
opens up an entire can of worms with regard to doing SPI transfers
283+
inside interrupt routines (some of which is solved by the Arduino
284+
`beginTransaction()` API, but possibly not everything). One simpler
285+
alternative could be to use an interrupt handler to just store a
286+
timestamp, and then do the actual handling in the main loop (this
287+
requires modifications of the library to pass a timestamp to the LMIC
288+
`radio_irq_handler()` function).
289+
290+
An even more accurate solution could be to use a dedicated timer with an
291+
input capture unit, that can store the timestamp of a change on the DIO0
292+
pin (the only one that is timing-critical) entirely in hardware.
293+
Unfortunately, timer0, as used by Arduino's `millis()` and `micros()`
294+
functions does not seem to have an input capture unit, meaning a
295+
separate timer is needed for this.
296+
297+
If the main microcontroller does not have a crystal, but uses the
298+
internal oscillator, the clock output of the transceiver (on DIO5) could
299+
be usable to drive this timer instead of the main microcontroller clock,
300+
to ensure the receive window timing is sufficiently accurate. Ideally,
301+
this would use timer2, which supports asynchronous mode (e.g. running
302+
while the microcontroller is sleeping), but that timer does not have an
303+
input capture unit. Timer1 has one, but it seems it will stop running
304+
once the microcontroller sleeps. Running the microcontroller in idle
305+
mode with a slower clock might be feasible, though. Instead of using the
306+
main crystal oscillator of the transceiver, it could be possible to use
307+
the transceiver's internal RC oscillator (which is calibrated against
308+
the transceiver crystal), or to calibrate the microcontroller internal
309+
RC oscillator using the transceiver's clkout. However, that datasheet is
310+
a bit vague on the RC oscillator's accuracy and how to use it exactly
311+
(some registers seem to be FSK-mode only), so this needs some
312+
experiments.
313+
314+
Downlink packets
315+
----------------
316+
Testing downlink packets is easy using the iot.semtech.com interface.
317+
However, note that it seems downlink packets from there are sent using
318+
the RX2 window and SF9BW125 settings, but LMIC defaults to SF12BW125 for
319+
the RX2 window (as indicated by the LoRaWAN specification). If downlink
320+
reception is not working, try changing the `DR_DNW2` parameter in
321+
`lorabase.h`.
43322

44323
License
45324
-------
46325
The source files in this repository are made available under the Eclipse
47326
Public License v1.0, except for the examples which use a more liberal
48327
license. Refer to each individual source file for more details.
49-

0 commit comments

Comments
 (0)