Lesson 1: Build a Simple Arduino LoRa Node In 10 Minutes

Last Updated on 15 Sep 2017


Lately LoRaWAN has been increasingly famous in the area of Internet of Things (IoT) applications. Many applications in our daily lives require remote control or monitoring, but at the same time high power consumption or data streaming is not necessary. This is where LoRaWAN came in and take its role due to its feature – low power, low payload.

In LoRaWAN, LoRa end device (also called LoRa node) is the component that gathers useful information or data then send those data using LoRa protocol. Usually, they are embedded circuit with built-in LoRa technology and attached to 1 or more sensors. Besides that, they are normally designed to consume very low power, meaning they can be powered by tiny coin cell battery but still able to operate for years! (That is the original idea of LoRaWAN).

LoRa nodes are implemented in most low power wireless sensor network applications such as irrigation systems, smart metering, smart cities, smartphone detection, building automation, etc. There are a lot of industrial grade LoRa sensors availabe in the market, but in this tutorial we will teach you how to build your own LoRa node!


In this tutorial, you will learn:

  • How to build a LoRa Node using Cytron LoRa-RFM Shield + Arduino
  • How to Create an account in The Things Network
  • How to Add an Application
  • How to register your LoRa Node to the application
  • How to Activate your LoRa Node


  1. Cytron LoRa-RFM Shield
  2. CT-UNO or other Arduino-compatible boards


  1. Arduino IDE


Build LoRa Node from zero

  1. The build is easy. Prepare CT-UNO (or other Arduino-compatible board).
  2. Plug the Cytron LoRa-RFM shield onto CT-UNO.
  3. Install the antenna.

Hardware setup is done, but we are not done with its firmware yet. Here we are going to use famous Arduino IDE to build firmware for it.

