Combining raw LoRa and LoRaWAN

Hello everyone. Can anyone help me figure out a fix to this? My repeater node is able to receive data from 3 sensor nodes through LoRa. The problem is when I try to LoRaWAN (repeater to gateway), the repeater is suddenly unable to receive any data. When I tried troubleshooting, I removed the state machine and repeater was able to receive data again. I think the LoRa and the configuration of the LoRaWAN stack are conflicting. It would be a lifesaver if someone could help. Thank you!

My code:

#include “LoRaWan_APP.h”
#include “Arduino.h”

#define RF_FREQUENCY 915000000 // Hz
#define TX_OUTPUT_POWER 14 // dBm
#define LORA_BANDWIDTH 0 // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved]
#define LORA_SPREADING_FACTOR 7 // [SF7…SF12]
#define LORA_CODINGRATE 1 // [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT 0 // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON false
#define LORA_IQ_INVERSION_ON false
#define RX_TIMEOUT_VALUE 1000
#define BUFFER_SIZE 51 // Define the payload size here

char txpacket[BUFFER_SIZE];
char rxpacket[BUFFER_SIZE];

static RadioEvents_t RadioEvents;

int16_t txNumber;
int16_t rssi, rxSize;

bool lora_idle = true;
unsigned long previousMillis = 0;
const long interval = 10000;

struct SensorData {
float surface_velocity;
float flow_rate;
float water_level;
bool received;
};

SensorData sensors[3];

/* OTAA para*/
uint8_t devEui[] = { 0x12, 0x3A, 0xBC, 0x4F, 0x56, 0x78, 0x9A, 0xBC };
uint8_t appEui[] = { 0x78, 0x56, 0x34, 0x12, 0xAB, 0xCD, 0xEF, 0x01 };
uint8_t appKey[] = { 0xAF, 0x4C, 0x3E, 0xD8, 0x92, 0x1A, 0x47, 0xFC, 0x5D, 0x69, 0xB1, 0x7E, 0x84, 0x36, 0xCB, 0x29 };

/* ABP para*/
uint8_t nwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe, 0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda, 0x85 };
uint8_t appSKey[] = { 0xd7, 0x2c, 0x78, 0x75, 0x8c, 0xdc, 0xca, 0xbf, 0x55, 0xee, 0x4a, 0x77, 0x8d, 0x16, 0xef, 0x67 };
uint32_t devAddr = (uint32_t)0x007e6ae1;

/LoraWan channelsmask, default channels 0-7/
uint16_t userChannelsMask[6] = { 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };

/LoraWan region, select in arduino IDE tools/
LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;

/LoraWan Class, Class A and Class C are supported/
DeviceClass_t loraWanClass = CLASS_A;

/the application data transmission duty cycle. value in [ms]./
uint32_t appTxDutyCycle = 10000;

/OTAA or ABP/
bool overTheAirActivation = true;

/ADR enable/
bool loraWanAdr = true;

/* Indicates if the node is sending confirmed or unconfirmed messages */
bool isTxConfirmed = true;

/* Application port /
uint8_t appPort = 2;
/
!

  • Number of trials to transmit the frame, if the LoRaMAC layer did not
  • receive an acknowledgment. The MAC performs a datarate adaptation,
  • according to the LoRaWAN Specification V1.0.2, chapter 18.4, according
  • to the following table:
  • Transmission nb | Data Rate
  • ----------------|-----------
  • 1 (first) | DR
  • 2 | DR
  • 3 | max(DR-1,0)
  • 4 | max(DR-1,0)
  • 5 | max(DR-2,0)
  • 6 | max(DR-2,0)
  • 7 | max(DR-3,0)
  • 8 | max(DR-3,0)
  • Note, that if NbTrials is set to 1 or 2, the MAC will not decrease
  • the datarate, in case the LoRaMAC layer did not receive an acknowledgment
    */
    uint8_t confirmedNbTrials = 4;

static void prepareTxFrame(uint8_t port) {
char aggregatedData[BUFFER_SIZE];

// Initialize overflow_time to 0.00
float overflow_time = 0.00;

// Calculate the differences in water level and velocity
float level_diff_12 = fabs(sensors[0].water_level - sensors[1].water_level);
float level_diff_23 = fabs(sensors[1].water_level - sensors[2].water_level);

float velocity_diff_12 = fabs(sensors[0].surface_velocity - sensors[1].surface_velocity);
float velocity_diff_23 = fabs(sensors[1].surface_velocity - sensors[2].surface_velocity);

// Determine block status based on the table
int block_bet_12 = 0;
int block_bet_23 = 0;

int drainage_cap_80 = 0;

// Check for sensor 1 and 2
if ((level_diff_12 >= 0.00 && level_diff_12 <= 0.15) && (velocity_diff_12 >= 0.15)) {
block_bet_12 = 1;
} else if ((level_diff_12 > 0.15 && level_diff_12 <= 0.30) && (velocity_diff_12 >= 0.15)) {
block_bet_12 = 1;
} else if (level_diff_12 > 0.30) {
block_bet_12 = 1;
}

// Check for sensor 2 and 3
if ((level_diff_23 >= 0.00 && level_diff_23 <= 0.15) && (velocity_diff_23 >= 0.15)) {
block_bet_23 = 1;
} else if ((level_diff_23 > 0.15 && level_diff_23 <= 0.30) && (velocity_diff_23 >= 0.15)) {
block_bet_23 = 1;
} else if (level_diff_23 > 0.30) {
block_bet_23 = 1;
}

// If any warning status is triggered, set overflow_time
if (block_bet_12 || block_bet_23) {
overflow_time = get_overflow_time();
}

// Check if water level reaches 80% of the drainage height (0.528m)
if (sensors[0].water_level >= 0.528 || sensors[1].water_level >= 0.528 || sensors[2].water_level >= 0.528) {
drainage_cap_80 = 1;
}

snprintf(aggregatedData, BUFFER_SIZE, “%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%d,%d,%.2f,%d”,
sensors[0].surface_velocity, sensors[0].flow_rate, sensors[0].water_level,
sensors[1].surface_velocity, sensors[1].flow_rate, sensors[1].water_level,
sensors[2].surface_velocity, sensors[2].flow_rate, sensors[2].water_level,
block_bet_12, block_bet_23, overflow_time, drainage_cap_80);

appDataSize = strlen(aggregatedData);
memcpy(appData, aggregatedData, appDataSize);
}

