Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
vinay y.n
Published © GPL3+

Single Channel LoRa Gateway using Wio E5 LoRa and Blynk

Single channel LoRaWAN gateway using Seeed studio Wio-E5 Module, ESP8266, And Blynk.

IntermediateProtip9 hours3,324
Single Channel LoRa Gateway using Wio E5 LoRa and Blynk

Things used in this project

Hardware components

Seeed Studio Wio-E5 Dev Kit
×2
Seeed Studio XIAO SAMD21 (Pre-Soldered) - Seeeduino XIAO
Seeed Studio XIAO SAMD21 (Pre-Soldered) - Seeeduino XIAO
×1
Silicon Labs Si7051
×1
6 DOF Sensor - MPU6050
DFRobot 6 DOF Sensor - MPU6050
×1
Grove - OLED Display 1.12'' V2
Seeed Studio Grove - OLED Display 1.12'' V2
×1
AA Batteries
AA Batteries
×1
USB-A to Mini-USB Cable
USB-A to Mini-USB Cable
×1

Software apps and online services

Arduino IDE
Arduino IDE
Blynk
Blynk

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Multitool, Screwdriver
Multitool, Screwdriver

Story

Read more

Schematics

Transmiiter Part Connection Diagram

Receiver Connection Diagram

Code

Transmiiter Part Code

C/C++
Multiple Libraries are Required to compiling the code
#include <Arduino.h>
#include <Wire.h>
#include "ClosedCube_Si7051.h"
#include "MPU6050.h"
ClosedCube_Si7051 si7051;
MPU6050 accelgyro;
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif

int data1=0;
int data2=0;
int data3=0; 
int data4=0; 
int16_t ax, ay, az;
int16_t gx, gy, gz;
#define OUTPUT_READABLE_ACCELGYRO
static char recv_buf[512];
static bool is_exist = false;
int a_x,a_y,a_z;

static int at_send_check_response(char *p_ack, int timeout_ms, char *p_cmd, ...)
{
    int ch = 0;
    int index = 0;
    int startMillis = 0;
    va_list args;
    memset(recv_buf, 0, sizeof(recv_buf));
    va_start(args, p_cmd);
    Serial1.printf(p_cmd, args);
    Serial.printf(p_cmd, args);
    va_end(args);
    delay(200);
    startMillis = millis();
 
    if (p_ack == NULL)
    {
        return 0;
    }
 
    do
    {
        while (Serial1.available() > 0)
        {
            ch = Serial1.read();
            recv_buf[index++] = ch;
            Serial.print((char)ch);
            delay(2);
        }
        if (strstr(recv_buf, p_ack) != NULL)
        {
            return 1;
        }
    } while (millis() - startMillis < timeout_ms);
    return 0;
}
 
static int node_send(uint32_t timeout)
{
   
    static uint16_t count = 0;
    int ret = 0;
    char data[32];
    char cmd[128];
    
    memset(data, 0, sizeof(data));
    sprintf(data, "%04X,%04X,%04X,%04X", data1, data2, data3,data4);
    sprintf(cmd, "AT+TEST=TXLRPKT,\"5345454544%s\"\r\n", data);
    ret = at_send_check_response("TX DONE", 2000, cmd);
    if (ret == 1)
    {
        Serial.print("Sent successfully!\r\n");
    }
    else
    {
        Serial.print("Send failed!\r\n");
    }
    data1 = si7051.readTemperature();
    data2 = a_z;
    data3 = 100;
    data4 = 200;
    
    return ret;
}
 
void setup(void)
{
    Serial.begin(115200);
    si7051.begin(0x40); // default I2C address is 0x40 and 14-bit measurement resolution
    Serial1.begin(9600);
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif
    accelgyro.initialize();
    uint16_t error;
    char errorMessage[256];
     if (at_send_check_response("+AT: OK", 100, "AT\r\n"))
    {
        is_exist = true;
        at_send_check_response("+MODE: TEST", 1000, "AT+MODE=TEST\r\n");
        at_send_check_response("+TEST: RFCFG", 1000, "AT+TEST=RFCFG,866,SF12,125,12,15,14,ON,OFF,OFF\r\n");
        delay(200);
    }
    else
    {
        is_exist = false;
        Serial.print("No E5 module found.\r\n");
    }
     
}
 
void loop(void)
{
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
    Serial.print("Sensor data");
    Serial.print(ax);
    Serial.print(",");
    Serial.print(ay);
     Serial.print(",");
     Serial.print(az);
    Serial.println();

    a_x = (ax+ay+az);
    a_y = sqrt(a_x);
    a_z = ((az)/ay);
   
    Serial.print("x:");
    Serial.print(a_z);
    Serial.println();
      
    if (is_exist)
    {
        node_send(2000);
        delay(500);    
    }
}

Receiver Part Code

