Arduino Nano to Server using IOTIF LoRa

Arduino Nano to Server using IOTIF LoRa

Summary

Discover how the Arduino Nano, combined with IoTIF LoRa, opens up endless possibilities for connecting devices to a server seamlessly. In this blog, we introduce the concept of LoRa routers and delve into the power of Arduino Nano, a compact yet versatile microcontroller. We'll guide you through creating a sender program, enabling you to transmit data effortlessly. Join us on this exciting journey to explore the potential of LoRa technology and revolutionize your IoT projects. Get ready to embrace the future of connectivity!

Introduction:

In this tutorial, we will learn how to connect the LORA Module to the Arduino Nano. We will use Arduino Nano, and Lora to create a transmitter and receiver for data transmission and reception respectively. The tutorial will provide step-by-step instructions on how to connect the LORA Module to the Arduino Nano. In this we will explain how to use these components to create a transmitter and receiver for data transmission and reception. It also includes explaination about how to setup dragino router and get started with node to server communication using LoRa modules 

 

read more : Arduino Nano Node to Node comunication using IOTIF LoRa

LoRa Router

LoRa Router LPS8: The LPS8 is an open source LoRaWAN Gateway. It lets you bridge LoRa wireless network to an IP network via WiFi, Ethernet. The LoRa wireless allows users to send data and reach extremely long ranges at low data-rates 

Router Setting:

WiFi Credentials at first boot: 

SSID: dragino-xxxxxx 
Password: dragino+dragino 

You can use a PC to connect to this WiFi network. The PC will get an IP address 10.130.1.xxx and the LPS8 has the default IP 10.130.1.1. 

Web Interface: Open a browser on the PC and type in the LPS8 ip address (depends on your connect method) http://10.130.1.1/ (Access via WiFi AP network) 
You will see the login interface of LPS8 as shown below. 

 The account details for Web Login are:  

Username: root 

Password: dragino 

 
Access the Internet as a WiFi Client: In the WiFi Client Mode, LPS8 acts as a WiFi client and gets DHCP from an upstream router via WiFi.  

The settings for WiFi Client is under page System → WiFi → WiFi WAN Client Settings 

 In the WiFi Survey Choose the WiFi AP, and input the Passphrase then click Save & Apply to connect. 

 

read more : Top 10 Robotic Projects for Beginners

Check Internet connection In the Home page, we can check the Internet connection.  

‚ěĘ GREEN Tick : This interface has Internet connection. ¬†

‚ěĘ Yellow Tick : This interface has IP address but don‚Äôt use it for internet connection.¬†

¬†‚ěĘ RED Cross : This interface doesn‚Äôt connected¬†

MQTT setup in LoRa:

Click on LoRaWAN - Change the service provider to Built-in for ABP Decode to MQTT and press save&Apply as shown in the below image 

 

read more : Top 10 Arduino Projects for Beginners

 

- For MQTT Server we can use freely available server like Hive MQ with the below mentioned credentials  

 

- Open MQTT Client and enter the Broker credentials¬†as mentioned below Broker Address ‚Äď broker.hivemq.com ¬† Broker Port ‚Äď 1883¬†

Device Setup:

Go to LoRa -> ABP Decryption Here we will need to add keys which have to be unique for every LoRa module. for general use we can change the last digit of the keys making them unique and it makes the tracking easier. 

After adding all the keys press ADD_KEY and the newly created device key will be added to the below table and same can be used for programming new LoRa Device.  

 

read more : Top 10 Arduino Projects to Get Started With

Go to MQTT-> Channels  
Add the Dev ID which you just created as the Local ID and Remote ID both of which can be given same ID for convenience and click on ADD_CHAN 

Arduino nano:

STEP 1(Hardware connection):

Let us first setup the transmitter part first. The transmitter part contains Arduino Nano Board, DHT11 Humidity & Temperature Sensor and LoRa Module. Assemble the connection between Arduino nano and DHT sensor as shown in the table below: 

Arduino nano 

DHT11 Sensor 

5 v 

VCC 

GND 

GND 

Digital Pin 7 

Out 

 

And the connection between Lora and Arduino nano: 

 

Lora module 

Arduino nano 

2,3,4,5,6,7,8,9 (8 Pin connector) 

Keypad connector (2,3,4,5,6,7,8,9) 

4 Pin connector (G, 5V, 10, 11) 

4 Pin connector (G, 5V, 10, 11) 

4 Pin connector (G, 5V, 12, 13) 

4 Pin connector (G, 5V, 12, 13) 

  

 

STEP 2(downloading the libraries):

