Wednesday, 2 November 2011

Connecting Polar WIND chest strap to Arduino

I have Polar RS800sd watch for some time. It has capabilities of measuring heart rate, running speed and distance. According to polar docs both chest and foot sensors use 2.4GHz frequency. I was tempted to figure out a way to connect these sensors to something different from original watch for a long time. Recently I have stumbled upon really nice work on Nike+ by Dmitry Grinberg and decided to follow his steps with my polar watch.

I have disassembled chest sensor (Polar WearLink WIND).

Here is how it looks like inside:
It uses the same radio transmitter as Nike+iPod (Nordic nRF2402).

The testpoints above nRF chip are responsible for SPI. I have used needles, tape and hot glue to connect Logic Analyzer to SPI on these testpoints. This step was fairly tricky, but this is still easier for me than soldering in such a tight space between ICs. :)

Once I have connected my Open Bench Logic Sniffer to these testpoints and dumped initial configuration and a lots of data frames. Luckily Nordic has released all the specs for nRF2402, so decoding configuration was easy. After power up two bytes are sent over SPI bus: F7 49. This means that chest sensor transmits using Shockburst on channel 73 at speed of 1 Mbps with 16-bit CRC. Data frames provided me with an idea  what address is: all frames that I have seen starts from C6 A1 01 F8 11. By looking at the data frames at the transmitter side it is impossible to tell what byte is the end of address and what is the start of data. CRC is also calculated on entire frame with address. To be on the safe side I have assumed that address is C6 A1 and the remaining static data is part of device serial number or something similar. I could not confirm this as I have only one sensor. Total of 28 bytes are transmitted in each packet (including address).  nRF24L01+ actually supports 2 byte addresses despite lack of information about it in the datasheet. AW_SETUP has to be set up to 0 to achieve this.

Next step is to receive data on some other device. I have picked up nRF24L01+ breakout board and connected it to arduino. I have set the receiver to the parameters above and it worked! Chest sensor transmit approximately 2 packets every second. Interestingly packets are sent in pairs that are exactly the same, only first bit is flipped.

OK, now it's time to try to make sense of the data. To investigate this black box I required a consistent reproducible test environment... and normal human heart rate fluctuate all the time. To get around this problem I decided to "emulate" electrical activity of the heart. Heart beat cycle has prominent phase when ventricles contract - this phase is called R wave. It can be easily seen on any ECG as sharp peak. Most of simple heart pace monitors detect only R wave. So I have connected the sensor to the same arduino through 10kOhm resistor and made arduino output pulse with duration of 1msec every second. This simple test setup has proved good enough to trick the sensor to believe that it is connected to very stable 60bpm heart. I have dumped a lot of packets sent in this mode and couple of things was instantly obvious:
1. 8th byte (including address) contains instant heart rate. No conversion necessary. 
2. Last byte of the packet (28th byte including address) contains moving average of heart rate. No conversion necessary. This value is instantly displayed on the watch as heart rate. This value reacts to changes slower then previous one.

The rest of the data protocol remains unreversed. But we already have most significant data that we can get out of it - heart rate!
Polar watches are also capable of recording time between individual heartbeats - R-R intervals. I suspect that bytes 09-15 serve this purpose (The number of non-zero bytes there increase with heart rate).

If anyone wants to have a look - you are welcome to have my data dumps:

My arduino sketch can be downloaded here.


Serial output:


  1. hi,

    did you get any progress on this ?

  2. Hi Artem,

    Nice work discovering the important parts of the WIND inner workings. I am about to take on a similar project and your information really helps a lot getting started.

    From the picture I can see the transmitter is controlled by a Texas Instruments micro controller running off a 32 kHz resonator. Its internal clock may be 1 MHz, but is rather inaccurate, which make me believe that byte 23-25 in the payload can be the content of a counter register.
    The counter may be initialized to around 0x400000 for about every 7-8 payloads and decremented by a multiple of 4095 between each transmission. As the factor between each transmission is not constant, this could be the result of the inaccuracy of the internal DCO in the micro controller.
    The cycle seems to end with a payload of 0x00038B each time.

    I have not looked into byte 26-27 yet, but it could also be an average depending on the heart rate. At first I thought it was the output of a FIR filter, but in the end it is lower than the average heart rate, so some kind of offset is applied at least.

    All the zeroed bytes puzzles me a bit, but could possibly be there for backwards compatibility issues.

  3. Nicky, I have stopped reversing polar chest strap once I have got HR data out of it. For my project that proved sufficient.

    asdasd, please keep me posted on your WIND protocol reversing.
    As for zerod space I still think it might be related to the fact polar records R-R variability data (intervals between individual heartbeats) and several heartbeats can be recorded in each packet (up to 3 at 180bpm).

  4. Hi Artem,
    I myself have started to use Polar Wearlink for a Capstone Project. Do you recommend me using your method or buying the Polar Heart Rate Interface. My project needs to detect heart beats, falling detection(accelerometer needed), and have some serial/bluetooth communication. The HRI would help since it has a PIC on it, and it will detect the Polar Wearlink. Let me know.

  5. hi Artem,

    i building a project with arduino and nrf24l01 modules and would like to read data from polar heartchest with frist arduino and then send it to an other arduino with nrf24 and lcd to display the data

    is it possible?

  6. Hi. This is very interesting. Had you considered just connecting to the polar W.I.N.D USB key, and attaching that to your arduino, iPhone, Android, etc? The protocol over the USB would likely be the same as what is transmitted, I would guess.