nRF24AP1 - ANT Code - Garmin Heart-Rate Monitor

Heya,

I’ve put this code up in a few other places, but posting here so that if I make any changes you can come here to see my progress.

I had some trouble getting some of the other example code for the nRF24AP1 working so I decided to work through it myself. I do not have it completely working yet but I do have the chip communicating and everything with my program so, its a good start!

Github: https://github.com/smysnk/garmin-heart-rate-monitor

Update: The code should now work! People using the sparkfun FOB will need to adjust global.h with the proper baud rate of 4800

Here is the output of my program:

root@syndsys-vmware:/home/sammy/ANT# ./ant /dev/ttyUSB0

TX: Success
txda: a4 01 4a 00 ef
TX: Success
txda: a4 02 4d 00 54 bf
TX: Success
RX: [sync]..[0x04]..[0x54]..[0x04]..[0x03]..[0x00]..[0x03]..[0xf0]
RX: msg received [7]
ID: MESG_CAPABILITIES_ID

[DEBUG] Device Capabilites
--------------------------
Max Ch                   4
Max Networks             3
Standard Opts         0x00
Advanced Opts1        0x03 [NETWORK_EN]
Advanced Opts2        0x00
Max Data Ch              0


txda: a4 02 4d 00 3d d6
TX: Success
RX: [sync]..[0x03]..[0x40]..[0x00]..[0x4d]..[0x28]..[0x82]
RX: msg received [6]
ID: MESG_RESPONSE_EVENT_ID
Response Handler (size=3)
Channel Num  0x00
Message ID   0x4d [unknown]
Message Code 0x28

txda: a4 03 42 00 00 01 e4
TX: Success
RX: [sync]..[0x03]..[0x40]..[0x00]..[0x42]..[0x00]..[0xa5]
RX: msg received [6]
ID: MESG_RESPONSE_EVENT_ID
Response Handler (size=3)
Channel Num  0x00
Message ID   0x42 [MESG_ASSIGN_CHANNEL_ID]
Message Code 0x00

new txda: a4 05 51 00 00 00 00 00 f0
old txda: a4 04 51 00 00 00 00 f1  --- Here was my problem!
TX: Success
RX: [sync]..[0x03]..[0x40]..[0x00]..[0x51]..[0x00]..[0xb6]
RX: msg received [6]
ID: MESG_RESPONSE_EVENT_ID
Response Handler (size=3)
Channel Num  0x00
Message ID   0x51 [MESG_CHANNEL_ID_ID]
Message Code 0x00

txda: a4 09 46 01 b9 a5 21 fb bd 72 c3 45 65
TX: Success
RX: [sync]..[0x03]..[0x40]..[0x01]..[0x46]..[0x00]..[0xa0]
RX: msg received [6]
ID: MESG_RESPONSE_EVENT_ID
Response Handler (size=3)
Channel Num  0x01
Message ID   0x46 [MESG_NETWORK_KEY_ID]
Message Code 0x00

txda: a4 02 44 00 0a e8
TX: Success
RX: [sync]..[0x03]..[0x40]..[0x00]..[0x44]..[0x00]..[0xa3]
RX: msg received [6]
ID: MESG_RESPONSE_EVENT_ID
Response Handler (size=3)
Channel Num  0x00
Message ID   0x44 [MESG_CHANNEL_SEARCH_TIMEOUT_ID]
Message Code 0x00

txda: a4 02 45 00 39 da
TX: Success
RX: [sync]..[0x03]..[0x40]..[0x00]..[0x45]..[0x00]..[0xa2]
RX: msg received [6]
ID: MESG_RESPONSE_EVENT_ID
Response Handler (size=3)
Channel Num  0x00
Message ID   0x45 [MESG_CHANNEL_RADIO_FREQ_ID]
Message Code 0x00

txda: a4 03 43 00 1f 86 7d
TX: Success
RX: [sync]..[0x03]..[0x40]..[0x00]..[0x43]..[0x00]..[0xa4]
RX: msg received [6]
ID: MESG_RESPONSE_EVENT_ID
Response Handler (size=3)
Channel Num  0x00
Message ID   0x43 [MESG_CHANNEL_MESG_PERIOD_ID]
Message Code 0x00

txda: a4 01 4b 00 ee
TX: Success
RX: [sync]..[0x03]..[0x40]..[0x00]..[0x4b]..[0x00]..[0xac]
RX: msg received [6]
ID: MESG_RESPONSE_EVENT_ID
Response Handler (size=3)
Channel Num  0x00
Message ID   0x4b [MESG_OPEN_CHANNEL_ID]
Message Code 0x00