Connect your Arduino nano with DHT11 Sensor. For DHT11 sensor, install the dht library and for send the sensor readings to gateway, install the lmic library using the Library Manager in the Arduino IDE. Go to Sketch > Include Library > Manage Libraries and search for library name in the library manager. 

 

read more : What is Arduino Nano

 

STEP 3 (Explanation of the program):

Explanation:

Including the necessary libraries: The code includes several libraries such as lmic.h, hal/hal.h, SPI.h, and DHT.h which are required for LoRaWAN communication and other functionalities. 

Defining the constant: The code defines the type and digital pin of DHT sensor and define the Lora module. The pin mapping for the specific hardware being used is defined using the lmic_pinmap structure. This structure specifies the pins used for NSS (chip select), RXTX (not used), RST (reset), and DIO (digital input/output) operations. The LoRaWAN network session key (NWKSKEY), application session key (APPSKEY), and device address (DEVADDR) are defined.  

Create necessary objects and functions: It defines the DHT sensor object called dht. The onEvent() function is a state machine event handler that handles different events triggered by the LMIC library during the LoRaWAN communication process. It prints out the event name to the serial monitor. The do_send() function is responsible for transmitting data. It reads temperature and humidity values from the DHT sensor, converts them to strings, and constructs a JSON payload containing the temperature and humidity values. If there is no ongoing transmission (OP_TXRXPEND is not set), the payload is sent using LMIC_setTxData2(). 

Setup Function: The setup() function initializes the serial communication, DHT sensor, and LMIC library. The network session key, application session key, and device address are set using LMIC_setSession(). Depending on the LoRaWAN region configuration (CFG_eu868 or CFG_us915), the channel frequencies and data rates are set using LMIC_setupChannel() and LMIC_enableChannel(). The link check mode and downlink data rate are also configured using LMIC_setLinkCheckMode() and LMIC_setDrTxpow() respectively. Finally, the do_send() function is called to send the initial message. 

Loop Function: The loop() function is called repeatedly after the setup() function. It runs the LMIC library's event loop using os_runloop_once(). If the SEND_BY_BUTTON flag is enabled and a button connected to pin 0 is pressed, it triggers a message transmission by calling do_send(). 

Sender program:


#include  

#include  

#include  

#include  

  

#define DHTPIN 7 // Digital pin connected to the DHT sensor  

#define DHTTYPE DHT11 //DHT sensor type 

DHT dht(DHTPIN, DHTTYPE);   

  

#define SEND_BY_BUTTON 0  // Send a message when button "0" is pressed 

#define SEND_BY_TIMER 1   // Send a message every TX_INTERVAL seconds 

// 018229BB  |  BFF2CA2C7191F895365CCF822C3224D1  |  2541B4A7145935927393358617651B9B  |  Dragino_LHT65 

// LoRaWAN NwkSKey, network session key 

  

static const PROGMEM u1_t NWKSKEY[16] = { 0x2B,0x7E,0x15,0x16,0x28,0xAE,0xD2,0xA6,0xAB,0xF7,0x15,0x88,0x09,0xCF,0x4F,0x88 }; 

  

static const u1_t PROGMEM APPSKEY[16] = { 0x2B,0x7E,0x15,0x16,0x28,0xAE,0xD2,0xA6,0xAB,0xF7,0x15,0x88,0x09,0xCF,0x4F,0x87 }; 

  

static const u4_t DEVADDR = 0x3230EE75; 

  

void os_getArtEui(u1_t* buf) {} 

void os_getDevEui(u1_t* buf) {} 

void os_getDevKey(u1_t* buf) {} 

static osjob_t sendjob; 

  

// Pin mapping for the SparkX ESP32 LoRa 1-CH Gateway 

const lmic_pinmap lmic_pins = { 

  .nss = 10, 

  .rxtx = LMIC_UNUSED_PIN, 

  .rst = 9, 

  .dio = { 2,3,4 }, 

}; 

  

// If send-by-timer is enabled, define a tx interval 

#ifdef SEND_BY_TIMER 

#define TX_INTERVAL 3  // Message send interval in seconds 

#endif 

unsigned int last_sent_time = 0; 

  

// State machine event handler 