void setup() {
Serial.begin(115200);
Mcu.begin();
deviceState = DEVICE_STATE_INIT;
txNumber = 0;
rssi = 0;

RadioEvents.RxDone = OnRxDone;
Radio.Init(&RadioEvents);
Radio.SetChannel(RF_FREQUENCY);
Radio.SetRxConfig(MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
0, true, 0, 0, LORA_IQ_INVERSION_ON, true);
memset(sensors, 0, sizeof(sensors));
}

void loop() {
unsigned long currentMillis = millis();

if (lora_idle) {
lora_idle = false;
Serial.println(“into RX mode”);
Radio.Rx(0);
}

Radio.IrqProcess();

switch (deviceState) {
case DEVICE_STATE_INIT:
#if (LORAWAN_DEVEUI_AUTO)
LoRaWAN.generateDeveuiByChipID();
#endif
LoRaWAN.init(loraWanClass, loraWanRegion);
break;

    case DEVICE_STATE_JOIN:
        LoRaWAN.join();  // Join LoRaWAN network
        break;

    case DEVICE_STATE_SEND:
        prepareTxFrame(appPort);  // Prepare the data to send
        LoRaWAN.send();  // Send data via LoRaWAN
        clearSensorData();  // Clear the sensor data buffer
        deviceState = DEVICE_STATE_CYCLE;  // Move to the next state
        break;

    case DEVICE_STATE_CYCLE:
        // Schedule next packet transmission
       //txDutyCycleTime = appTxDutyCycle + randr(-APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND);
        //LoRaWAN.cycle(txDutyCycleTime);  // Go into cycle state
        deviceState = DEVICE_STATE_SLEEP;  // Move to sleep state
        break;

    case DEVICE_STATE_SLEEP:
        LoRaWAN.sleep(loraWanClass);  // Put LoRaWAN to sleep
        break;

    default:
        deviceState = DEVICE_STATE_INIT;  // Initialize the device state if unknown
        break;
}

if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
aggregateData();
deviceState = DEVICE_STATE_SEND; // Trigger LoRaWAN send state
lora_idle = true;
}
}

void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) {
Serial.println(“OnRxDone called”);

if (size > BUFFER_SIZE) {
Serial.println(“Received packet is too large”);
return;
}

memcpy(rxpacket, payload, size);
rxpacket[size] = ‘\0’; // Null-terminate the string

// Parse the received data
int received_node_id;
float received_surface_velocity;
float received_flow_rate;
float received_water_level;

int parsedItems = sscanf(rxpacket, "%d,%f,%f,%f ", &received_node_id, &received_surface_velocity, &received_flow_rate, &received_water_level);

if (parsedItems == 4 && received_node_id >= 1 && received_node_id <= 3) {
sensors[received_node_id - 1].surface_velocity = received_surface_velocity;
sensors[received_node_id - 1].flow_rate = received_flow_rate;
sensors[received_node_id - 1].water_level = received_water_level;
sensors[received_node_id - 1].received = true;

// Output the received values
Serial.printf("\r\nReceived Node ID: %d\n", received_node_id);
Serial.printf("Received Surface Velocity: %.6f m/s\n", received_surface_velocity);
Serial.printf("Received Flow Rate: %.6f m/s^2\n", received_flow_rate);
Serial.printf("Received Water Level: %.6f m\n", received_water_level);
Serial.printf("RSSI: %d dBm, SNR: %d\n", rssi, snr);

} else {
Serial.println(“Failed to parse the received data”);
}

Radio.Sleep(); // Put the radio to sleep
lora_idle = true; // Set flag to allow switching back to RX mode
}

void aggregateData() {
Serial.println(“Aggregating data from all sensors:”);
for (int i = 0; i < 3; i++) {
if (sensors[i].received) {
Serial.printf(“Sensor %d - Surface Velocity: %.2f m/s, Flow Rate: %.2f m/s^2, Water Level: %.2f m\n”,
i + 1, sensors[i].surface_velocity, sensors[i].flow_rate, sensors[i].water_level);
} else {
Serial.printf(“Sensor %d - No data received\n”, i + 1);
}
}
}

void clearSensorData() {
memset(sensors, 0, sizeof(sensors));
Serial.println(“Sensor data cleared for next interval”);
}

float get_overflow_time() {
float V = 70.455;
float Q_in = sensors[0].flow_rate;
float Q_out = sensors[2].flow_rate;
float Q_net = Q_in - Q_out;

float of_time = V / Q_net;

return of_time;
}