This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Approach for serial over BLE?

Hello, we have kind of an in-house serial command protocol that we have used over Rs232, sockets, wifi, etc, and we would like to implement it over BLE. I am inheriting a good Nordic BLE project from a coworker, so I'm not expert in BLE yet, so please bear with me...

Our serial protocol is simple and framed, something like [command param1, param2... paramN|crc]. There is no max message length.

My understanding of BLE (from research and looking at my inherited code) is that a BLE interface is made up of one or more attributes which are a fixed length and act more or less like mailboxes... one side writes to an attribute, other side gets a notification that it has been updated and can read/use the data, and vice versa.

I need this interface to act like a serial port. My understanding from posts such as this:

devzone.nordicsemi.com/.../

is that if I want this, I need to implement it myself. So, the approach I'm toying around with is something like the below, which breaks the message up into several updates and uses the first two bytes as a length parameter. Pseudocode below.

Questions:

  • Do I suffer from some gross misunderstanding?
  • Is this a good way to implement serial over BLE (honestly this feels like the long way around; I'm surprised I have to do all this, maybe this is square peg round hole?)
  • Will I have timing issues? Seems like if the sender sends too fast, old updates could get overwritten with new before properly processed by other end (which is okay for a measurement, but very bad for serial data). For robustness do I have to incorporate some sort of "ready to receive" message back (what a pain this would be), or does BLE buffer these updates for me somehow?

Thanks very much for any thoughts.

SENDER PSEUDOCODE:

define ATTRIBUTE_LENGTH 20

void SerialOverBLEServer_TX(char *data, int length)
{
   while (length > 0)
   {
       if (length >= ATTRIBUTE_LENGTH)
       {   
          [set first two bytes to 20]
          [set rest of attribute to the next 18 bytes of serial data]
          length-=ATTRIBUTE_LENGTH);
          *data+=ATTRIBUTE_LENGTH);
       }
       else
       {   
          [set first two bytes to remaining length]
          [set rest of attribute to remaining serial data]
          length=0;
       }
       send_value (using sd_ble_gatts_hvx?)
   }       
 }

RECEIVER PSEUDOCODE:

void SerialOverBLE_RxHandler()  // notification on receiver that attribute is updated
{
    [Read the first two bytes as a length]
    [Process the appropriate remaining data as serial data]
}
Related