void onEvent(ev_t ev) { 

  Serial.print(os_getTime()); 

  Serial.print(": "); 

  switch (ev) { 

    case EV_SCAN_TIMEOUT: 

      Serial.println(F("EV_SCAN_TIMEOUT")); 

      break; 

    case EV_BEACON_FOUND: 

      Serial.println(F("EV_BEACON_FOUND")); 

      break; 

    case EV_BEACON_MISSED: 

      Serial.println(F("EV_BEACON_MISSED")); 

      break; 

    case EV_BEACON_TRACKED: 

      Serial.println(F("EV_BEACON_TRACKED")); 

      break; 

    case EV_JOINING: 

      Serial.println(F("EV_JOINING")); 

      break; 

    case EV_JOINED: 

      Serial.println(F("EV_JOINED")); 

      break; 

    case EV_RFU1: 

      Serial.println(F("EV_RFU1")); 

      break; 

    case EV_JOIN_FAILED: 

      Serial.println(F("EV_JOIN_FAILED")); 

      break; 

    case EV_REJOIN_FAILED: 

      Serial.println(F("EV_REJOIN_FAILED")); 

      break; 

    case EV_TXCOMPLETE: 

      digitalWrite(LED_BUILTIN, LOW);  // Turn off LED after send is complete 

      Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); 

      if (LMIC.txrxFlags & TXRX_ACK) 

        Serial.println(F("Received ack")); 

      if (LMIC.dataLen) { 

        Serial.println(F("Received ")); 

        Serial.println(LMIC.dataLen); 

        Serial.println(F(" bytes of payload")); 

      } 

#ifdef SEND_BY_TIMER 

      // Schedule the next transmission 

      os_setTimedCallback(&sendjob, sec2osticks(TX_INTERVAL), do_send); 

#endif 

      break; 

    case EV_LOST_TSYNC: 

      Serial.println(F("EV_LOST_TSYNC")); 

      break; 

    case EV_RESET: 

      Serial.println(F("EV_RESET")); 

      break; 

    case EV_RXCOMPLETE: 

      // data received in ping slot 

      Serial.println(F("EV_RXCOMPLETE")); 

      break; 

    case EV_LINK_DEAD: 

      Serial.println(F("EV_LINK_DEAD")); 

      break; 

    case EV_LINK_ALIVE: 

      Serial.println(F("EV_LINK_ALIVE")); 

      break; 

    default: 

      Serial.println(F("Unknown event")); 

      // Serial.println((unsigned) ev); 

      break; 

  } 

} 

  

// Transmit data from mydata 

void do_send(osjob_t* j) { 

  float temperature = dht.readTemperature(); 

  float humidity = dht.readHumidity(); 

  delay(10); 

  int count = 0; 

  if (LMIC.opmode & OP_TXRXPEND) { 

    Serial.println(F("OP_TXRXPEND, not sending")); 

  } else { 

  char temperatureStr[6]; 

  char humidityStr[6]; 

  dtostrf(temperature, 4, 2, temperatureStr); 

  dtostrf(humidity, 4, 2, humidityStr); 

  

  char payload[50]; 

  snprintf(payload, sizeof(payload), "{\"temperature\":%s,\"humidity\":%s}", temperatureStr, humidityStr); 

    LMIC_setTxData2(1, payload, sizeof(payload) - 1, 0); 

    Serial.println(F("Packet queued")); 

  } 

} 

void setup() { 

  Serial.begin(9600); 

  dht.begin(); 

  delay(500); 

  Serial.println("Starting: "); 

  os_init(); 

  Serial.println("After os_init: "); 

  LMIC_reset(); 

  Serial.println("after lmic reset: "); 

  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); 

  

  Serial.println("after lmic set session: "); 

#if defined(CFG_eu868) 

  LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI);  // g-band 

#elif defined(CFG_us915) 

  for (int b = 0; b < 8; ++b) { 

    LMIC_disableSubBand(b); 

  } 

  LMIC_enableChannel(17); 

#endif 

  LMIC_setLinkCheckMode(0); 

  LMIC.dn2Dr = DR_SF9; 

  LMIC_setDrTxpow(DR_SF12, 19); 

  do_send(&sendjob); 

} 

  

void loop() { 

  os_runloop_once(); 

#ifdef SEND_BY_BUTTON 

  if (digitalRead(0) == LOW) { 

    while (digitalRead(0) == LOW) 

      ; 

    do_send(&sendjob); 

  } 

#endif 

} 

MQTT Broker:

Go to the Hive MQ Client server - MQTT Websocket Client (hivemq.com) 

Change the host to broker.hivemq.com and click on connect  
 

Select Add new Subscription topic and enter the device ID and clickon Subscribe 

As soon as you add the topic you should be able to see the data in Hex formate as shown in the below image. You use any online tool and convert the Hex to String acccording to you use case. 

 

read more : What is Arduino UNO 
 

Conclusion:

In this tutorial we have discussed about using IOTIF LoRa for sending and receiving data with both Arduino Nano and Raspberry Pi on IOTIF, and also how send data to the Server usnig Arduino Nano, IOTIF LoRa and Dragino router. 

You may also like to read

Frequently Asked Questions

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.

You may also like to read