Quantcast
Channel: C# – Falafel Software Blog
Viewing all articles
Browse latest Browse all 54

Heart Rate Display with a Photon and a Microsoft Band

$
0
0

Those who know me, know I love sensors, and doing things with sensors. I’ve published many posts on accessing the various sensors on the Microsoft Band: Accelerometer & Gyroscope, Ultraviolet, Skin Temperature, and Galvanic Skin Response. One subject that I haven’t gotten to is the heart rate sensor. I’ve also started to publish a few IoT posts. For this post, I thought it would be fun to integrate the Band’s heart rate sensor with a Particle Photon so you can visualize your heart rate with an RGB LED. The LED pulses at the same rate as your heart and will shift its color from blue (for low rates) to red (for high rates).

Click to see my heartbeat

Click to see my heartbeat

In order to access the heart rate sensor on the band, I’m following the same project format as in my previous posts listed above, which are all based upon the Windows Phone. For other phones and devices, you can get what you need on the Band developer site.

To send the heart rate value and control the RGB LED with a Photon, I’ll use the same hardware, software, and firmware as my recent post on Controlling an RGB LED on a Photon with a UWA Color Picker. I did need to update the firmware to accommodate the pulsing of the LED to match the heart rate. I also needed to update the software to send the heart rate along with the color info.

Parts Used

Schematic

Falafel-Test-2 (10)

Software

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;
    }
}

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 { }
}

public static double ScaledValue(double max2, double min2, double max1, double min1, double v1, bool bindMinMax)
{
    if (bindMinMax)
    {
        if (v1 > max1) v1 = max1;
        if (v1 < min1) v1 = min1;
    }
    var v2 = ((v1 - min1) * (max2 - min2) / (max1 - min1)) + min2;
    return v2;
}

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;
}

You can download the project here.

The resulting project demonstrated that it was possible to tie together these diverse devices into a potentially useful system. I found that, while manually taking my own pulse, the pulsing of the LED did indeed follow the same rate. Of course the LED pulse wasn’t in sync with my heart beat, but it was evident that the rates did match. How might this be used? Not sure, but I found it to be cool.

The post Heart Rate Display with a Photon and a Microsoft Band appeared first on Falafel Software Blog.


Viewing all articles
Browse latest Browse all 54

Trending Articles