Need help correctly setting up new device on WisGate Edge Lite 2 RAK7268\RAK7268C

I have a WisGate Edge Lite 2 RAK7268\RAK7268C and a LoRa Enabled ESP32. I would like to accomplish sending a message from my ESP32 to the WisGate and have it publish that message to my local mqtt server.

I have tried setting it up in the following way:

  • WisGate is plugged into my Local Network via Ethernet
  • I have it in Network Server mode
  • Under LORA Network > Gateway I have it pointed to my MQTT Server
  • I created an Application and then within that Application I created a Device
  • I am using US Frequencies

Things I’m unclear about:

  • For the device specifically, I made up a Device EUI (0102030405060708) and Device Address 123456789. Is this valid for a local/private setup? I don’t totally understand this
  • For the Application Session and Application Network Key I was given a string. I believe that needs to be converted to a 32bit hex for my ESP32, see code below along with the screenshot from RAK
// LoRaWAN NwkSKey, network session key
static const PROGMEM u1_t NWKSKEY[64] = { 0x64, 0x36, 0x32, 0x34, 0x38, 0x37, 0x30, 0x35, 0x30, 0x66, 0x32, 0x64, 0x38, 0x30, 0x37, 0x65, 0x61, 0x63, 0x38, 0x35, 0x30, 0x66, 0x36, 0x32, 0x62, 0x63, 0x33, 0x61, 0x65, 0x38, 0x34, 0x33 };

// LoRaWAN AppSKey, application session key
static const u1_t PROGMEM APPSKEY[64] = { 0x30, 0x66, 0x62, 0x30, 0x38, 0x39, 0x64, 0x31, 0x62, 0x35, 0x30, 0x30, 0x35, 0x33, 0x30, 0x31, 0x61, 0x61, 0x31, 0x31, 0x66, 0x32, 0x30, 0x61, 0x37, 0x31, 0x64, 0x32, 0x61, 0x61, 0x34, 0x36 };

// LoRaWAN end-device address (DevAddr)
static const u4_t DEVADDR = 0x123456789;

(yes I know I’m exposing keys, this is just a test and they will be changed)

When my ESP32 device publishes a LORA message, it is not being picked up. I feel quite lost and would appreciate any pointers/help on getting this up and running.

Welcome to the forum @hummmingbear

First thing I saw is that the NWSKEY and APPSKEY from your ESP32 code is different from the Application Session Key and Network Session Key on the LoRaWAN server. They must be the same. Both are in HEX format, so if you set the Application Session Key to 0fb089d1b5005301aa11f20a71d2aa46 the APPSKEY in your code must be {0x0f, 0xb0, 0x89, 0xd1, 0xb5, 0x00, 0x53, 0x01, 0xaa, 0x11, 0xf2, 0x0a, 0x71, 0xd2, 0xaa, 0x46};, not the Ascii values.

I do not know what LoRaWAN library you use, some of them use LSB format, the network server is using MSB format

Is your ESP32 using the same LoRaWAN region as the gateway?

Do you see any packets in the RAK7268 LoRaWAN Packet Logger

Thank you for the reply, much appreciated. That totally worked! I had to covert both AppSessionKey and NetworkSessionKey to the format you provided. Woohoo!!

The only thing I had to change is for some reason it is seeing my device address as 23456789. On the ESP I have it set as static const u4_t DEVADDR = 0x123456789; I’m sure I’m misunderstanding this hex or type value?

One more question - Is there anyway to tell the RAK software to automatically decode the Base64 data/message before publishing it to MQTT?

About the dev addr, it is a 32bit number, but you set a 40bit in your code, so the upper 8 bit are discarded.

For the data sent over MQTT, as far as I know (I am not the gateway expert here), you need to decode the data on the network server. The internal network server supports only CayenneLPP format.
You can enable this in the Application => Payload Formats:

As I am always sending my data in Cayenne LPP format, I get the decoded data on the MQTT broker:

In Arduino, I use the CayenneLPP library. It is quite easy to use.

1 Like

Thank you for the help! That all makes sense, I’ll try that library out

