Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d44c8e2
Merge branch 'develop'
cujomalainey Feb 5, 2018
98d5cff
Rev minor version
cujomalainey Feb 5, 2018
9b000e8
Typo
cujomalainey Apr 4, 2018
68e0b7b
Typo
cujomalainey Apr 4, 2018
b051972
LEV profile for display and example added
Sepp62 Jun 7, 2019
d38ecb3
Refactoring Part 1
Sepp62 Jun 11, 2019
81c9431
Convert all tabs to spaces
cujomalainey Jun 12, 2019
f841494
BaseMaster: Handle request datapages in the base profile
cujomalainey Jun 12, 2019
91cb627
Travis: Missed a couple arguements in base master
cujomalainey Jun 12, 2019
50e7ce8
LEV: Display: Add example to Travis config
cujomalainey Jun 12, 2019
128d11c
Merge pull request #1 from cujomalainey/temp/remote/pr
Sepp62 Jun 12, 2019
d8b830c
rename LEV folder to Lev
Sepp62 Jun 12, 2019
6fd66e2
getError() --> getErrorMessage()
Sepp62 Jun 12, 2019
6395970
Unnecessary comment removed
Sepp62 Jun 12, 2019
b9582be
Some corrections, mainly TODOs added and some decoding bug fixes
Sepp62 Jun 12, 2019
b294cad
.gitignore rolled back
Sepp62 Jun 12, 2019
59a5074
Router: Reset radio before clearing reference
cujomalainey Jun 13, 2019
36e4357
Constant changed and commented code removed
Sepp62 Jun 13, 2019
8897dd8
First shot of muscle oxygen monitor profile, rudimentarily tested
Sepp62 Jun 13, 2019
b093d80
Refactoring consistent to "shifter"
Sepp62 Jun 15, 2019
fd43f0d
isDataPageValid() changed
Sepp62 Jun 15, 2019
6d3c6dd
Rev minor version
cujomalainey Feb 5, 2018
54a2ffa
Typo
cujomalainey Apr 4, 2018
7b78805
Typo
cujomalainey Apr 4, 2018
225398d
Created
Sepp62 Jun 16, 2019
355c3b0
Demo key for ANT network. Use your own from thisisant.com
Sepp62 Jun 16, 2019
26f5aae
Tabs replaced w/ spaces
Jun 16, 2019
f3d15fb
CommonDataPages: Add ProductInformationMsg
cujomalainey Jun 20, 2019
1cb487b
CommonDataPages: Add ManufacturersInfomation
cujomalainey Jun 20, 2019
d3c5962
Merge branch 'develop' into core/base-master
cujomalainey Jun 20, 2019
dfdd074
Merge branch 'master' into Development
Sepp62 Jun 21, 2019
6fca841
Merge branch 'core/base-master' into Development
Sepp62 Jun 21, 2019
919362b
Adapted to new msg balse classes for manufacturer and product
Sepp62 Jun 21, 2019
ad3ba44
Refactoring Moxy and Shifting for product and manufacturer information
Sepp62 Jun 21, 2019
6d091c5
Merge branch 'Development' into profiles/moxy/monitor
Sepp62 Jun 21, 2019
bc5f297
Refactoring manufacturer and product information
Sepp62 Jun 21, 2019
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ env:
- PLATFORMIO_CI_SRC=examples/EnvironmentDisplay/EnvironmentDisplay.ino
- PLATFORMIO_CI_SRC=examples/HeartRateDisplay/HeartRateDisplay.ino
- PLATFORMIO_CI_SRC=examples/HeartRateMonitor/HeartRateMonitor.ino

- PLATFORMIO_CI_SRC=examples/MuscleOxygenMonitor/MuscleOxygenMonitor.ino
install:
- pip install -U platformio

Expand Down
58 changes: 58 additions & 0 deletions examples/MuscleOxygenMonitor/MuscleOxygenMonitor.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**********************************************
* AntPlus muscle oxygen monitor example
*
* Deliver data of a muscle oxygen sensor
* to a display via serial port
*
* Author Bernd Wok�ck
* based on the work of Curtis Malainey
**********************************************/
#include <Arduino.h>
#include "ANT.h"
#include "ANTPLUS.h"

#define BAUD_RATE 9600
#define CHANNEL_1 0
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHANNEL_1 but defined as 0?


const uint8_t NETWORK_KEY[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };

AntWithCallbacks ant = AntWithCallbacks();
AntPlusRouter router = AntPlusRouter();
ProfileMuscleOxygenMonitor moxy = ProfileMuscleOxygenMonitor( 7369 );

void moxyCreateMsgHandler(MuscleOxygenBaseMainDataPageMsg& msg, uintptr_t data);

