Sending data fails after first packet (from Arduino UNO + LoRa Shield (RFM95))

We are attempting to send air quality measurement data to our server via LoRaWAN. The following script manages to send one packet, yet for some reason we have not been able to detect, after the TX_Interval time is up, a new packet isn’t sent but it gets stuck on “OS_PENDING”. Could anyone help us forward?

We found out the problem could be in the pin mapping but haven’t been able to trace the correct pin mapping. LMIC ASSERT on line 1875: "ASSERT((LMIC.opmode & OP_TXRXPEND)!=0)" · Issue #91 · matthijskooijman/arduino-lmic · GitHub

Here you can see the RFM95 data sheet (page 11): https://www.elecrow.com/download/RFM95-98_2.4G.pdf

Our script:

#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include <JYUconfig.h>

#define SensorPinTmp A0
#define SensorPinHum A1
#define SensorPinCo2 A2

int sensorValueTmp = -1;
int sensorValueHum = -1;
int sensorValueCo2 = -1;

// Pin mapping -- set your pin numbers here. These are for the Dragino shield.

const lmic_pinmap lmic_pins = {

   .nss = 10,

   .rxtx = LMIC_UNUSED_PIN,

   .rst = LMIC_UNUSED_PIN,

   .dio = {3, 2, LMIC_UNUSED_PIN},

};

// Insert Device EUI here

void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}

void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}

void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY, 16);}


// Schedule uplink to send every TX_INTERVAL seconds

const unsigned TX_INTERVAL = 150;

void do_send(osjob_t* j){

   // Check if there is not a current TX/RX job running

   if (LMIC.opmode & OP_TXRXPEND) {

       Serial.println(F("OP_TXRXPEND, not sending"));

   } else {

       // Prepare upstream data transmission at the next possible time.
       int maxAnalogVoltage = 5;
       sensorValueTmp = analogRead(SensorPinTmp)* (5/1023.0) / maxAnalogVoltage * 50 * 100;
       sensorValueHum = analogRead(SensorPinHum)* (5/1023.0) / maxAnalogVoltage * 100 * 100;
       sensorValueCo2 = analogRead(SensorPinCo2)* (5/1023.0) / maxAnalogVoltage * 2000 * 10;

       Serial.println("Reading is: ");

       Serial.println(sensorValueTmp);
       Serial.println(sensorValueHum);
       Serial.println(sensorValueCo2);

       // int -> byte array

       byte payload[6];

       payload[0] = lowByte(sensorValueTmp);
       payload[1] = highByte(sensorValueTmp);
       payload[2] = lowByte(sensorValueHum);
       payload[3] = highByte(sensorValueHum);
       payload[4] = lowByte(sensorValueCo2);
       payload[5] = highByte(sensorValueCo2);

       // transmit packet at the next available slot. The parameters are

       // - FPort, the port used to send the packet -- port 1

       // - the payload to send

       // - the size of the payload

       // - if we want an acknowledgement (ack), costing 1 downlink message, 0 means we do not want an ack

       LMIC_setTxData2(1, payload, sizeof(payload), 0);

       Serial.println(F("Payload queued"));

  }

}

static osjob_t sendjob;

void onEvent (ev_t ev) {

   switch(ev) {

       case EV_JOINING:

           Serial.println("EV_JOINING");

           break;

       case EV_JOINED:

           Serial.println("EV_JOINED");

           // We will disable link check mode, this is used to periodically verify network connectivity, which we do not need in this tutorial

           LMIC_setLinkCheckMode(0);

           break;

       case EV_JOIN_FAILED:

           Serial.println("EV_JOIN_FAILED");

           break;

       case EV_REJOIN_FAILED:

           Serial.println("EV_REJOIN_FAILED");

           break;

       case EV_TXCOMPLETE:

           Serial.println("EV_TXCOMPLETE");

           // Schedule next transmission

           os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send);

           break;

        default:

           break;

   }

}

void setup() {

   Serial.begin(9600);

   Serial.println(F("Starting"));

   // Initalizes the LIMIC library,

   os_init();

   // Resets the MAC state -- this removes sessions, meaning the device must repeat the join process each time it is started.

   LMIC_reset();

   // Let LMIC compensate for an inaccurate clock

   LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);

   // Disable link check validation -- this is used to periodically verify network connectivity. Not needed in this tutorial.

   LMIC_setLinkCheckMode(0);

   // Set data rate to Spreading Factor 7 and transmit power to 14 dBi for uplinks

   LMIC_setDrTxpow(DR_SF7, 14);

   // Start job

   do_send(&sendjob);

}



void loop() {

   os_runloop_once();

}

A big thank you in advance!

Please edit your post to add code tags ("</>" button in post editor).

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.