/***

 *  PEPNOUN_SKID_01

 *  Device will send uplink every 20 seconds.

***/

#include "rak1906.h"

#include "rak1910.h"

rak1910 rak1910;

rak1906 rak1906;

#define LED_BUILTIN1 35

#define LED_BUILTIN2 36

#define MAX_SIZE 100

#define OTAA_PERIOD   (20000)

/*************************************

   LoRaWAN band setting:

     RAK_REGION_EU433

     RAK_REGION_CN470

     RAK_REGION_RU864

     RAK_REGION_IN865

     RAK_REGION_EU868

     RAK_REGION_US915

     RAK_REGION_AU915

     RAK_REGION_KR920

     RAK_REGION_AS923

 *************************************/

#define OTAA_BAND     (RAK_REGION_EU868)

#define OTAA_DEVEUI   {0xAC, 0x1F, 0x09, 0xFF, 0xFE, 0x08, 0x6C, 0x3D}

#define OTAA_APPEUI   {0xAC, 0x1F, 0x09, 0xFF, 0xFE, 0x08, 0x6C, 0x3D}

#define OTAA_APPKEY   {0x8A, 0xE9, 0xA1, 0xA9, 0x30, 0xB0, 0x77, 0x57, 0x82, 0x93, 0x83, 0x3F, 0xDF, 0xCE, 0x97, 0xA6}

#define PIN_VBAT WB_A0

uint32_t vbat_pin = PIN_VBAT;

#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096

#define VBAT_DIVIDER (0.4F)        // 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M))

#define VBAT_DIVIDER_COMP (1.73)    // (1.403F) // Compensation factor for the VBAT divider

#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)

float readVBAT(void)

{

  float raw;

  raw = analogRead(vbat_pin);

  return raw * REAL_VBAT_MV_PER_LSB;

}

uint8_t mvToPercent(float mvolts)

{

    if (mvolts < 3300)

        return 0;

    if (mvolts < 3600)

    {

        mvolts -= 3300;

        return mvolts / 30;

    }

    mvolts -= 3600;

    return 10 + (mvolts * 0.15F);

}

uint8_t mvToLoRaWanBattVal(float mvolts)

{

    if (mvolts < 3300)

        return 0;

    if (mvolts < 3600)

    {

        mvolts -= 3300;

        return mvolts / 30 * 2.55;

    }

    mvolts -= 3600;

    return (10 + (mvolts * 0.15F)) * 2.55;

}

uint8_t collected_data[64] = { 0 };

void recvCallback(SERVICE_LORA_RECEIVE_T * data)

{

    if (data->BufferSize > 0) {

        Serial.println("Something received!");

        for (int i = 0; i < data->BufferSize; i++) {

            Serial.printf("%x", data->Buffer[i]);

        }

        Serial.print("\r\n");

    }

}

void joinCallback(int32_t status)

{

    Serial.printf("Join status: %d\r\n", status);

}

/*************************************

 * enum type for LoRa Event

    RAK_LORAMAC_STATUS_OK = 0,

    RAK_LORAMAC_STATUS_ERROR,

    RAK_LORAMAC_STATUS_TX_TIMEOUT,

    RAK_LORAMAC_STATUS_RX1_TIMEOUT,

    RAK_LORAMAC_STATUS_RX2_TIMEOUT,

    RAK_LORAMAC_STATUS_RX1_ERROR,

    RAK_LORAMAC_STATUS_RX2_ERROR,

    RAK_LORAMAC_STATUS_JOIN_FAIL,

    RAK_LORAMAC_STATUS_DOWNLINK_REPEATED,

    RAK_LORAMAC_STATUS_TX_DR_PAYLOAD_SIZE_ERROR,

    RAK_LORAMAC_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS,

    RAK_LORAMAC_STATUS_ADDRESS_FAIL,

    RAK_LORAMAC_STATUS_MIC_FAIL,

    RAK_LORAMAC_STATUS_MULTICAST_FAIL,

    RAK_LORAMAC_STATUS_BEACON_LOCKED,

    RAK_LORAMAC_STATUS_BEACON_LOST,

    RAK_LORAMAC_STATUS_BEACON_NOT_FOUND,

 *************************************/

