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]
}
Parents
  • You have a fairly good understanding of the situation I'd say.

    You may or may not need to implement anything though. Nordic were kind enough to give us a pre-programmed uart service. It can be found in the latest SDK docs here: this is a really good read

    Embrace this well-crafted and nearly comprehensive documentation. If you want to check out another SDK version, that's available too. I recommend getting a BLE book as well depending on how much you care to learn about the spec.

  • Thank you! I will read that thoroughly. But one question, in case you're familiar:

    Does the Nordic service (a) handle the timing issue I ask about above? Or (b) doesn't have to because BLE handles it natively (eg buffers/queues attributes updates, to guarantee notification of each) (so it would also apply to my code above), or (c) neither of the above, and you just have to be careful not to send too fast (in either approach)?

    The reason I'm asking is because my predecessor already implemented two custom attributes we are using as RX/TX for a specific handshake. It could be extended fairly easily to general serial I/O as I describe above. Although what you're proposing seems to be the "right" way, the quicker path to success may be my code above.

    What would make the decision for me is if their service is guaranteed to work with fast input, in a way that my code above is not.

Reply
  • Thank you! I will read that thoroughly. But one question, in case you're familiar:

    Does the Nordic service (a) handle the timing issue I ask about above? Or (b) doesn't have to because BLE handles it natively (eg buffers/queues attributes updates, to guarantee notification of each) (so it would also apply to my code above), or (c) neither of the above, and you just have to be careful not to send too fast (in either approach)?

    The reason I'm asking is because my predecessor already implemented two custom attributes we are using as RX/TX for a specific handshake. It could be extended fairly easily to general serial I/O as I describe above. Although what you're proposing seems to be the "right" way, the quicker path to success may be my code above.

    What would make the decision for me is if their service is guaranteed to work with fast input, in a way that my code above is not.

Children
No Data
Related