Skip to content

Commit 77cb54d

Browse files
committed
Merge branch 'profiles/heart-rate/monitor' into develop
2 parents 369cc33 + 66ad9de commit 77cb54d

20 files changed

+574
-66
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ cache:
3434
- "~/.platformio"
3535

3636
env:
37+
- PLATFORMIO_CI_SRC=examples/BicycleSpeedDisplay/BicycleSpeedDisplay.ino
3738
- PLATFORMIO_CI_SRC=examples/EnvironmentDisplay/EnvironmentDisplay.ino
3839
- PLATFORMIO_CI_SRC=examples/HeartRateDisplay/HeartRateDisplay.ino
39-
- PLATFORMIO_CI_SRC=examples/BicycleSpeedDisplay/BicycleSpeedDisplay.ino
40+
- PLATFORMIO_CI_SRC=examples/HeartRateMonitor/HeartRateMonitor.ino
4041
- PLATFORMIO_CI_SRC=examples/LEVDisplay/LEVDisplay.ino
4142

4243
install:
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/***********************************
2+
* AntPlus HRMonitor example
3+
*
4+
* Implements a HR Monitor sensor with
5+
* mocked data to it and then reports
6+
* all events through the serial port
7+
*
8+
* Author Curtis Malainey
9+
************************************/
10+
#include <Arduino.h>
11+
#include "ANT.h"
12+
#include "ANTPLUS.h"
13+
14+
#define BAUD_RATE 9600
15+
#define CHANNEL_0 0
16+
17+
const uint8_t NETWORK_KEY[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; // get this from thisisant.com
18+
19+
AntWithCallbacks ant;
20+
AntPlusRouter router;
21+
ProfileHeartRateMonitor hr(123, 0);
22+
23+
void batteryStatusDataPageHandler(HeartRateBatteryStatusMsg& msg, uintptr_t data);
24+
void capabilitiesDataPageHandler(HeartRateCapabilitiesMsg& msg, uintptr_t data);
25+
void cumulativeOperatingTimeDataPageHandler(HeartRateCumulativeOperatingTimeMsg& msg, uintptr_t data);
26+
void defaultDataPageHandler(HeartRateDefaultMsg& msg, uintptr_t data);
27+
void manufacturerInformationDataPageHandler(HeartRateManufacturerInformationMsg& msg, uintptr_t data);
28+
void previousHeartBeatDataPageHandler(HeartRatePreviousHeartBeatMsg& msg, uintptr_t data);
29+
void productInformationDataPageHandler(HeartRateProductInformationMsg& msg, uintptr_t data);
30+
void swimIntervalSummary(HeartRateSwimIntervalSummaryMsg& msg, uintptr_t data);
31+
32+
void heartRateFeatures(uint8_t bitfield);
33+
void printStatus(uint8_t status);
34+
35+
void setup() {
36+
Serial1.begin(BAUD_RATE);
37+
ant.setSerial(Serial1);
38+
delay(15000);
39+
40+
router.setDriver(&ant); // never touch ant again
41+
router.setAntPlusNetworkKey(NETWORK_KEY);
42+
router.setProfile(CHANNEL_0, &hr);
43+
// Delay after initial setup to wait for user to connect on serial
44+
45+
Serial.begin(BAUD_RATE);
46+
Serial.println("Running");
47+
hr.createHeartRateBatteryStatusMsg(batteryStatusDataPageHandler);
48+
hr.createHeartRateCapabilitiesMsg(capabilitiesDataPageHandler);
49+
hr.createHeartRateCumulativeOperatingTimeMsg(cumulativeOperatingTimeDataPageHandler);
50+
hr.createHeartRateDefaultMsg(defaultDataPageHandler);
51+
hr.createHeartRateManufacturerInformationMsg(manufacturerInformationDataPageHandler);
52+
hr.createHeartRatePreviousHeartBeatMsg(previousHeartBeatDataPageHandler);
53+
hr.createHeartRateProductInformationMsg(productInformationDataPageHandler);
54+
hr.createHeartRateSwimIntervalSummaryMsg(swimIntervalSummary);
55+
hr.begin();
56+
// print channel status
57+
Serial.println("===========================");
58+
/* printStatus(status); */
59+
}
60+
61+
void loop() {
62+
// Call this very frequently
63+
router.loop();
64+
}
65+
66+
void printDpMsg(int dp, const char* s) {
67+
Serial.print("Sending DataPage: ");
68+
Serial.print(dp);
69+
Serial.print(" - ");
70+
Serial.println(s);
71+
}
72+
73+
void batteryStatusDataPageHandler(HeartRateBatteryStatusMsg& msg, uintptr_t data) {
74+
printDpMsg(7, "Battery Status");
75+
}
76+
77+
void capabilitiesDataPageHandler(HeartRateCapabilitiesMsg& msg, uintptr_t data) {
78+
printDpMsg(6, "Capabilities");
79+
}
80+
81+
void cumulativeOperatingTimeDataPageHandler(HeartRateCumulativeOperatingTimeMsg& msg, uintptr_t data) {
82+
printDpMsg(1, "Cumulative Operating Time");
83+
}
84+
85+
void defaultDataPageHandler(HeartRateDefaultMsg& msg, uintptr_t data) {
86+
// All fields are reserved
87+
printDpMsg(0, "Default");
88+
}
89+
90+
void manufacturerInformationDataPageHandler(HeartRateManufacturerInformationMsg& msg, uintptr_t data) {
91+
printDpMsg(2, "Manufacturer Information");
92+
}
93+
94+
void previousHeartBeatDataPageHandler(HeartRatePreviousHeartBeatMsg& dp, uintptr_t data) {
95+
printDpMsg(4, "Previous Heart Beat");
96+
}
97+
98+
void productInformationDataPageHandler(HeartRateProductInformationMsg& msg, uintptr_t data) {
99+
printDpMsg(3, "Product Information");
100+
}
101+
102+
void swimIntervalSummary(HeartRateSwimIntervalSummaryMsg& msg, uintptr_t data) {
103+
printDpMsg(5, "Swim Interval");
104+
}
105+
106+
void printStatus(uint8_t status) {
107+
Serial.print("Channel Status: ");
108+
switch (status) {
109+
case CHANNEL_STATUS_UNASSIGNED:
110+
Serial.println("Unassigned");
111+
break;
112+
case CHANNEL_STATUS_ASSIGNED:
113+
Serial.println("Assigned");
114+
break;
115+
case CHANNEL_STATUS_SEARCHING:
116+
Serial.println("Searching");
117+
break;
118+
case CHANNEL_STATUS_TRACKING:
119+
Serial.println("Tracking");
120+
break;
121+
}
122+
}
Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,50 @@
11
#include <BaseClasses/ANTPLUS_BaseMasterProfile.h>
2+
#include <BaseClasses/ANTPLUS_BaseDataPage.h>
3+
#include <CommonDataPages/ANTPLUS_CommonDataPagePrivateDefines.h>
4+
#include <CommonDataPages/RX/ANTPLUS_RequestDataPage.h>
25

36
BaseMasterProfile::BaseMasterProfile(uint16_t deviceNumber, uint8_t transmissionType) : BaseProfile(deviceNumber, transmissionType) {
4-
57
}
68

79
void BaseMasterProfile::onChannelEventResponse(ChannelEventResponse& msg) {
10+
BaseProfile::onChannelEventResponse(msg);
811
if (msg.getCode() == STATUS_EVENT_TX) {
912
transmitNextDataPage();
1013
}
11-
BaseProfile::onChannelEventResponse(msg);
12-
}
14+
if (msg.getCode() == STATUS_EVENT_TRANSFER_TX_COMPLETED) {
15+
_requestAcked = true;
16+
}
17+
}
18+
19+
void BaseMasterProfile::onAcknowledgedData(AcknowledgedData& msg) {
20+
BaseProfile::onAcknowledgedData(msg);
21+
BaseDataPage<AcknowledgedData> dp(msg);
22+
if (dp.getDataPageNumber() == ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_NUMBER) {
23+
handleRequestDataPage(msg);
24+
}
25+
}
26+
27+
void BaseMasterProfile::handleRequestDataPage(AcknowledgedData& msg) {
28+
RequestDataPage dp(msg);
29+
if (!isDataPageValid(dp.getRequestedPageNumber())) {
30+
// Datapage requested isn't supported, don't do anything
31+
return;
32+
}
33+
_requestedCount = dp.getRequestedPageCount();
34+
_requestedPage = dp.getRequestedPageNumber();
35+
_isRequestAcknowledged = dp.getUseAcknowledgedMsgs();
36+
_requestAcked = !dp.transmitTillAcknowledged();
37+
}
38+
39+
bool BaseMasterProfile::isRequestedPagePending() {
40+
return _requestedCount > 0 || !_requestAcked;
41+
}
42+
43+
uint8_t BaseMasterProfile::getRequestedPage() {
44+
_requestedCount--;
45+
return _requestedPage;
46+
}
47+
48+
bool BaseMasterProfile::isRequestedPageAcknowledged() {
49+
return _isRequestAcknowledged;
50+
}

