-
Notifications
You must be signed in to change notification settings - Fork 0
/
IHeartRateProvider.cs
67 lines (62 loc) · 2.32 KB
/
IHeartRateProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
namespace CardioMeter;
public struct HeartRateEventArgs
{
public int HeartRate { get; private set; }
public int? EnergyExpended { get; private set; }
public DateTime Timestamp { get; private set; }
public double? RRInterval { get; private set; }
public override String ToString()
{
return String.Format("HeartRate: {0}, EnergyExpended: {1} J, Timestamp: {2}, RRInterval: {3} ms", HeartRate, EnergyExpended, Timestamp, RRInterval);
}
public static HeartRateEventArgs FromDummy(DateTime timestamp)
{
var ret = new HeartRateEventArgs();
ret.Timestamp = timestamp;
var unixMs = (timestamp.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
var periodMs = 30_000;
var amplitude = 20.0;
ret.HeartRate = (int)(amplitude * Math.Sin(unixMs / periodMs * 2 * Math.PI) + 160);
ret.RRInterval = 6000.0 / ret.HeartRate;
return ret;
}
public static HeartRateEventArgs FromBLEHeartRateMeasurement(byte[] rawValues)
{
// https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.heart_rate_measurement.xml
var ret = new HeartRateEventArgs();
ret.Timestamp = DateTime.Now;
var flagByte = rawValues[0];
var hrIsUint16 = (flagByte & 0x01) != 0;
var valuePtr = 1;
if (hrIsUint16)
{
ret.HeartRate = BitConverter.ToUInt16(rawValues, valuePtr);
valuePtr += 2;
}
else
{
ret.HeartRate = rawValues[1];
valuePtr += 1;
}
var sensorContactFlag = (flagByte & 0x06) >> 1;
var hasEnergyExpended = (flagByte & 0x08) != 0;
if (hasEnergyExpended)
{
ret.EnergyExpended = BitConverter.ToUInt16(rawValues, valuePtr);
valuePtr += 2;
}
var hasRRIntervals = (flagByte & 0x10) != 0;
// only get the final RR interval
if (hasRRIntervals)
{
ret.RRInterval = BitConverter.ToUInt16(rawValues, rawValues.Length - 2) / 1024.0 * 1000.0;
}
return ret;
}
}
public interface IHeartRateProvider
{
public event EventHandler<HeartRateEventArgs> HeartRateReceived;
public event EventHandler OnConnectionLost;
public event EventHandler OnConnectionEstablished;
}