"Best" way to send sensor data via BLE?

Tacca

  • Jr. Member
  • **
    • Posts: 5
    • View Profile
Hi,

I am facing a problem with my project.
I am trying to send 9axis sensor data via BLE, I managed to do that via UART example by truncating a concatenated message of the data, into chunks of 20 bytes each.
The problem is, the 9 axis data plus fusion becomes 3~4 messages (60 to 80 bytes), and I plan to use 2 9axis sensors (wirelings), which would double the length of the message I need to send. This decresce my throughput by a lot.
Right now, using only one sensor, I can't go below 120ms or I start loosing some of the data.

Is there a best way? Any thoughts are appreciated.
Thanks
« Last Edit: May 30, 2020, 05:37:55 PM by Tacca »


lennevia

  • Administrator
  • Hero Member
  • *****
    • Posts: 104
    • View Profile
Hello Tacca,

Can you include the code you currently have? I can try optimizing it to see if it can be made more efficient.

Do you need the accuracy you have mentioned? What data is most important to you, or do you need all of it?

Let me know!

Thanks,

Réna


Tacca

  • Jr. Member
  • **
    • Posts: 5
    • View Profile
Hello Réna, thanks for the help.
The code I was working with is available at:
https://github.com/brunotacca/knee_kinematic_sensor/blob/master/SensorCoreApp/SensorCoreApp.ino

I kinda mixed both the examples found at tinycircuits learn section.
This: https://github.com/TinyCircuits/TinyCircuits-TinyShield-Sensor-ASD2511/tree/master/examples/9-Axis_TinyShield_example
And this: https://github.com/TinyCircuits/TinyCircuits-TinyShield-BLE-ASD2116/tree/master/examples/STBLE/examples/UARTPassThrough

It's still a bit of a mess with a lot of commented code since I am still at the beginning of my research.

The idea I had was to have a concatenated String with the data I need, as you can see in this part:
Code: [Select]
      String msg = "";
      msg.concat("C");
      msg.concat(sampleCount);
      msg.concat("S0");
      msg.concat(accelData.x());
      msg.concat(accelData.y());
      msg.concat(accelData.z());
      msg.concat(gyroData.x());
      msg.concat(gyroData.y());
      msg.concat(gyroData.z());
      msg.concat(compassData.x());
      msg.concat(compassData.y());
      msg.concat(compassData.z());
      msg.concat("F");
      msg.concat(fusionData.x());
      msg.concat(fusionData.y());
      msg.concat(fusionData.z());
      msg.concat("#");

      sendMessage(msg);

And then, send it all truncating it in chunks of 20 bytes.
Code: [Select]
#define buffer_size 19

void sendMessage(String msg)
{
  uint8_t sendBuffer[msg.length() + 1] = {};
  msg.getBytes(sendBuffer, msg.length() + 1);

  uint8_t sentLength = 0;
  int sizeSendBuffer = sizeof(sendBuffer);

  while (sentLength < sizeSendBuffer)
  {
    int arraySize = buffer_size;
    if ((sizeSendBuffer - sentLength) < buffer_size)
    {
      arraySize = (sizeSendBuffer - sentLength);
    }

    uint8_t sendBufferTruncated[arraySize] = {};
    uint8_t sendLength = 0;

    while (sendLength < arraySize)
    {
      if (sendBuffer[sentLength] != 0)
      {
        sendBufferTruncated[sendLength] = sendBuffer[sentLength];
      }
      sendLength++;
      sentLength++;
    }

    lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, (uint8_t *)sendBufferTruncated, sendLength);
    SerialMonitorInterface.print("SENT> ");
    SerialMonitorInterface.println((char *)sendBufferTruncated);
  }

}

About the accuracy and the data I need... I do need the more messages I can get per second, and at least, all the sensor data (except for the fusion data maybe). I will be tracking knee movements each steps, so average runners cadence falls at 160ish steps per minute, I will be tracking only one knee so, 80ish steps per minute, which means 1.3 steps per second, a step each 650ms.

With the rate and model I have now, I need like around 60 to 80 bytes of data per full message, which means 4 truncated messages and I had a kind of a stable measurement at 120 ~ `130ms per message (4 messages, so it would send a message each 30ms). A full message per 120ms would mean 5,4 messages per step, this is not good enough for what I had in mind.

This considering I am using only 1 sensor. Since I plan to use 2 wirelings, the data length would double and I would get only 2,7 messages per step.

During this meantime, I found some possible workarounds:
1 - Maybe tinycircuits have a BLE 5.0 available? (the Data Length Extension feature would kinda solve my problem)
2 - Implement all my research in Cpp (which is not my strongest haha) and data fusion in the device itself, sending only my own fusion data.

I appreciate any thoughts you may have.
Thank you in advance.
« Last Edit: June 17, 2020, 08:24:54 PM by Tacca »


lennevia

  • Administrator
  • Hero Member
  • *****
    • Posts: 104
    • View Profile
Hello Tacca,

Have you considered using a Micro SD Card TinyShield? You would be able to save all of the necessary data with timestamps to be able to process it later.

I am curious about the range of Bluetooth on a runner.

TinyCircuits is in the process of designing a new processor board that includes a newer Nordic BLE module that may support the Data Length Extension you have mentioned.

Hope that helps give you some ideas on what you can do. In the future, I may have more time to look into the code you are currently developing to give better insight.

Thanks,
Réna


Tacca

  • Jr. Member
  • **
    • Posts: 5
    • View Profile
Hello Réna, thanks for the reply.

Now that you mention it, I had discarded the idea of a SD Card because I didn't want to have the runner plugging-unplugging the sd card for processing.
BUT... giving it another thought, it might be possible to just store (at a fast rate) and sync the data (at a safe rate) using SD card... this would imply in a little delay for the data showing on the device, but, the data amount would be good enough, solid and accurate.

I will probably order it since it might solve the problem.

Thank you again.


 

SMF spam blocked by CleanTalk