• I want to stream ADC data from the MDBT42 module via web bluetooth. The sampling & DMA part works nicely (thanks for the low-level library Gordon!). With 256x oversampling, I have a theoretical 781 effective sample / second. Each sample is an Uint16 value.
    I have seen the Web bluetooth and Web Bluetooth Dashboard tutorials, and looks like that can work.
    Need to fiddle with serialization, because JSON feels inefficient - 6 characters (worst case) to transfer 2 bytes of data. And the communication wasn't really happy at 160ms intervals :/

    My questions:

    • any better solution than the "UART" between a browser and and nRF?
    • any better serialization format for Uint16 array? Current idea: convert to hex, transfer without separator, and reassemble from 4 byte chunks. That's roughly 2/3 data usage compared to JSON, not sure about the CPU usage. And 😴
    • I guess bluetooth layer itself takes care about data integrity & ordering. Right? :) Or should I add my own CRC or other error check?
  • any better solution than the "UART" between a browser and and nRF?

    Not really - you can create your own characteristics, but because the UART is handled natively by Espruino it will probably be slightly faster.

    any better serialization format for Uint16 array?

    Raw binary :) I think just Bluetooth.write(uint16array.buffer) should do it, then you can decode on the other end.

    Bluetooth LE packets are normally 20 bytes max, so if you can send in chunks that are multiples of 20 you're likely to get slightly better bandwidth.

    Also do NRF.setConnectionInterval(7.5) as this'll force high speed comms all the time (usually Espruino drops it after some inactivity).

    I guess bluetooth layer itself takes care about data integrity & ordering.

    Absolutely yes :)

  • Oh, best serialization is no serialization at all :)

    Current progress: pretty happily pushing 128 * 16 bit values at 100ms intervals, and that is more than enough for this project.
    Thanks Gordon!

    For the record, going below 100ms interval, the busy LED becomes almost always on, and the actual throughput doesn't increase (measured in the browser by the number of received "packets").

    Edit: doing some math :)
    Theoretical maximum data transfer: (1000 ms /7.5 7.5ms interval)* 20 byte packets = 2666 bytes / sec
    Measured maximum: 260 bytes * 10 times per second = 2600 bytes / sec
    Is this pretty damn close to the theoretical maximum? :)

  • That sounds about right, yes :)

    At some point I believe we could enable a larger MTU (eg >20 byte chunks) which would really improve matters, but it's not guaranteed it won't just fall back to 20... So you could create something that'd work on one computer but bomb on another - and that sounded like a support nightmare :)

  • Sneak peek: Power consumption of a Pixl.JS streamed real time via web-bluetooth :)

    UI needs more work. Plotly doesn't really like redrawing thousands of data points in real time. :(
    Does anyone know a high-perf charting library?


    1 Attachment

    • 2019-09-23 21_40_17-localhost_8080.png
  • Nice - how did you work out the power consumption?

  • Just data from the INA226 :)
    Current measurements were working ok with just the MDBBT42Q and the low-level SAR ADC module with averaging.
    But the INA226 can work with a lower value shunt, can do low-side and high-side measurement, and has a higher maximum input voltage without thinking about the analog part.

  • Just tried creating my own characteristic + using notify:
    Works nicely, sending 4 byte notifications every 10ms seems to work fine.
    One huge benefit over using the Nordic Uart: the Nordic uart is still usable. I can connect to the same Puck with the Web Ide and my Web Bluetooth application at the same time!

    Edit: and on the browser side just receiving data at 100Hz doesn't create any extraordinary CPU usage. Actually I have dozens of tabs open in Vivaldi, and a couple in Chrome, and my laptop CPU clocks down to <1GHz and <10% CPU usage by Chrome :)

  • Created an example project with the Puck + Web Bluetooth pushing the magnetometer data at up to 80 Hz. It's really kind-of-surprisingly smooth.

    Code up at my Github
    Shaky can video: https://youtu.be/72ViaRna7ZM

  • Wow, this is so cool, thanks for sharing!

  • Thanks!

    A quick update (as I'm exploring these things): you can connect to, and receive notifications from multiple services. demonstration with battery level service.

    I have a more practical use: measuring energy consumption with an INA226: BLEnergyGraphs Right now uses the NUS for communication, but plan to "upgrade" it using custom characteristic & improve usability.

  • Nice - thanks!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

"Streaming" data via bluetooth - now with example code!

Posted by Avatar for AkosLukacs @AkosLukacs

Actions