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.