void sendCallback(int32_t status)

{

    if (status == RAK_LORAMAC_STATUS_OK) {

        Serial.println("Successfully sent");

    } else {

        Serial.println("Sending failed");

    }

}

void setup()

{

    pinMode(LED_BUILTIN1, OUTPUT);

    pinMode(LED_BUILTIN2, OUTPUT);

    digitalWrite(LED_BUILTIN1, HIGH);

    digitalWrite(LED_BUILTIN2, HIGH);

    Serial.begin(115200, RAK_AT_MODE);

    delay(2000);

    Wire.begin();

    Serial.printf("RAK1906 init %s\r\n", rak1906.init() ? "Success" : "Fail");

    rak1910.init();

    Serial.printf("RAK1910 init %s\r\n", rak1910.init() ? "Success" : "Fail");

    Serial.println("Pepnoun Node 1 : Skid No.1");

    Serial.println("------------------------------------------------------");

 

    if(api.lorawan.nwm.get() != 1)

    {

        Serial.printf("Set Node device work mode %s\r\n",

            api.lorawan.nwm.set(1) ? "Success" : "Fail");

        api.system.reboot();

    }

    // OTAA Device EUI MSB first

    uint8_t node_device_eui[8] = OTAA_DEVEUI;

    // OTAA Application EUI MSB first

    uint8_t node_app_eui[8] = OTAA_APPEUI;

    // OTAA Application Key MSB first

    uint8_t node_app_key[16] = OTAA_APPKEY;

 

    if (!api.lorawan.appeui.set(node_app_eui, 8)) {

        Serial.printf("LoRaWan OTAA - set application EUI is incorrect! \r\n");

        return;

    }

    if (!api.lorawan.appkey.set(node_app_key, 16)) {

        Serial.printf("LoRaWan OTAA - set application key is incorrect! \r\n");

        return;

    }

    if (!api.lorawan.deui.set(node_device_eui, 8)) {

        Serial.printf("LoRaWan OTAA - set device EUI is incorrect! \r\n");

        return;

    }

 

    if (!api.lorawan.band.set(OTAA_BAND)) {

        Serial.printf("LoRaWan OTAA - set band is incorrect! \r\n");

        return;

    }

    if (!api.lorawan.deviceClass.set(RAK_LORA_CLASS_A)) {

        Serial.printf("LoRaWan OTAA - set device class is incorrect! \r\n");

        return;

    }

    if (!api.lorawan.njm.set(RAK_LORA_OTAA))

    {

        Serial.printf("LoRaWan OTAA - set network join mode is incorrect! \r\n");

        return;

    }

    if (!api.lorawan.join())  

    {

        Serial.printf("LoRaWan OTAA - join fail! \r\n");

        return;

    }

 

    /** Wait for Join success */

    while (api.lorawan.njs.get() == 0) {

        Serial.print("Wait for LoRaWAN join...");

        api.lorawan.join();

        delay(10000);

    }

 

    if (!api.lorawan.adr.set(true)) {

        Serial.printf("LoRaWan OTAA - set adaptive data rate is incorrect! \r\n");

        return;

    }

    if (!api.lorawan.rety.set(1)) {

        Serial.printf("LoRaWan OTAA - set retry times is incorrect! \r\n");

        return;

    }

    if (!api.lorawan.cfm.set(1)) {

        Serial.printf("LoRaWan OTAA - set confirm mode is incorrect! \r\n");

        return;

    }

     

    Serial.printf("Duty cycle is %s\r\n", api.lorawan.dcs.get()? "ON" : "OFF");

    Serial.printf("Packet is %s\r\n", api.lorawan.cfm.get()? "CONFIRMED" : "UNCONFIRMED");

    uint8_t assigned_dev_addr[4] = { 0 };

    api.lorawan.daddr.get(assigned_dev_addr, 4);

    Serial.printf("Device Address is %02X%02X%02X%02X\r\n", assigned_dev_addr[0], assigned_dev_addr[1], assigned_dev_addr[2], assigned_dev_addr[3]);  // Check Device Address

    Serial.printf("Uplink period is %ums\r\n", OTAA_PERIOD);

    Serial.println("");

    api.lorawan.registerRecvCallback(recvCallback);

    api.lorawan.registerJoinCallback(joinCallback);

    api.lorawan.registerSendCallback(sendCallback);

    analogReference(AR_INTERNAL_3_0);

    //analogResolution(12);

    delay(1);

    readVBAT();

    digitalWrite(LED_BUILTIN1, LOW);

    digitalWrite(LED_BUILTIN2, LOW);

}

