ComThings / PandwaRF

PandwaRF: RF analysis tool with a sub-1 GHz wireless transceiver controlled by a smartphone or
https://pandwarf.com/
290 stars 53 forks source link

Best way to send large buffers #78

Closed trollwookiee closed 5 years ago

trollwookiee commented 5 years ago

If I have a data buffer of 15-20 Kbytes to be transmitted, how can I minimize the probability of Tx failure:

Originally posted by @Massimaux in https://github.com/ComThings/PandwaRF/issues/76#issuecomment-442373435

trollwookiee commented 5 years ago

both solution should work, but:

Massimaux commented 5 years ago

The experience with large buffers so far is as follows:

  1. LG K8 (Android 6.0 | API level 23)

    • It is noticeable that the BLE data rate between the phone and the dongle is not too high
    • Very low rate of Tx failures
  2. HUAWEI P10 Lite (Android 8.0 | API level 26)

    • It is noticeable that the data rate between the phone and the dongle is very high
    • Higher rate of Tx failures

I'm not certain about this observation, but it seems there is a correlation between the phone-dongle BLE data rate and the Tx failure rate. Is it possible that when PandwaRF receives large buffers from the phone with very high data rates, this may cause failure during the transmission?

Massimaux commented 5 years ago

Update: when talking about the phone-dongle BLE data rate I mean the effective data rate:

eff_data_rate = data / total_time

where, total_time = transmission time + gap_time

For example, if the bit rate is set to 16Kbit/s, then the effective data rate is much less than 16Kbit/s if there is a considerable gap time.

So, the gap time seems to vary between the two phones and my observation for large buffers is: shorter gap time --> higher rate of Tx failures longer gap time --> lower rate of Tx failures

trollwookiee commented 5 years ago

What do you mean exactly by "TX failure" ?

BTW you can measure the BLE data rate Android <-> PandwaRF in the BLE Perf page (you need to enable dev mode).

https://github.com/ComThings/PandwaRF/wiki/Android-Fragment-Ble-Perf

Massimaux commented 5 years ago

Tx failure:

trollwookiee commented 5 years ago
  • PandwaRF disconnects
  • both LEDs blinking in alternate fashion

==> these 2 points means PandwaRF has crashed, probably because there are too many data received by PandwaRF from phone. So you need to wait until PandwaRF has freed some memory before sending more packets for TX. I suggest using the asynchronous TX mode: The txSend() method has a parameter called async. I guess you are transmitting with async = true (txSend(x, x, true, x) This cause the txSend() method to return immediatly, before TX has started.

If you use the synchronous mode (txSend(x, x, false, x), the txSend() will block until TX is complete.

Maybe this can provide better results with large buffers.

Massimaux commented 5 years ago

Yes, I have used async=true. Do you suggest trying synchronous mode (async=false) for large buffers?

trollwookiee commented 5 years ago

Yes, try with synchronous mode (async=false) for large buffers

Massimaux commented 5 years ago

It seems that transmitting larger data using the synchronous mode is more reliable.

Apart from this, can keeping the BLE connection permanently ON drain the PandwaRF battery in couple of hours?

trollwookiee commented 5 years ago

thanks for feedback regarding large buffers. Here are some power consumption values:

Massimaux commented 5 years ago

Thanks for the battery info. The consumption looks OK.

Massimaux commented 5 years ago

I have an issue for which your help will be appreciated.

How can I impose a delay of certain duration between two transmissions? For example, I call txSend() for one data buffer and then I want to wait for 10 seconds before I call txSend() for another data buffer.

txSend(buffer1) wait for 10 seconds txSend(buffer2)

trollwookiee commented 5 years ago

TimeUnit.SECONDS.sleep(10); ?

try {
    Thread.sleep(10000);
} catch (InterruptedException e1) {
    e1.printStackTrace();
}

?

Massimaux commented 5 years ago

Thanks. I've been using several txSend(data, x, false, 1, GollumCallbackGetInteger) in sequence with a SLEEP between them but the behavior I'm seeing is:

  1. First, all txSend() methods including the SLEEP are called.
  2. Then the transmissions are performed but there is no delay between them.

I thought txSend(x,x,false,x) blocks so that no other code is executed until it returns.

How can I make sure that no next code is executed until txSend() completes the transmission?

Massimaux commented 5 years ago

I apologize for bothering, but I'm still struggling with this problem.

Is there a way to know when the data transmission caused by txSend(data, x, false, 1, cb) finishes?

This is crucial to my app because the next code (after txSend()) must NOT be executed before the real transmission finishes.

Thanks!

trollwookiee commented 5 years ago

Synchronous mode + txSend() callback doesn't do the trick ?

Massimaux commented 5 years ago

For some reason, only txSend(data, x, false, 1, cb) works. And when I have this code:

txSend(data1, x, false, 1, cb); TimeUnit.SECONDS.sleep(10); txSend(data2, x, false, 1, cb);

What actually happens is that the 10 seconds sleep is executed before the data1 transmission finishes.

Is there a way that a certain timeout is imposed on the dongle before it proceeds with the next transmission?

trollwookiee commented 5 years ago

txSend(data1, x, false, 1, cb) returns immediatly, but cb is here to notify you when txSend() finishes. If you call sleep() or 2nd txSend() before first cb is called, then the code is executed before 1st TX finish. If you want a txSend() function that is blocking, use the one without the cb parameter.

Massimaux commented 5 years ago

Thank you!

I will try with the txSend() without the cb parameter but I remember it didn't work as expected.

If it turns out that only txSend() with cb works well, could I somehow use the cb parameter to check if the first txSend() finished?