What about LMIC_setTxData2?

Could someone explain this function ???

LMIC_setTxData2 (u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed)

Thank you…

1 Like

I only know that is the sending function but I don’t know about detail…

1 Like


LMIC_setTxData2 (u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed)

u1_t port is the FPort used for the transmission. Default is 1. You can send different kind of data using different FPorts, so the payload decoder can extract the information depending on the port used.

xref2u1_t data ist your payload, so the data you want to send

u1_t dlen is the size of your payload

u1_t confirmed will let you activate an ACK for every packet you send. 0 means no ACK, 1 means with ACK. Every ACK costs you a downlink!

unsigned char mydata[1];
mydata[0] = 00;

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


Thank you so much

And I have one question about u1_t confirmed.

If I set u1_t = 1 and I send data 1 time and gateway doesn’t receive,it means no downlink form gateway, Right !!!

I wonder that I set u1_t = 2 or 3 ,What will happen ?

Yes you are right. If no one hears you you won’t receive anything.

I don’t think that values other than 0 or 1 are defined in LMIC.

1 Like

Thank you so much.

Your answer is very useful for me…

If you send confirmed traffic that is not acked, LMiC will try to re-send it.

However, this idea has a serious logic “bug”.

If the traffic actually is received, but for whatever reason of range or interference or gateway contention the downlink ack is not, then LMiC will try to resend the uplink. But the resend will have the same frame counter. If the network server sees that, it will ignore the message with an already used frame counter value, and not generate an ack. So as far as LMiC is concerned, the resend failed, and it will resend again - and no matter how many times it resends, it will never get an ack.

Network-level retry under these rules is a broken idea and shouldn’t be used.

If you are going to attempt confirmation, do it at application level - put a new message with new data and no ack flag into setTxData2(). If you want an ack, maybe use a different port number (just avoid the reserved high ports). Then you can send an application-level downlink reply. If you don’t get the reply, then again, send fresh data in a new call to setTxData2() which means a new frame count value - but remember those downlink acks get counted against your limit (enforced or not).

1 Like

Thank you, i wasn‘t aware of this.

Hi Bjoern
What is the data format for xref2u1_t ?
My payload is a mix of characters, numbers, signs, spaces and commas. EG
PP2019:05:20,12:14:00, 003,+0.123,-0.987,+12.345

Im stuck trying to load the payload into the LMIC function.
thanks in advance.

Your payload seems not a mix of those things (aka “string”): it seems a date plus four real numbers with fixed precision :wink:
Sending it as a string is not the best way - actually it is (strongly) deprecated. Some educational info here: https://www.thethingsnetwork.org/docs/devices/bytes.html (and consider if the date is really needed). As is, it’s a whopping 48 bytes of payload, vs. 8-12 really needed.

The LMIC payload is an array of bytes.

Yes, my payload does contain date and time as its starting info then 4 data variables.
So I should convert it all to bytes.
I’m not sure how to do that but will give it a go.


Thanks and really useful to get confirmed uplink in the server. But i have few doubts which lies like a mystery in myself.

  1. if the transmission acknowledgement is set to 1 and it shows confirmed data up at the server and received ack status at the node. What if the received ack status is not received at the node? Does it will try resending the data. if resending is failed, does it affects the other transmissions?
  2. can we do bidirectional data transfer with the nodes? like No predefined texts on tx and rx?
  3. how to confirm the downlink data?

Thanks in advance!

Hi All,

I know this is an old thread. But I am having a strange problem with LMIC_setTxData2 (u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed)

My end device is schedule to send data periodically and it’s doing that just fine. I wanted to optimize the behavior by only sending data if any sensor data is different compared to the previous one.
What I am noticing is LMIC gets stuck if LMIC_setTxData2 isn’t called in the scheduled task.
Has anyone seen the same behavior?

My workaround right now is to send an empty packet (i.e length = 0), but that defies the purpose, as I want to save power on the end device by only sending if needed.

Here my callback implementation. It’s pretty much the same as the TTN OTAA example

void do_send(osjob_t* j)
  // Check if there is not a current TX/RX job running
  if (LMIC.opmode & OP_TXRXPEND) {
    SerialUSB.println(F("OP_TXRXPEND, not sending"));
  else {
    SerialUSB.println(F("Getting sensor data and sending..."));
    if (get_sensor_data()) {
      digitalWrite(LED_BUILTIN, HIGH);
      // Prepare upstream data transmission at the next possible time.
      LMIC_setTxData2(1, fullPayload, data_length, 0);
      SerialUSB.println("[do_send] Packet queued");
    } else {
      SerialUSB.println("[do_send] Nothing to send...");

That is not usually the case

Gets “stuck” exactly how and where? Identify the condition, and you might be able to find a proper solution.

I actually found the issue in my own code.

The send task isn’t getting scheduled unless the TX_COMPLETE event was received (which is the “normal” use case) and obviously it will never be sent since the LMIC send is skipped. So the send task needs to be scheduled again immediately to the next available interval after a skip.

Turning on the debug trace in LMIC was key to find where the problem was.

That doesn’t make any sense.

Of course, if you have tasks that only re-run some interval after themselves, you need to make sure never to forget to schedule yourself, otherwise you will never remember to run again.

But there’s nothing odd about the behavior.

Keep in mind that at some level, LMiC is a demo (and an historic one at that) to do something useful you need to add a fair amount of your own code and probably create your own tasks.