src/BaseClasses/ANTPLUS_BaseMasterProfile.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,39 @@ class BaseMasterProfile : public BaseProfile {
99
protected:
1010
/**
1111
* Used to catch EVENT_TX and continue transmission pattern
12+
* Also handles EVENT_TRANSFER_TX_COMPLETED for acknowledgement
1213
*/
1314
virtual void onChannelEventResponse(ChannelEventResponse& msg);
1415
/**
1516
* This function, when called, will transmit the next message in the broadcast pattern
1617
*/
1718
virtual void transmitNextDataPage() = 0;
19+
/**
20+
* Checks for RequestDataPage messages and handles them accordingly
21+
*/
22+
virtual void onAcknowledgedData(AcknowledgedData& msg);
23+
/**
24+
* Checks with subclass to see if request is valid
25+
*/
26+
virtual bool isDataPageValid(uint8_t dataPage) = 0;
27+
/**
28+
* returns true if pattern is currently interrupted by a request
29+
*/
30+
bool isRequestedPagePending();
31+
/**
32+
* Returns the page number of the pending datapage
33+
*/
34+
uint8_t getRequestedPage();
35+
/**
36+
* returns true if the request is meant to be sent as a acknowledged message
37+
*/
38+
bool isRequestedPageAcknowledged();
39+
private:
40+
void handleRequestDataPage(AcknowledgedData& msg);
41+
uint8_t _requestedPage;
42+
uint8_t _requestedCount = 0;
43+
bool _isRequestAcknowledged;
44+
bool _requestAcked = true;
1845
};
1946