void setup() {
Serial2.begin(BAUD_RATE);
ant.setSerial(Serial2);
delay(1000);

router.setDriver(&ant); // never touch ant again
router.setAntPlusNetworkKey(NETWORK_KEY);
router.setProfile(CHANNEL_1, &moxy);
// Delay after initial setup to wait for user to connect on serial

Serial.begin(BAUD_RATE);
Serial.println("Running");

// setup muscle oxygen monitor
moxy.createMuscleOxygenDataMsg(moxyCreateMsgHandler);
moxy.begin();
}

void loop() {
router.loop();
}

void moxyCreateMsgHandler(MuscleOxygenBaseMainDataPageMsg& msg, uintptr_t data)
{
const int lo = 500, hi = 2500;
static uint16_t c = lo;

// fake data
msg.setTotalHemoglobinConcentration(c);
msg.setCurrentSaturatedHemoglobinPercentage(c++/4);

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO to add "previous sat hemoglobin"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is a mystery to me and my moxy display. Somebody else should integrate it.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

if (c > hi)
c = lo;
}
1 change: 1 addition & 0 deletions src/Profiles/ANTPLUS_Profiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
#include <Profiles/BicycleSpeed/ANTPLUS_BicycleSpeedProfile.h>
#include <Profiles/HeartRate/ANTPLUS_HeartRateProfile.h>
#include <Profiles/Environment/ANTPLUS_EnvironmentProfile.h>
#include <Profiles/MuscleOxygen/ANTPLUS_MuscleOxygenProfile.h>

#endif // ANTPLUS_ANTROUTER_h
23 changes: 23 additions & 0 deletions src/Profiles/MuscleOxygen/ANTPLUS_MuscleOxygenPrivateDefines.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef ANTPLUS_MUSCLEOXYGENPROFILEPRIVATEDEFINES_h
#define ANTPLUS_MUSCLEOXYGENPROFILEPRIVATEDEFINES_h

/* Channel Config */
#define ANTPLUS_MUSCLEOXYGEN_CHANNELTYPE CHANNEL_TYPE_BIDIRECTIONAL_RECEIVE
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ANTPLUS_MUSCLEOXYGEN_DISPLAY_CHANNELTYPE

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

#define ANTPLUS_MUSCLEOXYGEN_DEVICETYPE 31
#define ANTPLUS_MUSCLEOXYGEN_CHANNELPERIOD 8192
// Master channel
#define ANTPLUS_MUSCLEOXYGEN_MASTER_CHANNELTYPE 0x10
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#define ANTPLUS_MUSCLEOXYGEN_MONITOR_CHANNELTYPE CHANNEL_TYPE_BIDIRECTIONAL_TRANSMIT

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

#define ANTPLUS_MUSCLEOXYGEN_MASTER_TRANSMISSIONTYPE 5
#define ANTPLUS_MUSCLEOXYGEN_MASTER_DEVICENUMBER 5
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for?


// 30 / 2.5 = 12
#define ANTPLUS_MUSCLEOXYGEN_SEARCHTIMEOUT 12

/* Pages */
#define ANTPLUS_MUSCLEOXYGEN_DATAPAGE_MUSCLEOXYGENDATA 1
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add _NUMBER


// Base page */
#define ANTPLUS_MUSCLEOXYGEN_DATAPAGEBASE_DATAPAGE_BYTE 0x00


#endif // ANTPLUS_MUSCLEOXYGENPROFILEPRIVATEDEFINES_h
13 changes: 13 additions & 0 deletions src/Profiles/MuscleOxygen/ANTPLUS_MuscleOxygenProfile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef ANTPLUS_MUSCLEOXYGENPROFILE_h
#define ANTPLUS_MUSCLEOXYGENPROFILE_h

// General Definitions
#include <Profiles/MuscleOxygen/Monitor/ANTPLUS_ProfileMuscleOxygenMonitor.h>

// Datapages
#include <Profiles/MuscleOxygen/DataPages/ANTPLUS_ProfileMuscleOxygenDataPages.h>

// Profile Classes
// ...

#endif // ANTPLUS_MUSCLEOXYGENPROFILE_h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef ANTPLUS_PROFILEMUSCLEOXYGENDATAPAGES_h
#define ANTPLUS_PROFILEMUSCLEOXYGENDATAPAGES_h

/* Base */
#include <Profiles/MuscleOxygen/DataPages/Base/ANTPLUS_MuscleOxygenBaseMainDataPageMsg.h>

/* RX */
// ...

/* TX */
// ...

