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 read 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: LoRa Uplink screenshot

What's the best way to overcome this 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");
}
0

Can you use the GPS timestamp that's in the message and ignore any messages that are older than say, 10 sec from the current time at the server (which is usually time synced to time servers) ? Make sure that you're using the gps timestamp and not the system time, which could be off by more than 10 sec sometimes.

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.