RX: [sync]..[0x03]..[0x40]..[0x00]..[0x01]..[0x01]..[0xe7]
RX: msg received [6]
ID: MESG_RESPONSE_EVENT_ID
Response Handler (size=3)
Channel Num  0x00
Message ID   0x01 [unknown]
Message Code 0x01

I don’t know anything about Garmin HRM’s so this may be nonsense.

There’s a lot comes down to the ‘device profile’ of the sensor (in your case the HRM) and different equimpment manufactures have different profiles. As far as I can work out, the profile is a combination of the settings defined in section 5.2 in this document http://www.thisisant.com/images/Resourc … 0usage.pdf

I wanted to interface with Suunto, but they’ve opted to use a private network key rather than using the public network (ID=0) so without their co-operation, I’m stuck. To work out more than this, I think joining the ANT+ alliance will be required to get access to their reference designs and dev tools and I’m not sure I want to spend $500 just for a whim.

I’m my case I’m trying to fight my way past the Suunto helpdesk to talk to someone who knows what they’re doing but they are fending me off to date.

Garmin may be different, but you may also be doing everything right and just have the wrong key (or some other setting). If you’ve any information on the Garmin stuff post a link or chat me, I might opt to use that if this hurdle can be cleared.

Simon

WOOT! I managed to get it working. It was a small typo when I was setting the channel ID.

@dev Thanks for that PDF, it helped me out a bit!

Also getting it to work with Suunto should be no problem. Here are the differences between garmin and suunto

int gfreq = 0x39; //  garmin radio frequency
int gperiod = 0x1f86; // garmin search period

int sfreq = 0x41; //  suunto radio frequency
int speriod = 0x199a; // suunto search period

static uchar GARMIN_KEY[] = "B9A521FBBD72C345"; // Garmin
static uchar SUUNTO_KEY[] = "B9AD3228757EC74D"; // Suunto

Here is the raw output from the HRM:

RX: [sync]..[0x09]..[0x4e]..[0x00]..[0x58]..[0x60]..[0x36]..[0x18]..[0x4f]..[0x00]..[0x80]..[0x4d]..[0x77]
RX: msg received [12]
ID: Unknown [0x4e]

RX: [sync]..[0x09]..[0x4e]..[0x00]..[0x58]..[0x60]..[0x36]..[0x18]..[0x39]..[0x01]..[0x81]..[0x4d]..[0x01]
RX: msg received [12]
ID: Unknown [0x4e]

RX: [sync]..[0x09]..[0x4e]..[0x00]..[0x58]..[0x60]..[0x36]..[0x18]..[0x40]..[0x02]..[0x82]..[0x4d]..[0x78]
RX: msg received [12]
ID: Unknown [0x4e]

RX: [sync]..[0x09]..[0x4e]..[0x00]..[0x58]..[0x60]..[0x36]..[0x18]..[0x40]..[0x02]..[0x82]..[0x4d]..[0x78]
RX: msg received [12]
ID: Unknown [0x4e]

RX: [sync]..[0x09]..[0x4e]..[0x00]..[0x58]..[0x60]..[0x36]..[0x18]..[0x40]..[0x02]..[0x82]..[0x4d]..[0x78]
RX: msg received [12]
ID: Unknown [0x4e]

I’ve rezipped my code with the fix in it.

That’s awesome. I’ll give it a try later. Out of curiosity how did you obtain the different network settings?

