Giter Club home page Giter Club logo

biofeed's Introduction

Biofeed

Rebroadcast Bluetooth heart rate sensor data as UDP Open Sound Control (OSC) messages

This Python script interfaces with a bluetooth single-lead ECG device (heart rate monitor) and rebroadcasts the data over UDP for consumption by other devices on the same IP network. The intended use case is in biofeedback experiments where this stream is used to produce modulation signals for synthesizer patches. This also serves as a place to collect code fragments, notes, and examples on Bluetooth and OSC messaging.

Photo by Richard R. Hewitt

Interfacing with Audio Software

Rather than send packets with an ad hoc format such as raw bytes, the data are encoded as Open Sound Control messages, which are understood by software like Native Instruments Reaktor.

In Reaktor the OSC settings are located under the File menu. You must click the OSC Activate checkbox at the top of this settings window to begin receiving OSC messages. Although Reaktor displays the IP address of your network interface, it should also receive messages sent by this script on the loopback interface. The port should be set to 5005. Once this is set up, you can add a module to your patch: Built-in Modules -> OSC -> OSC Receive. In the Connect tab of that module, you can select /h10/hr for heart rate in BPM or /h10/rr for ECG R-R intervals. Integer R-R intervals are about 15 times more precise than integer heart rates, but you may want to invert the R-R-R values in a patch as these values decrease when heart rate increases. Both should be updated at about one-second intervals.

Unfortunately I have not yet identified a way to receive the data in the Bitwig Grid.

It should be possible to receive messages in VCV Rack using this module: https://github.com/j4s0n-c/trowaSoft-VCV#cvosccv.

Interfacing with the Heart Rate Sensor

I do not have much experience interfacing with Bluetooth devices, so rather than diving into platform-specific calls to OS Bluetooth services, I wanted to begin with a cross-platform library in Python. The code here was written for the Polar H10 because this is the device I have on hand. It has only been tested with this device, but certain aspects of the code should work with other heart rate devices.

The Polar H10 provides heart rate, R-R interval, and the realtime ECG data from which these figures are derived. The ECG data is filtered on the device to remove low frequency components from muscle movement etc. It can also provide other data such as accelerometer data which are not yet read by this example.

The H10 is a Bluetooth Low Energy (BLE) device, a standard which is actually completely separate from classic Bluetooth. The heart rate and R-R interval data area follow the Bluetooth Low Energy (BLE) Generic Attribute Profile (GATT), which makes them non-proprietary and allows them to be read by devices from various manufacturers without special configuration. The ECG data follows the proprietary Polar Measurement Data (PMD) specification.

Abbreviations

  • BLE: Bluetooth Low Energy, a separate specification from "classic" Bluetooth.
  • PMD: Polar Measurement Data. This is explained by the PMD Specification document.
  • PPG: Photoplethysmography (PPG) is optical blood flow data, as collected by watches or armbands like the Polar OH1. The Polar H10 collects true ECG data rather than PPG.
  • Other relevant abbreviations are defined at the end of the Polar Measurement Data Specification.

Bluetooth Low Energy

Bluetooth Low Energy (BLE) is a completely separate standard from classic Bluetooth. BLE Servers advertise their presence every so often. They may advertise frequently after some kind of interaction, then back off to save energy.

BLE has a data rate of 100kbit to 1Mbit per second. This is not sufficient for transmitting voice, but fine for many other purposes. It uses very little energy. Some devices like the H10 can run for one or two years on a single cell battery.

BLE has several pairing procedures. Some devices Just Work (this is apparently the technical name), while others rely on passkey entry to flout Man In The Middle (MITM) attacks. The H10 seems to "just work". Connections begin in Security Mode 1, Level 1 (no authentication and no encryption) and can then be upgraded to any security level.

A certain UUID range is reserved for GATT standard services. These are represented with four hex digits (a 16 bit integer), which are substituted into the first 32-bit section of the UUID (e.g. the service ABCD gives the UUID 0000ABCD-0000-1000-8000-00805f9b34fb). All other pseudorandom UUIDs can be used by manufacturers for their own purposes. You shouldn't need to manually insert the 16 bit numbers into this standard UUID (as done in some example code). I'd expect the bluetooth library to do this for you.

Each device has a MAC address and UUID that uniquely identify it. For some reason these are not used to connect to the device on MacOS. A UUID is used instead.

BLE GATT defines some technical terms. It's important when reading technical documentation like the Polar Measurement Data (PMD) Specification to interpret these terms in their narrow GATT technical sense, not as everyday English words. The hierarchy of terms is: Device -> Service -> Characteristic -> Detail. Each one of these has a reserved UUID (in the case of standard GATT) or a pseudorandom one assigned by a manufacturer for proprietary extensions. I will write these terms with Initial Capitals to indicate that they are being used in their narrow technical sense. When reading the PMD specification, note that a list of acronyms is at the end of the document, and some important interactions are given only as examples without text explanation.

Heart Rate is a standard Characteristic. The H10 defines an additional Polar Measurement Data (PMD) Service whose UUID begins with FB005C80. This contains two Characteristics whose UUIDs are the same as the Service except that the initial 32-bit segments end with 5C81 (the PMD Control Point) and 5C82 (the PMD Data MTU Characteristic).

If the H10 is paired with some other device (such as your phone or watch), you may get bleak.exc.BleakError: Device with address X was not found. Or maybe if the contacts are not wet - once I wet them, I saw it three times in 5 seconds. But then it failed again - maybe I need to call stop_notify and disconnect to free it up. Or maybe it was simply Bluetility interfering with my connection attempt.

The H10 seems to advertise its presence even when it's not being worn, but also seems to refuse connections until it detects skin contact.

The ECG data is not present in the standard GATT profile and is specific to Polar. It uses a Service and Characteristics described in the Polar Measurement Data (PMD) Specification document, which is available as a PDF in the Polar BLE SDK repository on GitHub.

read_gatt_char means read a Characteristic, not a character.

There are no spec pages for querying or setting stream settings or starting a stream, but the document contains examples of doing these things for Acceleration, ECG, and PPG streams with embedded explanations of the bytes in the messages.

A tool called Bluetility can be used on MacOS to browse the characteristics of nearby bluetooth devices. https://github.com/jnross/Bluetility/releases

Sources:

biofeed's People

Contributors

abyrd avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.