Arm Mbed OS support forum

A BLE topic continued from github

@vcoubard and @paulszczepanek
Thanks for the quick reply on the topic i raised at github.

I think i shall clarify why i posted that:

  • i started trying to learn how to program BLE features in Mbed OS several weeks ago
  • as a comparison i read into BLE with Arduino and could easily solve the task with ArduinoBLE library in just 2 days though i had absolutely no experience with that before
  • I also programmed an ESP32 to stream high frequency data into InfluxDB over WiFi in just 3 days, though never programmed these technologies before and even those raised some challanges along the road

Before posting there i tried several things:

  1. placing _event_queue.break_dispatch(); inside the onDisconnectionComplete() block
  2. placing _event_queue.break_dispatch(); and call start() inside the onDisconnectionComplete() block to reinitialize.
  3. trying to find anything in the EventQueue documentation that could cancel out the effect of the call_every() method
  4. the only thing that did seem to have any effect was system_reset()
    All these inspired the title i used there.

After reading your replies over there my first thought was: OK, i will just replace call_every() method with a simple eventqueue.call() that will update the values only once from within the onConnectionComplete() block…but that should trigger the onDataSent event…so i just will need add an onDataSent() block and call my update_sensor_value() from within that… and that should do the trick.

I was wrong again. :frowning: :slight_smile: :frowning:

Paul replied the data transmission rate doubles because i make duplicate calls of _event_queue.call_every(UPDATEINTV, [this] { update_sensor_value(); }); which was obvious even for me, i just could not find any eventqueue methods that would counter act call_every(). If it is not just my mistake, then it would mean we have a hard-coded issue in the examples and thus teaching bad practice for BLE newcomers like me. I mean for sure BLE connection will get broken over time and if on reconnection the TX rate always doubles, then the signal will sooner or later fall apart just because of that no matter what. If this is true, please consider to change the examples.

Since updating to Mbed Studio V1.4 i can debug much slower as printf and (un)BufferedSerial stopped working with my Artemis board (and BLE is not reimplemented yet in Mbed on my MAX32630FTHR where i can still debug :wink: )

Despite this i already rewamped my example posted originally on github. This time i based it on the GattServer Characteristic Updates example. This time the TX rate does not increase if i reconnect even though void start() still calls _event_queue->call_every().
However the scope application i made in App Inventor behaves differently as with the code based on BLE_GattServer_AddService example:

  • If i stop scanning before trying to connect, then the phone will never connect the board
  • I can disconnect and reconnect only 2-3 times before the app would abort
  • but as i said the TX rate now remains the same after reconnection

To sum all this up i get a feeling there may be some inconsistencies throughout the current BLE related APIs.

Will also try to implement your suggestions in the following days.
Meanwhile i found out i can only transfer 1 byte at a time despite the GATT_MTU could allow at least 20 byte payload per packet. This will add some complexity as the signal i want to transfer contains important details that last only for 16-20 milliseconds. So if i can not send multiple readings at once, then i will need to set a really short connection interval of about 10-12 ms which will be really challenging if the default rate is 50ms. I just can not go with WiFi as that consumes 120 mA at least…

Please, ask one question at a time or at least number the questions in a summary.

Let me help you with first with one question that sticks out. The call_every function returns and id that is used to cancel it.
int id = _event_queue.call_every(UPDATEINTV, [this] { update_sensor_value(); }); _event_queue.cancel(id);
This will stop the calls so that you can replace it with new ones later. This is explained clearly in the event queue functions doxygen.

Why can you only transfer one byte at time?

Oh my bad… it seems i overlooked that and did not pass the id into _event_queue.cancel()
Thanks for pointing it out.