void addInt32ToData(uint8_t* data, uint8_t* length, int32_t value) {

    // Add each byte of the int32_t to the array

    data[(*length)++] = (value >> 24) & 0xFF;

    data[(*length)++] = (value >> 16) & 0xFF;

    data[(*length)++] = (value >> 8) & 0xFF;

    data[(*length)++] = value & 0xFF;

}

void uplink_routine()

{

    digitalWrite(LED_BUILTIN1, HIGH); // Turn on LED1

    digitalWrite(LED_BUILTIN2, HIGH); // Turn on LED2

    // Read battery voltage

    float vbat_mv = readVBAT();

    int32_t vbat = static_cast<int32_t>(vbat_mv); // Convert to integer

    // Read GPS data

    float lat = rak1910.latitude();

    float lon = rak1910.longitude();

    int32_t lat_fixed = static_cast<int32_t>(lat * 1000000); // Convert to integer

    int32_t lon_fixed = static_cast<int32_t>(lon * 1000000); // Convert to integer

    // Read other sensor data

    float temperature = rak1906.temperature();

    float humidity = rak1906.humidity();

    uint8_t temp = static_cast<uint8_t>(temperature * 10); // Convert to integer

    uint8_t hum = static_cast<uint8_t>(humidity * 10); // Convert to integer

    // Prepare data packet

    uint8_t data_len = 0;

    addInt32ToData(collected_data, &data_len, vbat); // Corrected function call

    addInt32ToData(collected_data, &data_len, lat_fixed);

    addInt32ToData(collected_data, &data_len, lon_fixed);

    if (data_len < MAX_SIZE) collected_data[data_len++] = hum;

    if (data_len < MAX_SIZE) collected_data[data_len++] = temp;

    // Send data

    if (api.lorawan.send(data_len, (uint8_t *) & collected_data, 2, true, 1)) {

        Serial.println("Sending is requested");

    } else {

        Serial.println("Sending failed");

    }

    digitalWrite(LED_BUILTIN1, LOW); // Turn off LED1

    digitalWrite(LED_BUILTIN2, LOW); // Turn off LED2

}

void addInt16ToData(uint8_t* data, uint8_t* length, int16_t value) {

    data[(*length)++] = (value >> 8) & 0xFF;

    data[(*length)++] = value & 0xFF;

}

void loop()

{

    static uint64_t last = 0;

    static uint64_t elapsed;

 

    if ((elapsed = millis() - last) > OTAA_PERIOD) {

        uplink_routine();

 

        last = millis();

    }

    //Serial.printf("Try sleep %ums..", OTAA_PERIOD);

    api.system.sleep.all(OTAA_PERIOD);

    //Serial.println("Wakeup..");

}

object

applicationID: “1”

applicationName: “Pepnoun_Nodes”

devEUI: “ac1f09fffe086c3d”

deviceName: “Pepnoun_Nodes”

timestamp: 1705922844

fCnt: 6

fPort: 2

data: “AAAD/gAAAAAAAAAAAAA=”

data_encode: “base64”

adr: true

I’m having issue with the decoding of the payload, anyone can help and verify what I’m doing wrong in this? Im using rak4630 forwarding data to wisgate 7289. I’m trying to parse the data through node-red and eventually push the sensor data to influxdb

From your description its not very clear what your problem is.

Your data is encoded with base64:

data: “AAAD/gAAAAAAAAAAAAA=”

data_encode: “base64”

So basically you just need to decode that e.g. usin the python module:

And then you may obtain your JSON object.

1 Like