Arduino IDE basic setups for LoRa Node

  1. Install latest Arduino IDE from the link provided above.
  2. Open Arduino IDE. Now we are going to include necessarry libraries to build firmware for our LoRa node. First of all, download this ZIP file. Then in Arduino IDE, go to Sketch -> Include Library -> Add .ZIP library, select the downloaded ZIP file then open.
  3. Start a new sketch. Copy the code below and paste it into new sketch.
    #include <lmic.h>
    #include <hal/hal.h>
    #include <SPI.h>
    // LoRaWAN NwkSKey, network session key
    static const PROGMEM u1_t NWKSKEY[16] = { 0xAE, 0xBD, 0x9B, 0xBC, 0x43, 0x41, 0xFB, 0x47, 0x3D, 0xA5, 0x8D, 0x0D, 0x48, 0x98, 0xEF, 0xCF };
    // LoRaWAN AppSKey, application session key
    static const u1_t PROGMEM APPSKEY[16] = { 0xE1, 0x51, 0x0F, 0xB1, 0x59, 0x4C, 0xC8, 0xD7, 0xAA, 0x43, 0xAC, 0xE7, 0xE2, 0xBC, 0x5F, 0x1B };
    // LoRaWAN end-device address (DevAddr)
    static const u4_t DEVADDR = { 0x260314F7 };
    // These callbacks are only used in over-the-air activation, so they are
    // left empty here (we cannot leave them out completely unless
    // DISABLE_JOIN is set in config.h, otherwise the linker will complain).
    void os_getArtEui (u1_t* buf) { }
    void os_getDevEui (u1_t* buf) { }
    void os_getDevKey (u1_t* buf) { }
    static uint8_t mydata[] = "HI,Lora World!";
    static osjob_t sendjob;
    // Schedule data trasmission in every this many seconds (might become longer due to duty
    // cycle limitations).
    // we set 10 seconds interval
    const unsigned TX_INTERVAL = 10;
    // Pin mapping according to Cytron LoRa Shield RFM
    const lmic_pinmap lmic_pins = {
    	.nss = 10,
    	.rxtx = LMIC_UNUSED_PIN,
    	.rst = 7,
    	.dio = {2, 5, 6},
    void onEvent (ev_t ev) {
    	Serial.print(": ");
    	switch(ev) {
    		case EV_TXCOMPLETE:
    			Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
    			// Schedule next transmission
    			os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
    			Serial.println(F("Unknown event"));
    void do_send(osjob_t* j){
    	// Check if there is not a current TX/RX job running
    	if (LMIC.opmode & OP_TXRXPEND) {
    		Serial.println(F("OP_TXRXPEND, not sending"));
    	} else {
    		// Prepare upstream data transmission at the next possible time.
    		LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0);
    		Serial.println(F("Packet queued"));
    	// Next TX is scheduled after TX_COMPLETE event.
    void setup() {
    	// LMIC init
    	// Reset the MAC state. Session and pending data transfers will be discarded.
    	// Set static session parameters. Instead of dynamically establishing a session
    	// by joining the network, precomputed session parameters are be provided.
    	uint8_t appskey[sizeof(APPSKEY)];
    	uint8_t nwkskey[sizeof(NWKSKEY)];
    	memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
    	memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
    	LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);
    	// Select frequencies range
    	// Disable link check validation
    	// TTN uses SF9 for its RX2 window.
    	LMIC.dn2Dr = DR_SF9;
    	// Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library)
    	// Start job
    void loop() {

Now we leave the arduino code behind. Later we are going to modify some of the lines in the coding but we will need some info first. Let’s register account at The Things Network to get those info!

Create an Account at The Things Network (TTN):

Why do we need this account under The TTN? Because later on, we are going to use the platform provided by this organisation to view and monitor our LoRa Node. LoRa node is the one that gathers information from sensors then transmit the data using LoRa Technology. But transmit to where? Where can we see those information?

For those who are new to LoRaWAN, these data eventually will reach what we called Network server, server which will handle these LoRa data. There are a lot of 3rd party companies or organisations which provide this service but this comes with price as well. But luckily TTN offers this service free. All we need to do is register an account under The Things Network. Once we register account, we can register our LoRa nodes under the account. So whatever data sent by registered LoRa nodes, once reach TTN network server, will be recognised by TTN, therefore the data will be shown in TTN dashboard/platform under your account. For how these data can be channelled to TTN network server, this is the job of another LoRaWAN component – LoRa Gateway, which will be discussed in next tutorial.

Let’s start creating an account!

  1. Go to account.thethingsnetwork.org and click create an account. You will receive confirmation email to activate your account.
  2. Select CONSOLE from the top menu.
  3. Select APPLICATIONS to start registration of LoRa node.

Add an Application

Devices need to be registered with an application to communicate with. Let’s add one.

  1. On Applications page, click .
  2. The following screen will appear.
  3. For Application ID, choose a unique ID of lower case, alphanumeric characters and nonconsecutive – and _.
  4. For Description, enter anything you like.
  5. For Application EUI, we can leave it to let TTN generate for us.
  6. For Handler registration, we are going to use ttn-handler-brazil.
  7. Click Add application at the bottom of screen to finish.

You will be redirected to the newly added application.

Register your Device

You are now ready to register your device to the application.

  1. On the Applications > Your Application ID page, scroll down to DEVICES.
  2. In DEVICES category, click .
  3. You will come to the page as shown in the following.
  4. For Device ID, choose a – for this application – unique ID of lower case, alphanumeric characters and nonconsecutive – and _.
  5. For Device EUI, you can let it to be randomly generated.
  6. Leave the App Key to be randomly generated.
  7. Leave the default App EUI selected.
  8. Click Register to finish. (You will be redirected to the newly registered device)

Activate your Device

In LoRaWAN, to secure the data traffic, each LoRa node will use so called session keys to protect the content of sent data. And the session keys will be used to encrypt the data, and they are provided by network server. When the lora packets/data reach network server, network server will use these session keys to identify this LoRa node belongs to who, that’s we need to register our device to an account first.

There are 2 types of activation, Over The Air Activation (OTAA) and Activation By Personalization (ABP).

  • In OTAA, the device will use the generated App Key to request session keys from network server, and each request will result in different keys. App Key can be generated after device registration.
  • In ABP, session keys are fixed and have to be hard-coded into devices. In TTN, you set or generate the session keys via the console and hard-code them on your device. Device will use those keys forever for any data tranmission unless we hard code different set of session keys into them.

In this tutorial, we will be using ABP instead of OTAA. If you want to explore later, you can try OTAA.

  1. In the newly registered device page (Applications > Your Application ID > Devices > Your Device ID), choose Settings from menu located on top-right.
  2. Change activation method from OTAA to ABP
  3. At the same page, uncheck Frame Counter Checks box as well as shown in picture below to disable frame counter check for testing purpose.
  4. Click Save at the bottom of the page
  5. You will see 2 session keys generated for this device, Network Session Key and Application Session Key. These 2 keys will be used in Arduino Coding. (We said in ABP, session keys are fixed and have to be hard-coded into devices. Remember?)
  6. You can click on small eye icon in each keys to view the keys, initially they are hidden with dots.

Let’s back to Arduino

At this point, we are done with device registration. Let’s activate the device and let it up and running.

  1. There are 3 infos we need to apply to Arduino coding: network session keys, app session keys and finally device address.
  2. For Network session key press <> to show the msb hex decimal value copy directly and paste to your arduino code.
  3. For App Session key press <> to show the msb hex decimal value copy directly and paste to your arduino code.
  4. For Device Address adding copy and paste to your arduino code, note that you needed to add 0x.
  5. Below is the example:
  6. Click upload to upload the code to Arduino. Firmware is completed.

What else?

In the future, we will be monitoring the data of flow of LoRa Node in dashboard. Just go to Device page of each device, choose Data from top-menu from top-right corner and start viewing the data.

The example:

In dashboard, hex code of each character will be displayed. Therefore, the sentence “HI,Lora World!” with total of 14 characters will be displayed in HEX format (14 HEX characters). ‘H’ to 0x48, ‘I’ to 0x49, ‘,’ to 0x2C, and so forth. You can visit this ascii table for reference.

Congratulations, you have built yourself first LoRa Node! To test its functionality, you are going to have a LoRa Gateway in your area and it is configure to forward LoRa packets to TTN network server. Let’s go to next tutorial Lesson 2: Setting up a Raspberry Pi 3 LoRa Gateway with HAT-LRGW-915 to build your own LoRa Gateway!

If you have any questions regarding to this tutorial, please kindly post them in our forum.


  1. The Things Network Documentations
  2. Arduino LoRaWAN library
  3. Arduino Source Code for LoRa Node

Related Post

LoRa in Malaysia? Probably in Indonesia too?

Together, Cytron and Atilze Enabling IoT

Leave a Reply

Your email address will not be published. Required fields are marked *