#endif // ANTPLUS_PROFILEMUSCLEOXYGENDATAPAGES_h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <Profiles/MuscleOxygen/DataPages/Base/ANTPLUS_MuscleOxygenBaseMainDataPageMsg.h>
#include <Profiles/MuscleOxygen/ANTPLUS_MuscleOxygenPrivateDefines.h>
#include <ANTPLUS_PrivateDefines.h>


MuscleOxygenBaseGenericMsg::MuscleOxygenBaseGenericMsg() : BaseDataPageMsg<BroadcastDataMsg>()
{
memset(_buffer, 0, MESSAGE_SIZE);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious what the benefit of memsetting the values are :) All values in the datapage should be defined so we shouldnt be left with an 0s.

Copy link
Contributor

@Sepp62 Sepp62 Jun 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During development, you cannot be sure to have all the bytes in a defined state. Initializing with "0" makes it easier to see bugs in bit math. Generally spoken: Initializing member data has very low cost and pays off during develplement and maintenance life cycle. In our special case "moxy" setPreviousSaturatedHemoglobinPercentage is unused and therefore a default initialization is helpful.

Copy link
Owner Author

@cujomalainey cujomalainey Jun 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point, I think though I would just set it to 0 it out in the variable declaration.

*edit fair

setDataBuffer(_buffer);
}

MuscleOxygenBaseMainDataPageMsg::MuscleOxygenBaseMainDataPageMsg(uint8_t dataPageNumber) : MuscleOxygenBaseGenericMsg()
{
_buffer[ANTPLUS_DEFAULT_DATAPAGE_BYTE] = dataPageNumber;
setCapabilities();
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment on other review about automating API :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dataPageNumber parameter removed.

setNotifications();
}

void MuscleOxygenBaseMainDataPageMsg::setEventCount( uint8_t n )
{
_buffer[1] = n;
}

void MuscleOxygenBaseMainDataPageMsg::setNotifications( uint8_t n )
{
_buffer[2] = n;
}

void MuscleOxygenBaseMainDataPageMsg::setCapabilities( uint8_t c )
{
_buffer[3] = c;
}

void MuscleOxygenBaseMainDataPageMsg::setTotalHemoglobinConcentration( uint16_t tc )
{
_buffer[4] = (uint8_t)tc;
_buffer[5] &= ~0x0F;
_buffer[5] |= (tc >> 8) & 0x0F;
}

/* TODO
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, what is missing here that needs the TODO?

Copy link
Contributor

@Sepp62 Sepp62 Jun 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behaviour of "setPreviousSaturatedHemoglobinPercentage" cannot be verified with my moxy display device. So it is not clear for me, how to handle it from the application side. Of course, I read the antplus docs, but I do not have a clue about the use of it. Since I cannot test it, I commented it out to give somebody else a chance to use it.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the device just bumps the reading down. So on every event it moves the current value into previous and puts a new current. Docs site this reasoning for in the event of a data loss. It would be awesome if the class could handle this itself but since the class is never preserver I don't think there is a way around it other than showing the user through the example to do it themselves.

void MuscleOxygenBaseMainDataPageMsg::setPreviousSaturatedHemoglobinPercentage( uint16_t pp )
{
_buffer[5] &= ~0xF0;
_buffer[5] |= (uint8_t)(pp << 4);
_buffer[6] &= ~0x3F;
_buffer[6] |= (pp >> 4) & 0x3F;
}
*/

