3

I'm building a LoRaWAN GPS Logger using the Arduino LMIC Library. I've got a running solution which reads GPS coordinates and transmits them via LoRaWAN to TTN. For activation, I'm using OTAA. On TTN, I included the TTN Mapper integration where I can see the coverage of the TTN availability. However, there is one major issue regarding timing.

When I'm reading a GPS coordinate, I want to transfer it via LoRaWAN immediately. If there is no coverage, then the device shouldn't do anything (or just send it without arriving anywhere). However, I'm experiencing that old transmissions are stuck in the queue, especially on device start. If the device starts in an area without TTN coverage, it still tries to send its first measured GPS coordinates until it gets to an area where it can join the network (OTAA). After joining, it sends the coordinates. Those coordinates are now displayed in TTN Mapper as a point with TTN coverage, even though there was no TTN coverage at the given location.

On the screenshot below you can see that the time the GPS was recorded differs from the time the package arrived in TTN: enter image description here

What's the best way to overcome that problem?

0

After device startup the first transmit will always trigger an OTAA join. How about sending the coordinates 0,0 in the first transmission?

I always do blocking transmits to make sure the transmit is done before I obtain a new gps fix and enqueue another transmission. Doing blocking transmits will guarantee that you have joined the network when you queue your second transmit. Also do a rough calculation of what the minimum delay should be between two transmits to be withing the duty cycle limits so that lmic does not delay your transmission.

My lmic blocking tx function looks like this:

static uint8_t txFailedCount = 0;

void tx_blocking(uint8_t* radioPacket, uint8_t packetLength)
{
  txFailedCount++;

  // If we failed to transmit 6 times, reset LMIC
  if(txFailedCount>6) {
    Serial.println("LMIC lockup detected, resetting");
    setup_lmic();
  }

  do_send(&sendjob, radioPacket, packetLength);

  uint32_t start = millis();
  // Wait for join to complete. May take a couple of minutes.
  while( LMIC.opmode & OP_JOINING ) {
    os_runloop_once();
    delay(10);
  }
  while( (LMIC.opmode & OP_TXDATA) && (millis() - start < TX_TIMEOUT) )
  {
    os_runloop_once();
    delay(10);

    // If we are in OP_TXDATA state we are successfully transmitting
    txFailedCount = 0;
  }

  if(millis() - start > TX_TIMEOUT) {
    txFailedCount++;
  }

  Serial.println("TX done");
}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.