Replies: 2 comments 6 replies
|
For a phone-to-watch protocol, I would not share the same line-oriented channel with the REPL and console output. A custom BLE characteristic with a small framed protocol is the robust solution. The frame should include a message type, length, sequence or request ID, payload, and checksum/CRC if corruption is possible. The watch can send notifications for responses/events, while writes from the phone carry commands. That keeps application traffic independent from debug prints and avoids trying to parse a stream that can legally contain arbitrary console text. If a custom characteristic is not practical for the first prototype, move the REPL/console to a different transport and reserve the existing BLE channel for the app, but document the trade-off: changing the console can affect the app loader and development workflow. Temporarily suppressing prints during the handshake may hide symptoms, but it will not solve interleaved output during normal operation. Also make the protocol tolerant of partial BLE packets. A single write/notification is not guaranteed to contain one complete application message, so the receiver needs a buffer and a parser that can recover from an incomplete frame. Add a version byte and reject unexpected frame types instead of letting a malformed command enter the REPL. That separation will make BlueWatch more reliable and leave the console useful for debugging instead of turning debug output into a source of protocol corruption. |
|
It's not ideal, but we have managed pretty much ok with Gadgetbridge and the App Loader so far. If you split by newline, and ignore anything that doesn't start with
This shouldn't happen? do you have an example? In the App Loader/etc we send It's easy to say that it should be a custom characteristic, but there are all kinds of gotchas. As the post above mentioned, partial writes - and the limit on the maximum size for characteristic writes (so how would you split one notification over several writes). Also we handle the Nordic UART characteristic internally (with a buffer) so it's more efficient than just a direct write. ... not to mention the difficulty adding features and being backwards compatible if there's a predefined communications format with message IDs (especially if you define that just for your iOS app). Having said that, recent builds have added a packet protocol on top of the standard Nordic UART channel: https://github.com/espruino/Espruino/blob/master/README_Protocol.md It's also supported by UART.js (https://github.com/espruino/EspruinoWebTools/blob/master/uart.js#L83-L94) and the app loader does increasingly try and use it - so you could use that for sending commands, and at least you get an 'ack'. There's also this which might be handy: https://github.com/espruino/Espruino/blob/master/src/jsinteractive.c#L1871 so you can do that right after connect to get info on the device |
Uh oh!
There was an error while loading. Please reload this page.
For BlueWatch, the iOS companion app, I'm struggling a bit with the default bluetooth communications channel being the same as the repl and console. SInce prints and logging show up at the same time as the app and phone handshake, it's struggling to connect properly without interference from prints, functions, and other data on the repl stream, and the commands often get corrupted or mixed with another line in REPL as a result. Is there a way that I can separate the communications between the app to watch, and the repl and app loader in the app? I know you can always make your own characteristics for communications, or change where the console is set, but I don't quite know if that's the way to go about this, or if there's an easier way.
All reactions