void MuscleOxygenBaseMainDataPageMsg::setCurrentSaturatedHemoglobinPercentage( uint16_t cp )
{
_buffer[6] &= ~0xC0;
_buffer[6] |= (uint8_t)(cp << 6);
_buffer[7] = cp >> 2;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef ANTPLUS_MUSCLEOXYGENBASEMAINDATAPAGEMSG_h
#define ANTPLUS_MUSCLEOXYGENBASEMAINDATAPAGEMSG_h

#include <BaseClasses/ANTPLUS_BaseDataPageMsg.h>
#include <Profiles/MuscleOxygen/ANTPLUS_MuscleOxygenPrivateDefines.h>

#include "ANT.h"

class MuscleOxygenBaseGenericMsg : public BaseDataPageMsg<BroadcastDataMsg> {
public:
MuscleOxygenBaseGenericMsg();

void copyData(uint8_t * buf, size_t len) { memcpy(_buffer, buf, len); }

protected:
uint8_t _buffer[MESSAGE_SIZE];
};

class MuscleOxygenBaseMainDataPageMsg : public MuscleOxygenBaseGenericMsg {
public:
MuscleOxygenBaseMainDataPageMsg(uint8_t dataPageNumber = ANTPLUS_MUSCLEOXYGEN_DATAPAGE_MUSCLEOXYGENDATA);

void setTotalHemoglobinConcentration( uint16_t tc );
void setCurrentSaturatedHemoglobinPercentage(uint16_t cp);

// internal
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these internal? Don't we want users to set these values?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"internal" removed

void setEventCount(uint8_t n);
void setNotifications(uint8_t n = 0x00);
void setCapabilities(uint8_t c = 0x06);
};

#endif // ANTPLUS_MUSCLEOXYGENBASEMAINDATAPAGEMSG_h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <Profiles/MuscleOxygen/Monitor/ANTPLUS_ProfileMuscleOxygenMonitor.h>
#include <CommonDataPages/ANTPLUS_CommonDataPagePrivateDefines.h>


ProfileMuscleOxygenMonitor::ProfileMuscleOxygenMonitor( uint16_t deviceNumber, uint8_t transmissionType) :
BaseMasterProfile(deviceNumber, transmissionType),
_patternStep(0),
_toggle(0),
_eventCount(0)

{
setChannelConfig();
}

void ProfileMuscleOxygenMonitor::setChannelConfig() {
setChannelType(ANTPLUS_MUSCLEOXYGEN_MASTER_CHANNELTYPE);
setDeviceType(ANTPLUS_MUSCLEOXYGEN_DEVICETYPE);
setChannelPeriod(ANTPLUS_MUSCLEOXYGEN_CHANNELPERIOD);
setSearchTimeout(ANTPLUS_MUSCLEOXYGEN_SEARCHTIMEOUT);
}

void ProfileMuscleOxygenMonitor::transmitNextDataPage() {
// some static aux messages
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm out of town (and off grid) in the mountains, but next week I'll do my best to fill in these missing common datapages on core/base-master and merge it into the shifter and moxy branches for you.

const uint8_t manufacturer[] = { 0x50, 0xFF, 0xFF, 0x01, 0x0F, 0x00, 0x85, 0x83 };
const uint8_t product[] = { 0x51, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0x00, 0x00 };

if (_patternStep++ < 64) {
transmitMuscleOxygenMainPageMsg();
}
else {
MuscleOxygenBaseGenericMsg msg;
if (_toggle++ % 1 == 0)
msg.copyData((uint8_t*)manufacturer, MESSAGE_SIZE);
else
msg.copyData((uint8_t*)product, MESSAGE_SIZE);
send(msg);
_patternStep = 0;

// debug
/*
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug needs to be removed :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

for (int i = 0; i < msg.getDataLength(); i++) {
Serial.print(msg.getData(i), HEX); Serial.print(" ");
}
Serial.println("");*/
}
}

void ProfileMuscleOxygenMonitor::transmitMuscleOxygenMainPageMsg() {
MuscleOxygenBaseMainDataPageMsg msg;
msg.setEventCount( _eventCount );
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can control this, if I'm reading the datasheet right, it should only increment when the sensor gets a new value, which is outside the libraries' control and depends on the moxy hardware.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

if( _patternStep % 4 == 0 )
_eventCount++;
_createMuscleOxygenDataMsg.call(msg);
send(msg);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef ANTPLUS_PROFILEMUSCLEOXYGENMONITOR_h
#define ANTPLUS_PROFILEMUSCLEOXYGENMONITOR_h

#include <BaseClasses/ANTPLUS_BaseMasterProfile.h>
#include <Profiles/MuscleOxygen/DataPages/ANTPLUS_ProfileMuscleOxygenDataPages.h>
#include <Profiles/MuscleOxygen/ANTPLUS_MuscleOxygenPrivateDefines.h>
#include <CommonDataPages/ANTPLUS_CommonDataPages.h>

class ProfileMuscleOxygenMonitor : public BaseMasterProfile {
public:
ProfileMuscleOxygenMonitor(uint16_t deviceNumber, uint8_t transmissionType = ANTPLUS_MUSCLEOXYGEN_MASTER_TRANSMISSIONTYPE);

/**
* Register callback to populate default data messages (Datapage 0)
*/
void createMuscleOxygenDataMsg(void(*func)(MuscleOxygenBaseMainDataPageMsg&, uintptr_t), uintptr_t data = 0) { _createMuscleOxygenDataMsg.set(func, data); }

protected:
virtual void transmitNextDataPage();
virtual bool isDataPageValid(uint8_t dataPage) { return true; }

private:
void setChannelConfig();
void transmitMuscleOxygenMainPageMsg();

uint8_t _patternStep;
uint8_t _toggle;
uint8_t _eventCount;

Callback<MuscleOxygenBaseMainDataPageMsg&> _createMuscleOxygenDataMsg;
};

#endif // ANTPLUS_PROFILEMUSCLEOXYGENMONITOR_h