Bary Nusz
Published © GPL3+

Heart Rate Display with a Photon and a Microsoft Band

Integrating the Microsoft Band’s heart rate sensor with a Particle Photon so you can visualize your heart rate with an RGB LED.

BeginnerShowcase (no instructions)3,046

Things used in this project

Hardware components

Photon
Particle Photon
×1
Microsoft Band
×1
RGB LED, Common Cathode
×1
Resistor 1k ohm
Resistor 1k ohm
×3

Story

Read more

Schematics

Photon Circuit

Photon Circuit

Code

Windows Phone App

C#
The Windows Phone project combined elements from both my previous Microsoft Band posts and my RGB LED Photon post. This section is straight from previous Band posts except I’m setting up the heart rate sensor and event handler. This handles reading the heart rate from the Band. Note: in order to access the user’s heart rate you must call the SensorManager.HeartRate.RequestUserConsentAsync function, which displays a consent dialog to the user.
private async void Button_Click(object sender, RoutedEventArgs e)
{
    try
    {
        this.sensorTextBlock.Text = "Connecting to Band";
        // Get the list of Microsoft Bands paired to the phone.
        IBandInfo[] pairedBands = await BandClientManager.Instance.GetBandsAsync();
        if (pairedBands.Length < 1)
        {
            this.sensorTextBlock.Text = "This sample app requires a Microsoft Band paired to your phone. Also make sure that you have the latest firmware installed on your Band, as provided by the latest Microsoft Health app.";
            return;
        }

        timer.Start();

        // Connect to Microsoft Band.
        using (IBandClient bandClient = await BandClientManager.Instance.ConnectAsync(pairedBands[0]))
        {
            start = DateTime.Now;
            this.sensorTextBlock.Text = "Reading heart rate sensor";

            bandClient.SensorManager.HeartRate.ReadingChanged += HeartRate_ReadingChanged;
            await bandClient.SensorManager.HeartRate.RequestUserConsentAsync();
            await bandClient.SensorManager.HeartRate.StartReadingsAsync();

            await Task.Delay(TimeSpan.FromMinutes(5));

            await bandClient.SensorManager.HeartRate.StopReadingsAsync();
            bandClient.SensorManager.HeartRate.ReadingChanged -= HeartRate_ReadingChanged;
        }
        this.sensorTextBlock.Text = "Done";
    }
    catch (Exception ex)
    {
        this.sensorTextBlock.Text = ex.ToString();
    }
}

private async void HeartRate_ReadingChanged(object sender, Microsoft.Band.Sensors.BandSensorReadingEventArgs<Microsoft.Band.Sensors.IBandHeartRateReading> e)
{
    var span = (DateTime.Now - start).TotalSeconds;
    IBandHeartRateReading reading = e.SensorReading;
    string text = string.Format("Heartrate = {0}\nQuality = {1}\nTime Stamp = {2}\nTime Span = {3}\n", reading.HeartRate, reading.Quality, reading.Timestamp, span);
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { this.sensorTextBlock.Text = text; }).AsTask();
    start = DateTime.Now;

    lock(hrLock)
    {
        heartRate = reading.HeartRate;
    }
}

Windows Phone App

C#
This section is straight from my previous Photon RGB LED post where I constructed an HTML post to send to the Particle Cloud. The data I’m posting to my Photon is in the following CSV format: “{Red Value},{Green Value},{Blue Value},{Heart Rate}”. I’m using a timer to check to see if the heart rate value has changed. If the value has changed, an HTML post is sent to the Particle cloud. I compute the color based upon a sliding scale from a low heart rate (around 50bpm) being full blue and a high heart rate (around 140bpm) being full red. I then post the computed color and heart rate to the Particle cloud. From there the data makes its way down to the Photon and the RGB LED.
private async void Timer_Tick(object sender, object e)
{          
    if (heartRate != lastHeartRate)
    {
        lastHeartRate = heartRate;
        timer.Stop();

        int rValue = (int)ScaledValue(255, 0, highHeartRate, lowHeartRate, lastHeartRate, true);
        int gValue = 255 - rValue;

        SolidColorBrush color = new SolidColorBrush(new Color() {
            R = (byte)rValue,
            G = (byte)gValue,
            B = 0 });

        await SetRGBHeartRate(color, lastHeartRate);

        timer.Start();
    }
}

private async Task SetRGBHeartRate(SolidColorBrush rgb, int heartRate)
{
    string url = String.Format("https://api.particle.io/v1/devices/{0}/setRGBHR?access_token={1}", 
        PHOTONDEVICEID, 
        ACCESS_TOKEN);
    var request = WebRequest.Create(url);
    var postData = "value=" + string.Format("{0},{1},{2},{3}", 
        rgb.Color.R, 
        rgb.Color.G, 
        rgb.Color.B, 
        heartRate);
    var data = Encoding.UTF8.GetBytes(postData);
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    using (var stream = await request.GetRequestStreamAsync())
    {
        stream.Write(data, 0, data.Length);
    }
    try
    {
        var response = await request.GetResponseAsync();
        var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
    }
    catch { }
}

Photon Firmware

C/C++
This section is the Photon firmware. It is straight from my previous Photon RGB LED post with an update for handling and displaying the heart rate value.
// This #include statement was automatically added by the Particle IDE.
#include "rgb-controls/rgb-controls.h"

#define REDPIN D0
#define GREENPIN D1
#define BLUEPIN D2
using namespace RGBControls;

Led led(REDPIN, GREENPIN, BLUEPIN);
Color currentColor(255, 0, 0);
int heartRate;
Color noColor(0, 0, 0);
Color blueColor(0, 0, 255);

void setup() {
    bool success = Particle.function("setRGBHR", setRGBHR);
    heartRate = 120;
    //currentColor = blueColor;
}

void loop() {
    int fullDelay = 60000 / heartRate;
    int quarterDelay = fullDelay * 0.25;

    led.fadeOnce(noColor, currentColor, quarterDelay);
    delay(quarterDelay);
    led.fadeOnce(currentColor, noColor, quarterDelay);
    delay(quarterDelay);
}

int setRGBHR(String command)
{
    Particle.publish("setRGBHR", command);
    //Data comes in the format "{R},{G},{B},{HR}"
    int commaIndex = command.indexOf(',');
    //Strip the red color from the string
    String red = command.substring(0,commaIndex);
    
    command = command.substring(commaIndex+1);
    commaIndex = command.indexOf(',');
    //Strip the green color from the string
    String green = command.substring(0,commaIndex);
    
    command = command.substring(commaIndex+1);
    commaIndex = command.indexOf(',');
    //Strip the blue color from the string
    String blue = command.substring(commaIndex);
    
    //Strip the heartrate from the string
    String hr = command.substring(commaIndex+1);
    heartRate = hr.toInt();

    Color newColor(red.toInt(), green.toInt(), blue.toInt());
    //What's new is old now
    currentColor = newColor;
    
    return 1;
}

Project Code

Credits

Bary Nusz

Bary Nusz

8 projects • 32 followers
Nusz Labs “Tinkerer-in-Chief”.

Comments