The fellow that started this thread [here, has the keys in his source. I will have to inquire myself how he got them too, maybe through some leet reverse engineering!](http://developer.garmin.com/forum/viewtopic.php?t=410&postdays=0&postorder=asc&start=0&sid=80eebfe47ffbce2bfc6b62262d9d9a2c)

How I never found that thread is a total mystery to me. Very useful though.

Cheers

Made some updates to better support Suunto settings, all centralized in global.h

I’ve gotten “bored” and have since developed a uC based power meter based off several strain gauges. I thought it would be neat to interface this to my Garmin 705. Although I’m sure I could “fake” it to look like a HRM monitor and just use that as my power data, but it’d be much neater to send it as actual power data (since they support various power meters over ant+). Since I don’t have access to the developer area of the garmin doc for the SDK I wasn’t sure how the PM’s communicate with the unit. I assume the “device profile” is different from HRM’s anyone have any ideas or suggestions for this? It was somewhat related to this original post so I figured I’d ask here :slight_smile:

I suppose even if knew the device profile I’d have to find out the network keys that garmin uses for that particular accessory :x

Hi smysnk

Glad to hear you nearly got success. I downloaded the sources (ant.tar.bz2) and tried to compiler but still failed. Can you suggest me what compiler should I use?

Thanks!

This was developed under linux.

simpily typing “make” should be all you need to do to compile

After a day or two strugeling to get anything working a week back I soldered pin headers on the two breakout boards I had not tryed this afternoon and went back to my breadboard setup. I had never suceeded in getting good coms with the board at all but with the threat of switching out the breakoutboards I got comunication straight away and managed to set up terminal macros to correctly recive from my garmin HRM. So a big step forward and a lot better understanding after manualy sending and reciving a load of messaged.

Has anyone actualy decoded the actual HRM data yet? I am hoping there will just be some period of some form in there, e.g. milicseconds between beats…

ellbiddy:
I’ve gotten “bored” and have since developed a uC based power meter based off several strain gauges. I thought it would be neat to interface this to my Garmin 705. Although I’m sure I could “fake” it to look like a HRM monitor and just use that as my power data, but it’d be much neater to send it as actual power data (since they support various power meters over ant+). Since I don’t have access to the developer area of the garmin doc for the SDK I wasn’t sure how the PM’s communicate with the unit. I assume the “device profile” is different from HRM’s anyone have any ideas or suggestions for this? It was somewhat related to this original post so I figured I’d ask here :slight_smile:

I've just decoded the garmin power profile. If you're still interested, drop me a pm.

Hi Folks,

I’ve used the code from this thread to get started writing my own programming for working with the nRF24AP1 USB ANT Stick. I’m facing the same problem both in this code and in my own. After running the program, then exiting with ctrl-c, running it again fails to communicate. It hangs after the second packet (which is the first one expecting a response).

Has anyone else experienced this? Anybody have an idea?

Thanks in advance.

ssnyde:
After running the program, then exiting with ctrl-c, running it again fails to communicate. It hangs after the second packet (which is the first one expecting a response)

You could try my code: git clone git://e2c3.com/nant.git

I’ve recently rewritten my ant library and it’s still work in progress, but it should work for a HRM or ANT+ power meter.

Thanks gdev.

I can’t seem to compile due to this error

foo2.c:157: warning: integer constant is too large for ‘long’ type

Not a problem I think I found the issue. The problem only occurs on my laptop which runs kubuntu 9.10 kernel 2.6.31 which uses 1.5 of the ftdi driver. Everything works great on my desktop which is debian lenny kernel 2.6.26 with version 1.4.3 of the ftdi driver. I can’t be sure its not hardware but I think its the driver. At some point if I can find the source I’ll recompile 1.4.3 on the laptop but for now it’s all good.

ssnyde:
I can’t seem to compile due to this error

foo2.c:157: warning: integer constant is too large for ‘long’ type

I wouldn't worry about foo*.c. They're just test programs that discover ANT network keys. Only network keys that comply with a certain algorithm are accepted by the set network key operation so I was curious as to how it is done. I've found about 400 of them and they seem to be constrained to a mask value and probably some bit count operations. Anyway, foo*.c need two USB keys to transmit and receive and also stress test the library. It sounds like unsigned long long isn't 64 bits on your laptop. Is it a 32 bit system and your desktop is 64 bit?

I take it the program works on your desktop?

Hmm, yeah I was seeing the ctrl-c, not sending problem before. I haven’t don’t any work on the ant recently but I will look into sending some type of reset at the start will fix things.

edit: Nevermind, I am sending reset here…

ant.c 64: ANT_send(1+1, MESG_SYSTEM_RESET_ID, 0x00);

Hi guys, kind of stuck in a dilema here.

would any of you guys know if a heart rate monitor with ANT transmission can transmit data to 2 ant receivers simultaneously? or only one at a time

The garmin HRM can do this, and probably the same with the suunto

i see, basically i wanted to have a heartrate strap that transmits data to 2 devices

  1. something thats always on the person to store the data for the last 24 hours…

  2. a pc connection to keep a monitor of the data aswell…

any ideas or if i could use any products i.e. sunito belt with our own ANT modules? or are we restricted to use their own ANT reciever and software?