C/C++
Multiple Libraries required to compile the code
#include <Arduino.h>
#define BLYNK_TEMPLATE_ID "Your Blynk Template ID"
#define BLYNK_DEVICE_NAME "Your Blynk Device Name"
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
static char recv_buf[512];
static bool is_exist = false;
int RXPin = D6;
int TXPin = D5;
SoftwareSerial E5(RXPin, TXPin);
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
char auth[] = "Blynk Device authentication code";
char ssid[] = "Your Wi-Fi Name";
char pass[] = "Your Wi-Fi Password";
BlynkTimer timer;
WidgetLCD lcd(V1);
WidgetLCD lcd2(V3);
//////////////////////////////////////////////////////////////////////////////////////////
static int at_send_check_response(char *p_ack, int timeout_ms, char *p_cmd, ...)
{
int ch = 0;
int index = 0;
int startMillis = 0;
va_list args;
memset(recv_buf, 0, sizeof(recv_buf));
va_start(args, p_cmd);
E5.printf(p_cmd, args);
Serial.printf(p_cmd, args);
va_end(args);
delay(200);
startMillis = millis();

if (p_ack == NULL)
{
return 0;
}
do
{
while (E5.available() > 0)
{
ch = E5.read();
recv_buf[index++] = ch;
Serial.print((char)ch);
delay(2);
}


  
if (strstr(recv_buf, p_ack) != NULL)
{
return 1;
}
} 
while (millis() - startMillis < timeout_ms);
return 0;
}

////////////////////////////////////////////////////////////////////

static int recv_prase(void)
{
char ch;
int index = 0;
memset(recv_buf, 0, sizeof(recv_buf));
while (E5.available() > 0)
{
ch = E5.read();
recv_buf[index++] = ch;
Serial.print((char)ch);
delay(2);
}
 
if (index)
{
char *p_start = NULL;
char data[32] = {
0,
};
int rssi = 0;
int snr = 0;
p_start = strstr(recv_buf, "+TEST: RX \"5345454544");
if (p_start)
{
p_start = strstr(recv_buf, "5345454544");
if (p_start && (1 == sscanf(p_start, "5345454544%s,", data)))
{
data[16] = 0;
int data1,data2,data3,data4;
char *endptr,*endptr1,*endpt2,*endptr3;

char dataarray1[5] = {data[0], data[1],data[2], data[3]};
char dataarray2[5] = {data[4], data[5], data[6], data[7]};
char dataarray3[5] = {data[8], data[9], data[10], data[11]};
char dataarray4[5] = {data[12], data[13],data[14], data[15]};

data1 = strtol(dataarray1, &endptr, 16);
data2 = strtol(dataarray2, &endptr1, 16);
data3 = strtol(dataarray3, &endptr, 16);
data4 = strtol(dataarray4, &endptr1, 16);
lcd2.clear(); 
Serial.print("data1:");
Serial.print(data1);
Serial.println();
Serial.print("data2:");
Serial.print(data2);
Serial.println();
Serial.print("data3:");
Serial.print(data3);
Serial.println();
Serial.print("data received displaying on the wio terminal");
Serial.print("\r\n");
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("Temperature:");
display.print(data1);
display.print(" C");
Blynk.virtualWrite(V0,data1);

if(data2 <=10)
{
  display.setCursor(0,20);
  display.print("The device Position  had Changed");
  lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "The device Posi"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(0, 1, "tion had Changed"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")  
}
else
{
  display.setCursor(0,20);
  display.print("The device is in a   constant position");
  lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "The device is in"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")  
  lcd.print(0, 1, "constant position"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")  
}
}
p_start = strstr(recv_buf, "RSSI:");
if (p_start && (1 == sscanf(p_start, "RSSI:%d,", &rssi)))
 {
String newrssi = String(rssi);
Serial.print(rssi);
Serial.print("\r\n");
Blynk.virtualWrite(V2,newrssi);
display.setCursor(0,50);
display.print("RSSI:");
display.print(rssi);
display.print(" dB");
display.display(); 
delay(100);
display.clearDisplay();
}

 p_start = strstr(recv_buf, "SNR:");
if (p_start && (1 == sscanf(p_start, "SNR:%d", &snr)))
{
Serial.print(snr);
Serial.print("\r\n");
}
return 1;
}
}
return 0;
}
 

/////////////////////////////////////////////////////////////////////////////
static int node_recv(uint32_t timeout_ms)
{
at_send_check_response("+TEST: RXLRPKT", 1000, "AT+TEST=RXLRPKT\r\n");
int startMillis = millis();
do
{
if (recv_prase())
{
return 1;
}
} 

while (millis() - startMillis < timeout_ms);
Serial.print("No data");
Serial.println("");
display.clearDisplay();
display.setCursor(0,50);
display.print("Transmitter Not found");
display.display(); 
lcd.clear(); 
lcd2.clear(); //Use it to clear the LCD Widget
lcd2.print(0, 0, "Transmitter Not"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
lcd2.print(0, 1, "Found"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")  
Blynk.virtualWrite(V0,0);
Blynk.virtualWrite(V2,0);
return 0;
//

}

/////////////////////////////////////////////////////////
void setup() {
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
 {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
delay(2000);
display.clearDisplay();
E5.begin(9600);
Serial.print("Receiver\r\n");
    
if (at_send_check_response("+AT: OK", 100, "AT\r\n"))
{
is_exist = true;
at_send_check_response("+MODE: TEST", 1000, "AT+MODE=TEST\r\n");
at_send_check_response("+TEST: RFCFG", 1000, "AT+TEST=RFCFG,866,SF12,125,12,15,14,ON,OFF,OFF\r\n");
delay(200);
}
else
 {
is_exist = false;
Serial.print("No E5 module found.\r\n");
}
}
 



void loop()
{
if (is_exist)
{
node_recv(2000);
}
Blynk.run();
timer.run();
}

Credits

vinay y.n

vinay y.n

26 projects • 45 followers
An electronic product engineer with 8 years of experience in the field. The passion for electronics began as a hobby 11 years ago.

Comments