2047
#endif // ANTPLUS_BASESLAVEPROFILE_h

src/BaseClasses/ANTPLUS_BaseProfile.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ void BaseProfile::setChannelPeriod(uint16_t channelPeriod) {
4747
}
4848

4949
void BaseProfile::pushChannelConfig() {
50-
AssignChannel ac = AssignChannel(_channel, _channelType, ANTPLUS_NETWORKKEY_INDEX);
51-
ChannelId ci = ChannelId(_channel, _deviceNumber, _deviceType, ANTPLUS_PAIRING_BIT_MASK & _deviceType, _transmissionType);
52-
ChannelPeriod cp = ChannelPeriod(_channel, _channelPeriod);
53-
ChannelRfFrequency crf = ChannelRfFrequency(_channel, ANTPLUS_CHANNEL_FREQUENCY);
54-
SearchTimeout st = SearchTimeout(_channel, _searchTimeout);
50+
AssignChannel ac(_channel, _channelType, ANTPLUS_NETWORKKEY_INDEX);
51+
ChannelId ci(_channel, _deviceNumber, _deviceType, ANTPLUS_PAIRING_BIT_MASK & _deviceType, _transmissionType);
52+
ChannelPeriod cp(_channel, _channelPeriod);
53+
ChannelRfFrequency crf(_channel, ANTPLUS_CHANNEL_FREQUENCY);
54+
SearchTimeout st(_channel, _searchTimeout);
5555

5656
_router->send(ac);
5757
_router->send(ci);
@@ -61,20 +61,21 @@ void BaseProfile::pushChannelConfig() {
6161
}
6262

6363
void BaseProfile::openChannel() {
64-
OpenChannel oc = OpenChannel(_channel);
64+
OpenChannel oc(_channel);
6565
_channelStatus = CHANNEL_STATUS_SEARCHING;
6666
_router->send(oc);
6767
}
6868

6969
void BaseProfile::closeChannel() {
70-
CloseChannel cc = CloseChannel(_channel);
70+
CloseChannel cc(_channel);
7171
_channelStatus = CHANNEL_STATUS_ASSIGNED;
7272
_router->send(cc);
7373
}
7474

7575
void BaseProfile::onChannelEventResponse(ChannelEventResponse& msg) {
7676
uint8_t event = msg.getCode();
7777

78+
// TODO this looks weird to me
7879
switch (event) {
7980
case STATUS_EVENT_CHANNEL_CLOSED:
8081
case STATUS_EVENT_RX_FAIL_GO_TO_SEARCH:
@@ -117,15 +118,25 @@ void BaseProfile::onChannelStatus(ChannelStatus& msg) {
117118

118119
void BaseProfile::checkProfileStatus() {
119120
if (!getDeviceNumber() || !getTransmissionType()) {
120-
RequestMessage rm = RequestMessage(CHANNEL_ID, _channel);
121+
RequestMessage rm(CHANNEL_ID, _channel);
121122
send(rm);
122123
}
123124
if (_channelStatus == CHANNEL_STATUS_SEARCHING) {
124-
RequestMessage rm = RequestMessage(CHANNEL_STATUS, _channel);
125+
RequestMessage rm(CHANNEL_STATUS, _channel);
125126
send(rm);
126127
}
127128
}
128129

130+
void BaseProfile::send(AcknowledgedDataMsg& msg) {
131+
msg.setChannelNumber(_channel);
132+
_router->send(msg);
133+
}
134+
135+
void BaseProfile::send(BroadcastDataMsg& msg) {
136+
msg.setChannel(_channel);
137+
_router->send(msg);
138+
}
139+
129140
void BaseProfile::send(AntRequest& msg) {
130141
_router->send(msg);
131142
}

src/BaseClasses/ANTPLUS_BaseProfile.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,18 @@ class BaseProfile {
6060
* Close radio channel and stop transmitting
6161
*/
6262
virtual void stop();
63+
/**
64+
* Sends a message and sets the associated channel in the message
65+
*/
66+
void send(AcknowledgedDataMsg& msg);
67+
/**
68+
* Sends a message and sets the associated channel in the message
69+
*/
70+
void send(BroadcastDataMsg& msg);
6371
/**
6472
* Sends a message through the connected router
6573
*/
6674
void send(AntRequest& msg);
67-
6875
protected:
6976
void callOnOtherDataPage(AntRxDataResponse& msg);
7077
void setChannelType(uint8_t channelType);

src/CommonDataPages/ANTPLUS_CommonDataPagePrivateDefines.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
#define ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_BYTE 5
1616
#define ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_COUNT_MASK 0x7FF
1717
#define ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_USEACKNOWLEDGED_MASK 0x80
18+
#define ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_TRANSMISSIONCOUNT_MASK 0x7F
19+
#define ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_TRANSMITTILLACKNOWLEDGED_VALUE 0x80
20+
#define ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_USEACKNOWLEDGED_SHIFT 7
1821

1922
#define ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDPAGENUMBER_BYTE 6
2023

src/CommonDataPages/RX/ANTPLUS_RequestDataPage.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,16 @@ uint8_t RequestDataPage::getDescriptorByte2() {
1717
return getData(ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_DESCRIPTORBYTE2_BYTE);
1818
}
1919

20-
uint8_t RequestDataPage::getRequestedTransmissionResponse() {
21-
return getData(ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_BYTE);
20+
uint8_t RequestDataPage::getRequestedPageCount() {
21+
return getData(ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_BYTE) & ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_TRANSMISSIONCOUNT_MASK;
22+
}
23+
24+
uint8_t RequestDataPage::getUseAcknowledgedMsgs() {
25+
return getData(ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_BYTE) >> ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_USEACKNOWLEDGED_SHIFT;
26+
}
27+
28+
uint8_t RequestDataPage::transmitTillAcknowledged() {
29+
return getData(ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_BYTE) == ANTPLUS_COMMON_DATAPAGE_REQUESTDATAPAGE_REQUESTEDTRANSMISSIONRESPONSE_TRANSMITTILLACKNOWLEDGED_VALUE;
2230
}
2331

2432
uint8_t RequestDataPage::getRequestedPageNumber() {

src/CommonDataPages/RX/ANTPLUS_RequestDataPage.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ class RequestDataPage : public BaseDataPage<AcknowledgedData> {
1313
uint16_t getSlaveSerialNumber();
1414
uint8_t getDescriptorByte1();
1515
uint8_t getDescriptorByte2();
16-
uint8_t getRequestedTransmissionResponse();
16+
uint8_t getRequestedPageCount();
17+
uint8_t getUseAcknowledgedMsgs();
18+
uint8_t transmitTillAcknowledged();
1719
uint8_t getRequestedPageNumber();
1820
uint8_t getCommandType();
1921
};
2022

21-
#endif // ANTPLUS_REQUESTDATAPAGE_h
23+
#endif // ANTPLUS_REQUESTDATAPAGE_h

0 commit comments

Comments
 (0)