LoRA – DIY Model with Arduino
Here used the Lora SX1278 module with ESP8266 Wi-Fi module. This is quite an interesting project because first, you bring the sensor data from a remote location, where no internet facility is available, to the node where the internet is available.
And then you send that sensor data to an IoT platform with the help of a gateway. By doing so, you can monitor any sensor from any part of the world, provided you have an internet connection.
Apart from this, there are other projects as well, however, the projects which I have just mentioned, are undoubtedly very important projects, because you can design any project by modifying these projects.
You can see 4 buttons on the transmitter side Arduino. Using these very 4 buttons, I am going to control certain loads on the receiver side. For demonstration purposes, I have put 4 bulbs on the receiver’s side, which are connected to 4 relays. Besides lights, you can use any other 110/220Vac loads or use any other DC type loads.
Features:
1. Frequency Range: 868 / 915 MHz
2. Sensitivity up to -139dBm @Lora
3. Maximum output power: 20 dBm
4. 13mA@receiver mode
5. Sleep current <200 nA
6. Data transfer rate: @FSK,1.2-300 Kbps
7. @Lora TM, 0.018-37.5 Kbps
8. Lora TM, FSK, GFSK & OOK Modulation mode
9. Built-in ESD Protection
10. 127 dB Dynamic Range RSSI
11. Packet engine up to 256 bytes with FIFO and CRC
12. Hopping frequency
13. Built-in temperature sensor and low battery indicator
14. Excellent blocking immunity
15. Operating Temperature Range:-40 ~ + 85 °C
Applications:
A. Remote control
B. Remote meter reading
C. Home security alarm and remote keyless entry
D. Industrial control
E. Home automation remote sensing
F. Individual data records
G. Toys control
H. Sensor network
I. Tire pressure monitoring
J. Health monitoring
L. Wireless PC peripherals
M. Tag reading and writing
Lora Transmitter Circuit Diagram:
Lora Transmitter programming:
#include "SPI.h" #include "LoRa.h" #include "Adafruit_GFX.h" #include "Adafruit_SSD1306.h" byte msgCount = 0; byte localAddress = 0xBB; byte destination = 0xFF; long lastSendTime = 0; int interval = 50; // 4 buttons or switches int sw1 = 2; int sw2 = 4; int sw3 = 6; int sw4 = 8; int Sensor1 = 0; int Sensor2 = 0; int Sensor3 = 0; int Sensor4 = 0; int load1 = 0; int load2 = 0; int load3 = 0; int load4 = 0; boolean bflag = false; String outgoing; #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET -1 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); String Mymessage = ""; void setup() { Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); display.setTextColor(WHITE); pinMode(sw1, INPUT_PULLUP); pinMode(sw2, INPUT_PULLUP); pinMode(sw3, INPUT_PULLUP); pinMode(sw4, INPUT_PULLUP); Serial.println("LoRa Duplex"); if (!LoRa.begin(433E6)) { // initialize ratio at 915 MHz Serial.println("LoRa init failed. Check your connections."); while (true); // if failed, do nothing } Serial.println("LoRa init succeeded."); } void loop() { if (millis() - lastSendTime > interval) { Sensor1 = digitalRead(sw1); Sensor2 = digitalRead(sw2); Sensor3 = digitalRead(sw3); Sensor4 = digitalRead(sw4); Mymessage = Mymessage + !Sensor1 +"," + !Sensor2 + "," + !Sensor3 +"," + !Sensor4; sendMessage(Mymessage); delay(10); Mymessage = ""; lastSendTime = millis(); interval = random(50) + 100; } onReceive(LoRa.parsePacket()); } void sendMessage(String outgoing) { LoRa.beginPacket(); LoRa.write(destination); LoRa.write(localAddress); LoRa.write(msgCount); LoRa.write(outgoing.length()); LoRa.print(outgoing); LoRa.endPacket(); msgCount++; } void onReceive(int packetSize) { if (packetSize == 0) return; int recipient = LoRa.read(); byte sender = LoRa.read(); byte incomingMsgId = LoRa.read(); byte incomingLength = LoRa.read(); String incoming = ""; while (LoRa.available()) { incoming += (char)LoRa.read(); } if (incomingLength != incoming.length()) { //Serial.println("error: message length does not match length"); ; return; } if (recipient != localAddress && recipient != 0xFF) { // Serial.println("This message is not for me."); return; } String q = getValue(incoming, ',', 0); String r = getValue(incoming, ',', 1); String s = getValue(incoming, ',', 2); String t = getValue(incoming, ',', 3); load1 = q.toInt(); load2 = r.toInt(); load3 = s.toInt(); load4 = t.toInt(); String DisplayData = ""; DisplayData = DisplayData + load1 + "," + load2 + "," + load3 + "," + load4 ; //new code end //clear display display.clearDisplay(); display.setTextSize(2); display.setCursor(0,0); display.print("Status:"); display.setTextSize(3); display.setCursor(0, 28); display.print(DisplayData); display.display(); } String getValue(String data, char separator, int index) { int found = 0; int strIndex[] = { 0, -1 }; int maxIndex = data.length() - 1; for (int i = 0; i <= maxIndex && found <= index; i++) { if (data.charAt(i) == separator || i == maxIndex) { found++; strIndex[0] = strIndex[1] + 1; strIndex[1] = (i == maxIndex) ? i+1 : i; } } return found > index ? data.substring(strIndex[0], strIndex[1]) : ""; }
The VCC of the LoRa module is connected with the 3.3V of the Arduino.
The MISO Pin of the LoRa module is connected with the Arduino’s pin 12.
The MOSI pin is connected with the Arduino’s pin 11.
The SCLK pin of the LoRa module is connected with the Arduino’s pin 13.
The NSS pin is connected with the Arduino’s pin 10 and the ground pin of the LoRa module is connected with the Arduino’s GND.
4 switches are connected with the Arduino pins 2, 3, 4, and 5.
SSD1306 Oled display module SCL and SDA pins are connected with the Arduino’s A5 and A4 pins.
Lora Receiver Circuit Diagram:
On the receiver side, a 4-channel relay module is connected with the Arduino pins 2, 3, 4, and 5. While the connections of the SX1278 Lora module remain exactly the same.
#include "SPI.h" #include "LoRa.h" byte msgCount = 0; byte localAddress = 0xFF; byte destination = 0xBB; long lastSendTime = 0; int interval = 50; boolean flag1 = false; boolean flag2 = false; boolean flag3 = false; boolean flag4 = false; int RLY1=2; int RLY2=3; int RLY3=4; int RLY4=5; from the Transmitter int Sensor1 = 0; int Sensor2 = 0; int Sensor3 = 0; int Sensor4 = 0; int relay1Status; int relay2Status; int relay3Status; int relay4Status; String outgoing; String statusmessage = ""; void setup() { Serial.begin(9600); pinMode(RLY1,OUTPUT); pinMode(RLY2,OUTPUT); pinMode(RLY3,OUTPUT); pinMode(RLY4,OUTPUT); Serial.println("LoRa Duplex"); if (!LoRa.begin(433E6)) { Serial.println("LoRa init failed. Check your connections."); while (true); // if failed, do nothing } Serial.println("LoRa init succeeded."); } void loop() { if (millis() - lastSendTime > interval) { relay1Status = digitalRead(RLY1); relay2Status = digitalRead(RLY2); relay3Status = digitalRead(RLY3); relay4Status = digitalRead(RLY4); statusmessage = statusmessage + relay1Status + "," + relay2Status + "," + relay3Status + "," + relay4Status; sendMessage(statusmessage); delay(10); statusmessage = ""; lastSendTime = millis(); interval = random(50) + 100; } onReceive(LoRa.parsePacket()); } void sendMessage(String outgoing) { LoRa.beginPacket(); LoRa.write(destination); LoRa.write(localAddress); LoRa.write(msgCount); LoRa.write(outgoing.length()); LoRa.print(outgoing); LoRa.endPacket(); msgCount++; } void onReceive(int packetSize) { if (packetSize == 0) return; // read packet header bytes: int recipient = LoRa.read(); byte sender = LoRa.read(); byte incomingMsgId = LoRa.read(); byte incomingLength = LoRa.read(); String incoming = ""; while (LoRa.available()) { incoming += (char)LoRa.read(); } if (incomingLength != incoming.length()) { return; } // if the recipient isn't this device or broadcast, if (recipient != localAddress && recipient != 0xFF) { //Serial.println("This message is not for me."); ; return; } String q = getValue(incoming, ',', 0); String r = getValue(incoming, ',', 1); String s = getValue(incoming, ',', 2); String t = getValue(incoming, ',', 3); Sensor1 = q.toInt(); Sensor2 = r.toInt(); Sensor3 = s.toInt(); Sensor4 = t.toInt(); if((Sensor1 == 1)&&(flag1==false)) { digitalWrite(RLY1,HIGH); relay1Status = 1; Serial.println("Relay 1 is turned on"); flag1=true; } if((Sensor1 == 0)&&(flag1 ==true)) { digitalWrite(RLY1,LOW); relay1Status = 0; Serial.println("Relay 1 is turned off"); flag1=false; } if((Sensor2 == 1)&&(flag2==false)) { digitalWrite(RLY2,HIGH); relay2Status = 0; Serial.println("Relay 2 is turned on"); flag2=true; } if((Sensor2 == 0)&&(flag2 ==true)) { digitalWrite(RLY2,LOW); relay2Status = 0; Serial.println("Relay 2 is turned off"); flag2=false; } if((Sensor3 == 1)&&(flag3==false)) { digitalWrite(RLY3,HIGH); relay3Status = 1; Serial.println("Relay 3 is turned on"); flag3=true; } if((Sensor3 == 0)&&(flag3 ==true)) { digitalWrite(RLY3,LOW); relay3Status = 0; Serial.println("Relay 3 is turned off"); flag3=false; } if((Sensor4 == 1)&&(flag4==false)) { digitalWrite(RLY4,HIGH); relay4Status = 1; Serial.println("Relay 4 is turned on"); flag4=true; } if((Sensor4 == 0)&&(flag4 ==true)) { digitalWrite(RLY4,LOW); relay4Status = 0; Serial.println("Relay 4 is turned off"); flag4=false; } incoming = ""; } String getValue(String data, char separator, int index) { int found = 0; int strIndex[] = { 0, -1 }; int maxIndex = data.length() - 1; for (int i = 0; i <= maxIndex && found <= index; i++) { if (data.charAt(i) == separator || i == maxIndex) { found++; strIndex[0] = strIndex[1] + 1; strIndex[1] = (i == maxIndex) ? i+1 : i; } } return found > index ? data.substring(strIndex[0], strIndex[1]) : ""; }
Download the following libraries.