red30 said:
I also noticed on Friday that if I make a request for BleMan.WriteData, and I do not ask again, there are times that it does not reach at all ... Why can this happen?
Are you into fishing? You sure do like opening cans of worms
I expect what's happening is that a BLE write is not guaranteed, as in the Android BLE interface isn't automatically retrying failed operations that got clobbered by competing wifi or other Bluetooth transmissions (or you reheating your coffee in the microwave...) The write request is sent out, and if the BLE device happens to hear it, then it sends back a "no worries, got that, thanks" message that also might separately get clobbered and never make it back to you as a WriteComplete event.
Now, for normal BLE GATT operation, this isn't so bad. Let's say we want to set a BLE-controlled light to 40% on, we do a WriteData 40 to the light-level characteristic, the light receives it, sets the light accordingly, sends us back a confirmation which we receive as a WriteComplete event, and we'e like:
job done; how easy was that?
At least that's how it works according to the spec sheet and in the classroom. In the real world and the 2.4 GHz radio band, it's more like:
But for our 40% light example, we're ok: if we don't get that WriteComplete confirmation back within a reasonable time, we just try again, until nature submits to our persistence (and laws of probability) and we fluke both the outgoing and return transmissions making it across that radio ocean unscathed.
Sometimes our outgoing packet might get through ok, but the return confirmation is lost, and thus we repeat the outgoing packet and that gets through too (ie, received twice). No harm done in our 40% light example - the light still ends up at the write setting ie 40%. Duplication is no problem,
to be sure, to be sure.
But now, what about this HM-10/HC-08 serial link? We send (say) 50 bytes of data, it gets broken down into 20:20:10 byte chunks and sent as 3 writes over BLE. Assuming them dragons be looking the other way and those 3 packets all get through ok, everything's great - the HM-10/HC-08 module receives the 20+20+10 bytes, shoves 'em out the serial port, we get our WriteComplete confirmations, life is sweet. Ship that baby!
But if one of those packets goes missing, what do we do? We know something's gone wrong, in that we're missing a WriteComplete confirmation, but we don't know precisely
what has gone wrong, in that it could be one of these
two scenarios:
(1) the outgoing message got clobbered, and thus no confirmation was sent
(2) the outgoing message got through, but the return confirmation got clobbered
It all looks the same to us, ie, we didn't get confirmation that the data got through. Our two options are:
-
repeat the write request, which solves for scenario 1, but results in data double-up if it was scenario 2, eg: we send "
one two three four five six seven eight nine ten" but what comes out the UART at the other end is "
one two three four five six seven eight ive six seven eight nine ten". Nice try, but no cigar.
-
ignore the issue, which solves for scenario 2, but results in data loss for scenario 1, eg "
one two three four f{lost data}nine ten". This is definitely a no-cigar result.
Many protocols solve this problem by sequence-numbering individual packets, but I'm pretty sure BLE doesn't do this*. And, as with the 40% light example above, this is no problem for the usual BLE use-case. Presumably the reasoning behind leaving it out was that: if somebody needs it, they can do it themselves.
{*I could be wrong here, maybe BLE does do this -
and it'd be fantastic if it did - but I haven't seen anything that confirms it}
So, some applications using HM-10/HC-08 modules as a serial link replacement could be headed straight for that dragon zone.
In your case, though, given that you can align your outgoing serial data packets on, and within, the 20-byte packetization by the HM-10/HC-08 module, you should be ok.
It is possible that the return data might be split across two packets, eg 3 bytes in one packet and 5 bytes in the next, but because you're only expecting return 8-byte packets in-between requests, this should also be ok, provided that you're using BLE indications (ie, confirmed) rather than notifications (ie, unconfirmed).
If you don't get a WriteComplete for an 8-byte request that you've sent, then you just send it again, and (as I understand it) if your PIC happens to get both 8-byte requests, then it will either reply once (no problem) or twice (still mostly* no problem, because both 8-byte responses will fit within a single 20-byte return BLE packet).
{*ok, ok, yes... it is possible that they might be split across two packets, but I'm pretty sure that will be taken care of anyway because you're already awake to the possibility that even a single 8-byte response might be split across two BLE packets and, worst case, if the duplicate responses were split at the 8-byte response boundary and thus you weren't expecting the second one because you've already received the first one without anything extra (yet), then - as I understand it - you can identify responses by their header bytes, so:
what could possibly go wrong?!?!)