-
Notifications
You must be signed in to change notification settings - Fork 23
/
HeartRateMonitor.ino
144 lines (124 loc) · 4.87 KB
/
HeartRateMonitor.ino
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/***********************************
* AntPlus HRMonitor example
*
* Implements a HR Monitor sensor with
* mocked data to it and then reports
* all events through the serial port
*
* This is a minimum viable example
* all additional datapages are optional
* and are enabled through flags passed
* into the profile
*
* It is highly recommended you read the documenation at
* https://github.com/cujomalainey/antplus-arduino/wiki/HeartRate-Monitor-Profile
*
* Author Curtis Malainey
************************************/
#include <Arduino.h>
#include "ANT.h"
#include "ANTPLUS.h"
#define BAUD_RATE 9600
#define CHANNEL_0 0
const uint8_t NETWORK_KEY[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; // get this from thisisant.com
uint32_t flags = 0;
ArduinoSerialAntWithCallbacks ant;
AntPlusRouter router;
ProfileHeartRateMonitor hr(123, 0, flags);
// void batteryStatusDataPageHandler(HeartRateBatteryStatusMsg& msg, uintptr_t data);
// void capabilitiesDataPageHandler(HeartRateCapabilitiesMsg& msg, uintptr_t data);
// void cumulativeOperatingTimeDataPageHandler(HeartRateCumulativeOperatingTimeMsg& msg, uintptr_t data);
void defaultDataPageHandler(HeartRateDefaultMsg& msg, uintptr_t data);
void manufacturerInformationDataPageHandler(HeartRateManufacturerInformationMsg& msg, uintptr_t data);
// void previousHeartBeatDataPageHandler(HeartRatePreviousHeartBeatMsg& msg, uintptr_t data);
void productInformationDataPageHandler(HeartRateProductInformationMsg& msg, uintptr_t data);
// void swimIntervalSummary(HeartRateSwimIntervalSummaryMsg& msg, uintptr_t data);
void populateBaseHeartRate(HeartRateBaseMainDataPageMsg& msg);
void setup() {
Serial1.begin(BAUD_RATE);
ant.setSerial(Serial1);
delay(15000);
Serial.begin(BAUD_RATE);
Serial.println("Running");
router.setDriver(&ant); // never touch ant again
router.setAntPlusNetworkKey(NETWORK_KEY);
router.setProfile(CHANNEL_0, &hr);
// Delay after initial setup to wait for user to connect on serial
// hr.createHeartRateBatteryStatusMsg(batteryStatusDataPageHandler);
// hr.createHeartRateCapabilitiesMsg(capabilitiesDataPageHandler);
// hr.createHeartRateCumulativeOperatingTimeMsg(cumulativeOperatingTimeDataPageHandler);
hr.createHeartRateDefaultMsg(defaultDataPageHandler);
hr.createHeartRateManufacturerInformationMsg(manufacturerInformationDataPageHandler);
// hr.createHeartRatePreviousHeartBeatMsg(previousHeartBeatDataPageHandler);
hr.createHeartRateProductInformationMsg(productInformationDataPageHandler);
// hr.createHeartRateSwimIntervalSummaryMsg(swimIntervalSummary);
Serial.println("===========================");
hr.begin();
}
void loop() {
// Call this very frequently
router.loop();
}
void printDpMsg(int dp, const char* s) {
Serial.print("Sending DataPage: ");
Serial.print(dp);
Serial.print(" - ");
Serial.println(s);
}
/* Optional */
// void batteryStatusDataPageHandler(HeartRateBatteryStatusMsg& msg, uintptr_t data) {
// printDpMsg(7, "Battery Status");
// populateBaseHeartRate(msg);
// }
/* Optional */
// void capabilitiesDataPageHandler(HeartRateCapabilitiesMsg& msg, uintptr_t data) {
// printDpMsg(6, "Capabilities");
// populateBaseHeartRate(msg);
// }
/* Optional */
// void cumulativeOperatingTimeDataPageHandler(HeartRateCumulativeOperatingTimeMsg& msg, uintptr_t data) {
// printDpMsg(1, "Cumulative Operating Time");
// populateBaseHeartRate(msg);
// }
void defaultDataPageHandler(HeartRateDefaultMsg& msg, uintptr_t data) {
// All fields are reserved
printDpMsg(0, "Default");
populateBaseHeartRate(msg);
}
void manufacturerInformationDataPageHandler(HeartRateManufacturerInformationMsg& msg, uintptr_t data) {
printDpMsg(2, "Manufacturer Information");
populateBaseHeartRate(msg);
msg.setManufacturerIdLsb(78);
msg.setSerialNumber(0xabcd);
}
/* Optional */
// void previousHeartBeatDataPageHandler(HeartRatePreviousHeartBeatMsg& msg, uintptr_t data) {
// printDpMsg(4, "Previous Heart Beat");
// populateBaseHeartRate(msg);
// }
void productInformationDataPageHandler(HeartRateProductInformationMsg& msg, uintptr_t data) {
printDpMsg(3, "Product Information");
populateBaseHeartRate(msg);
msg.setHardwareVersion(1);
msg.setSoftwareVersion(2);
msg.setModelNumber(3);
}
/* Optional */
// void swimIntervalSummary(HeartRateSwimIntervalSummaryMsg& msg, uintptr_t data) {
// printDpMsg(5, "Swim Interval");
// populateBaseHeartRate(msg);
// }
void populateBaseHeartRate(HeartRateBaseMainDataPageMsg& msg) {
static uint8_t toggle = 0;
static uint8_t hr = 0;
static uint16_t eventTime = 0;
static uint8_t count = 0;
msg.setPageChangeToggle(toggle++ < 4);
msg.setComputedHeartRate(20*sin(hr++) + 120);
msg.setHeartBeatEventTime(eventTime);
msg.setHeartBeatCount(count++);
if (toggle >= 8) {
toggle = 0;
}
eventTime += 120;
}