Ant+ libarary and USB driver for Teensy 3.5/6

MichaelMC

Well-known member
Attached is a first draft of implementing a USBHost driver for an Ant+ USB stick on the Teensy 3.6, for the Ant+ network protocol. Ant-FS (file transfers) is not implemented, yet, in the library though the framework is there for someone else to investigate, I have no need of it.
(Ant+ is a low energy Wifi networking protocol, originally and specifically targeting sports sensors, such as a heart rate monitor, bike speed sensor, etc..)

View attachment antplus_usb_05042017.zip

Notes:
Driver has been simultaneously tested with two devices:; that is, one device per channel; A heart rate monitor chest strap, and a combined bike sensor - speed and cadence, as can be observed in the debug output below.
In this draft, please compile with the included USBHost_t36. There are two small but required modifications: QTD_LENGTH() added to USBHost_t36.h and PERIODIC_LIST_SIZE must be set to 8, otherwise default library should be fine.

This is an initial draft so feedback is more than welcomed.

Using the included example, antplus.ino, should produced something below:
Code:
with HRM enabled only
---------


Ant+ USB
 @ start up mesg reason: 0x0
[0] * network key accepted
[0]  * channel assign accepted
[0]  * channel mesg period accepted
[0]  * search timeout period accepted
[0]  * radio freq accepted
[0]  * search waveform accepted
[0]  * set channel id accepted
[0]  * open channel accepted
Channel 0 status: STATUS SEARCHING CHANNEL
 @ version: 'AJK1.04RAF'
 @ capabilities:
   Max ANT Channels: 8
   Max ANT Networks: 3
   Std. option: 0x0
   Advanced: 0xBA
   Advanced2: 0x36
[1]  * channel assign accepted
Channel 1 status: STATUS ASSIGNED CHANNEL
[0] * network key accepted
[1]  * channel mesg period accepted
[0]  * channel assign accepted
[1]  * search timeout period accepted
[0]  * channel mesg period accepted
[1]  * radio freq accepted
[0]  * search timeout period accepted
[1]  * search waveform accepted
[0]  * radio freq accepted
[1]  * set channel id accepted
[0]  * search waveform accepted
[1]  * open channel accepted
[0]  * set channel id accepted
Channel 1 status: STATUS SEARCHING CHANNEL
 @ capabilities:
   Max ANT Channels: 8
   Max ANT Networks: 3
   Std. option: 0x0
   Advanced: 0xBA
   Advanced2: 0x36
 @ version: 'AJK1.04RAF'
[0]  * open channel accepted
 @ capabilities:
   Max ANT Channels: 8
   Max ANT Networks: 3
   Std. option: 0x0
   Advanced: 0xBA
   Advanced2: 0x36
 @ version: 'AJK1.04RAF'
HRM: sequence:208, interval:6672ms, bpm:46
Channel 0 status: STATUS TRACKING_CHANNEL
Device found on channel 0: deviceId:26434, deviceType:120, transType:1
HRM: sequence:209, interval:1318ms, bpm:47
HRM: sequence:210, interval:1147ms, bpm:48
HRM: sequence:211, interval:954ms, bpm:48
HRM: sequence:212, interval:1004ms, bpm:49
HRM: sequence:213, interval:1392ms, bpm:49
HRM: sequence:214, interval:1378ms, bpm:48
HRM: sequence:215, interval:1216ms, bpm:49
HRM: sequence:216, interval:1194ms, bpm:49
HRM: sequence:217, interval:1162ms, bpm:49
HRM: sequence:218, interval:1183ms, bpm:49
HRM: sequence:219, interval:1236ms, bpm:49
HRM: sequence:220, interval:1251ms, bpm:49
HRM: sequence:221, interval:1288ms, bpm:48
HRM: sequence:222, interval:1208ms, bpm:48
HRM: sequence:223, interval:1208ms, bpm:49
HRM: sequence:224, interval:1190ms, bpm:49
HRM: sequence:225, interval:1179ms, bpm:49
HRM: sequence:226, interval:1178ms, bpm:49
HRM: sequence:227, interval:1201ms, bpm:49
HRM: sequence:228, interval:1135ms, bpm:49
HRM: sequence:229, interval:1134ms, bpm:50
HRM: sequence:230, interval:1126ms, bpm:50
HRM: sequence:231, interval:1147ms, bpm:50
HRM: sequence:232, interval:1140ms, bpm:51
HRM: sequence:233, interval:1074ms, bpm:51
HRM: sequence:234, interval:1098ms, bpm:51
HRM: sequence:235, interval:1092ms, bpm:52
HRM: sequence:236, interval:1047ms, bpm:52
HRM: sequence:237, interval:1058ms, bpm:53
HRM: sequence:238, interval:1055ms, bpm:53
HRM: sequence:239, interval:1032ms, bpm:54
HRM: sequence:240, interval:1048ms, bpm:54
HRM: sequence:241, interval:1057ms, bpm:55
HRM: sequence:242, interval:1051ms, bpm:55
HRM: sequence:243, interval:1044ms, bpm:55
HRM: sequence:244, interval:1059ms, bpm:55
HRM: sequence:245, interval:1066ms, bpm:55
HRM: sequence:246, interval:1052ms, bpm:55
HRM: sequence:247, interval:1090ms, bpm:55
HRM: sequence:248, interval:1113ms, bpm:55
HRM: sequence:249, interval:1111ms, bpm:55
HRM: sequence:250, interval:1089ms, bpm:55
HRM: sequence:251, interval:1099ms, bpm:55
HRM: sequence:252, interval:1087ms, bpm:55
HRM: sequence:253, interval:1053ms, bpm:55
HRM: sequence:254, interval:1083ms, bpm:55
HRM: sequence:255, interval:1127ms, bpm:55
HRM: sequence:0, interval:1093ms, bpm:55
HRM: sequence:1, interval:1109ms, bpm:54
HRM: sequence:2, interval:1096ms, bpm:54
HRM: sequence:3, interval:1070ms, bpm:55
HRM: sequence:4, interval:1074ms, bpm:55
HRM: sequence:5, interval:1088ms, bpm:55
HRM: sequence:6, interval:1114ms, bpm:54
HRM: sequence:7, interval:1079ms, bpm:55
HRM: sequence:8, interval:1104ms, bpm:54
HRM: sequence:9, interval:1098ms, bpm:54
HRM: sequence:10, interval:1063ms, bpm:55
HRM: sequence:11, interval:1062ms, bpm:55
HRM: sequence:12, interval:1074ms, bpm:55
HRM: sequence:13, interval:1084ms, bpm:55
HRM: sequence:14, interval:1070ms, bpm:55
HRM: sequence:15, interval:1108ms, bpm:55
HRM: sequence:16, interval:1107ms, bpm:55
HRM: sequence:17, interval:1067ms, bpm:55
HRM: sequence:18, interval:1071ms, bpm:55
HRM: sequence:19, interval:1042ms, bpm:55
HRM: sequence:20, interval:1037ms, bpm:55
HRM: sequence:21, interval:1034ms, bpm:56
HRM: sequence:22, interval:1079ms, bpm:56
HRM: sequence:23, interval:1085ms, bpm:56
HRM: sequence:24, interval:1107ms, bpm:55
etc..

---

with HRM and a combined speed and cadence sensor enabled
(i'm manually spinning the cranks to generate sensor pickup)


---------
Ant+ USB
 @ start up mesg reason: 0x0
[0] * network key accepted
[0]  * channel assign accepted
[0]  * channel mesg period accepted
[0]  * search timeout period accepted
[0]  * radio freq accepted
[0]  * search waveform accepted
[0]  * set channel id accepted
[0]  * open channel accepted
Channel 0 status: STATUS SEARCHING CHANNEL
 @ capabilities:
   Max ANT Channels: 8
   Max ANT Networks: 3
   Std. option: 0x0
   Advanced: 0xBA
   Advanced2: 0x36
 @ version: 'AJK1.04RAF'
HRM: sequence:166, interval:37073ms, bpm:64
Channel 0 status: STATUS TRACKING_CHANNEL
[1]  * channel assign accepted
Channel 1 status: STATUS ASSIGNED CHANNEL
[0] * network key accepted
[1]  * channel mesg period accepted
[0]  * channel assign accepted
[1]  * search timeout period accepted
[0]  * channel mesg period accepted
[1]  * radio freq accepted
[0]  * search timeout period accepted
[1]  * search waveform accepted
[0]  * radio freq accepted
[1]  * set channel id accepted
[0]  * search waveform accepted
[1]  * open channel accepted
[0]  * set channel id accepted
Channel 1 status: STATUS SEARCHING CHANNEL
 @ capabilities:
   Max ANT Channels: 8
   Max ANT Networks: 3
   Std. option: 0x0
   Advanced: 0xBA
   Advanced2: 0x36
 @ version: 'AJK1.04RAF'
[0]  * open channel accepted
HRM: sequence:167, interval:1105ms, bpm:63
 @ capabilities:
   Max ANT Channels: 8
   Max ANT Networks: 3
   Std. option: 0x0
   Advanced: 0xBA
   Advanced2: 0x36
 @ capabilities:
   Max ANT Channels: 8
   Max ANT Networks: 3
   Std. option: 0x0
   Advanced: 0xBA
   Advanced2: 0x36
 @ version: 'AJK1.04RAF'
SPDCAD: speed: 614.52km/h, cadence: 27676rpm, total distance: 114.55km
Channel 1 status: STATUS TRACKING_CHANNEL
Device found on channel 1: deviceId:23513, deviceType:121, transType:1
HRM: sequence:168, interval:1080ms, bpm:62
HRM: sequence:169, interval:1123ms, bpm:61
HRM: sequence:170, interval:1074ms, bpm:60
HRM: sequence:171, interval:1037ms, bpm:60
HRM: sequence:172, interval:875ms, bpm:60
HRM: sequence:173, interval:842ms, bpm:60
HRM: sequence:174, interval:808ms, bpm:61
SPDCAD: speed: 0.00km/h, cadence: 1rpm, total distance: 114.55km
HRM: sequence:175, interval:759ms, bpm:63
SPDCAD: speed: 0.00km/h, cadence: 349rpm, total distance: 114.55km
HRM: sequence:176, interval:738ms, bpm:66
HRM: sequence:177, interval:718ms, bpm:68
HRM: sequence:178, interval:715ms, bpm:70
SPDCAD: speed: 0.23km/h, cadence: 27rpm, total distance: 114.55km
SPDCAD: speed: 22.28km/h, cadence: 0rpm, total distance: 114.56km
HRM: sequence:179, interval:696ms, bpm:72
SPDCAD: speed: 24.83km/h, cadence: 86rpm, total distance: 114.56km
SPDCAD: speed: 24.36km/h, cadence: 0rpm, total distance: 114.56km
HRM: sequence:180, interval:673ms, bpm:74
SPDCAD: speed: 24.21km/h, cadence: 0rpm, total distance: 114.56km
SPDCAD: speed: 23.92km/h, cadence: 0rpm, total distance: 114.56km
HRM: sequence:181, interval:682ms, bpm:75
SPDCAD: speed: 23.77km/h, cadence: 0rpm, total distance: 114.57km
SPDCAD: speed: 23.56km/h, cadence: 0rpm, total distance: 114.57km
SPDCAD: speed: 23.35km/h, cadence: 0rpm, total distance: 114.57km
HRM: sequence:182, interval:668ms, bpm:77
SPDCAD: speed: 23.14km/h, cadence: 0rpm, total distance: 114.57km
HRM: sequence:183, interval:653ms, bpm:79
SPDCAD: speed: 22.94km/h, cadence: 0rpm, total distance: 114.57km
SPDCAD: speed: 22.80km/h, cadence: 21rpm, total distance: 114.57km
HRM: sequence:184, interval:663ms, bpm:80
SPDCAD: speed: 22.54km/h, cadence: 0rpm, total distance: 114.58km
SPDCAD: speed: 22.28km/h, cadence: 0rpm, total distance: 114.58km
HRM: sequence:185, interval:672ms, bpm:81
SPDCAD: speed: 22.16km/h, cadence: 0rpm, total distance: 114.58km
SPDCAD: speed: 21.97km/h, cadence: 0rpm, total distance: 114.58km
HRM: sequence:186, interval:679ms, bpm:82
SPDCAD: speed: 21.72km/h, cadence: 0rpm, total distance: 114.58km
SPDCAD: speed: 21.49km/h, cadence: 0rpm, total distance: 114.59km
HRM: sequence:187, interval:683ms, bpm:83
SPDCAD: speed: 21.31km/h, cadence: 0rpm, total distance: 114.59km
SPDCAD: speed: 21.08km/h, cadence: 0rpm, total distance: 114.59km
HRM: sequence:188, interval:689ms, bpm:83
SPDCAD: speed: 20.91km/h, cadence: 0rpm, total distance: 114.59km
SPDCAD: speed: 20.74km/h, cadence: 0rpm, total distance: 114.60km
HRM: sequence:189, interval:692ms, bpm:84
SPDCAD: speed: 20.47km/h, cadence: 0rpm, total distance: 114.60km
SPDCAD: speed: 0.00km/h, cadence: 14rpm, total distance: 114.60km
SPDCAD: speed: 20.53km/h, cadence: 0rpm, total distance: 114.60km
HRM: sequence:190, interval:683ms, bpm:84
SPDCAD: speed: 21.60km/h, cadence: 0rpm, total distance: 114.60km
HRM: sequence:191, interval:709ms, bpm:84
SPDCAD: speed: 21.49km/h, cadence: 62rpm, total distance: 114.60km
SPDCAD: speed: 22.94km/h, cadence: 0rpm, total distance: 114.61km
SPDCAD: speed: 23.92km/h, cadence: 0rpm, total distance: 114.61km
HRM: sequence:192, interval:705ms, bpm:84
SPDCAD: speed: 23.70km/h, cadence: 66rpm, total distance: 114.61km
SPDCAD: speed: 24.52km/h, cadence: 0rpm, total distance: 114.61km
HRM: sequence:193, interval:750ms, bpm:84
SPDCAD: speed: 24.67km/h, cadence: 0rpm, total distance: 114.61km
SPDCAD: speed: 24.44km/h, cadence: 69rpm, total distance: 114.61km
HRM: sequence:194, interval:756ms, bpm:83
SPDCAD: speed: 24.83km/h, cadence: 0rpm, total distance: 114.62km
SPDCAD: speed: 24.83km/h, cadence: 0rpm, total distance: 114.62km
SPDCAD: speed: 24.75km/h, cadence: 69rpm, total distance: 114.62km
HRM: sequence:195, interval:756ms, bpm:83
SPDCAD: speed: 25.23km/h, cadence: 0rpm, total distance: 114.62km
SPDCAD: speed: 25.15km/h, cadence: 0rpm, total distance: 114.62km
SPDCAD: speed: 24.99km/h, cadence: 55rpm, total distance: 114.63km
HRM: sequence:196, interval:768ms, bpm:82
SPDCAD: speed: 25.15km/h, cadence: 0rpm, total distance: 114.63km
SPDCAD: speed: 25.23km/h, cadence: 0rpm, total distance: 114.63km
SPDCAD: speed: 0.00km/h, cadence: 69rpm, total distance: 114.63km
HRM: sequence:197, interval:724ms, bpm:82
SPDCAD: speed: 24.99km/h, cadence: 0rpm, total distance: 114.63km
SPDCAD: speed: 24.75km/h, cadence: 0rpm, total distance: 114.64km
HRM: sequence:198, interval:732ms, bpm:82
SPDCAD: speed: 24.67km/h, cadence: 0rpm, total distance: 114.64km
SPDCAD: speed: 24.44km/h, cadence: 63rpm, total distance: 114.64km
HRM: sequence:199, interval:705ms, bpm:82
SPDCAD: speed: 24.21km/h, cadence: 0rpm, total distance: 114.64km
SPDCAD: speed: 24.06km/h, cadence: 0rpm, total distance: 114.64km
SPDCAD: speed: 23.92km/h, cadence: 68rpm, total distance: 114.64km
HRM: sequence:200, interval:706ms, bpm:82
SPDCAD: speed: 24.36km/h, cadence: 0rpm, total distance: 114.65km
SPDCAD: speed: 24.14km/h, cadence: 0rpm, total distance: 114.65km
HRM: sequence:201, interval:708ms, bpm:83
SPDCAD: speed: 23.92km/h, cadence: 0rpm, total distance: 114.65km
SPDCAD: speed: 23.77km/h, cadence: 0rpm, total distance: 114.65km
HRM: sequence:202, interval:690ms, bpm:83
SPDCAD: speed: 23.56km/h, cadence: 0rpm, total distance: 114.65km
SPDCAD: speed: 23.42km/h, cadence: 29rpm, total distance: 114.66km
SPDCAD: speed: 23.70km/h, cadence: 0rpm, total distance: 114.66km
HRM: sequence:203, interval:673ms, bpm:84
SPDCAD: speed: 23.63km/h, cadence: 0rpm, total distance: 114.66km
HRM: sequence:204, interval:677ms, bpm:84
SPDCAD: speed: 23.56km/h, cadence: 62rpm, total distance: 114.66km
SPDCAD: speed: 23.14km/h, cadence: 0rpm, total distance: 114.67km
HRM: sequence:205, interval:671ms, bpm:85
SPDCAD: speed: 22.94km/h, cadence: 0rpm, total distance: 114.67km
SPDCAD: speed: 21.25km/h, cadence: 0rpm, total distance: 114.67km
HRM: sequence:206, interval:667ms, bpm:85
HRM: sequence:207, interval:678ms, bpm:86
HRM: sequence:208, interval:674ms, bpm:86
SPDCAD: speed: 0.00km/h, cadence: 20rpm, total distance: 114.67km
HRM: sequence:209, interval:647ms, bpm:87
HRM: sequence:210, interval:657ms, bpm:87
HRM: sequence:211, interval:668ms, bpm:88
SPDCAD: speed: 1.98km/h, cadence: 0rpm, total distance: 114.67km
HRM: sequence:212, interval:645ms, bpm:88
HRM: sequence:213, interval:640ms, bpm:89
HRM: sequence:214, interval:643ms, bpm:89
HRM: sequence:215, interval:656ms, bpm:89
HRM: sequence:216, interval:644ms, bpm:90
HRM: sequence:217, interval:474ms, bpm:90
HRM: sequence:218, interval:833ms, bpm:90
HRM: sequence:219, interval:634ms, bpm:90
HRM: sequence:220, interval:613ms, bpm:91
HRM: sequence:221, interval:617ms, bpm:92
HRM: sequence:222, interval:603ms, bpm:93
HRM: sequence:223, interval:632ms, bpm:93
HRM: sequence:224, interval:853ms, bpm:93
HRM: sequence:225, interval:907ms, bpm:93
HRM: sequence:226, interval:894ms, bpm:90
HRM: sequence:227, interval:816ms, bpm:88
HRM: sequence:228, interval:897ms, bpm:85
HRM: sequence:229, interval:899ms, bpm:83
HRM: sequence:230, interval:837ms, bpm:81
HRM: sequence:231, interval:895ms, bpm:79
HRM: sequence:232, interval:908ms, bpm:78
HRM: sequence:233, interval:901ms, bpm:76
HRM: sequence:234, interval:911ms, bpm:75
HRM: sequence:235, interval:950ms, bpm:73
HRM: sequence:236, interval:943ms, bpm:72
HRM: sequence:237, interval:928ms, bpm:71
 
Is this code open source? Should I merge it into the USBHost_t36 library? It really needs to have a MIT or similar license to be merged.

I'm not familiar with this wireless protocol and I don't own any devices that use it. Any suggestions on the minimal gear to buy to actually give it a try?


Edit: took me a few minutes to figure out the command to extract this zip file: "7za x antplus_usb_05042017.zip" ;)
 
It's open source in that it's here for anyone to do with what they please. I still want to complete implementing a few of the remaining profiles, afterwhich I'll create a github and add an open source licence (for all to abuse).

A minimal setup would be a USB stick and a sensor of your choice.
Any Ant+ USB dongle should suffice. For my teensy bike computer I'll be picking up this small £12 adapter here: https://www.amazon.co.uk/Anself-Compatible-Garmin-Forerunner-011-02209-00/dp/B00LIIMHP4/?th=1
For developing Ant+ anything I'd recommend one leans toward a heart rate monitor strap, just wear and forget. I use an older model of this: https://www.amazon.co.uk/Garmin-Monitor-Products-Including-Forerunner-x/dp/B000UOD5QM/

7zip was used to compact the source in to a Zip compatible archive. I selected .zip as the forum doesn't accept .7z, a much leaner container imo.
 
Thanks very much for the library, I have been thinking about making a bike computer for years. I have ordered a generic ant+ usb stick form Amazon and have parts coming from PJRC. With sunlight readable required does anyone have any display suggestions?
 
Success! Just received parts from PJRC, generic Ant+ module working initially with HRM and with a little tweak cadence.
 
Excellent, nice to have confirmation.

How did you fair with the sunlight readable display? My own research hasn't turned up anything but non-viable E-Ink. A capacitive touch ~320x240 OLED would be amazing find right about now.
 
Last edited:
I've merged all the Ant code.

In the process, I made *many* modifications to put into the C++ object and replace the libant C-style callback with a group of Arduino style callbacks.

Any chance you could give the latest code a try?

https://github.com/PaulStoffregen/USBHost_t36

Here's the example sketch. Much more Arduino style! ;)

https://github.com/PaulStoffregen/USBHost_t36/blob/master/examples/AntPlus/AntPlus.ino

I tested with the Garmin heart rate monitor, but I don't have the bicycle wheel hardware.
 
Paul this looks excellent; nice, clean and with a user friendly API.

Few modifications.
Added:
Code:
		profileSetup_SPDCAD(&ant.dcfg[PROFILE_SPDCAD], devid);
		memset(&spdcad, 0, sizeof(spdcad));
to USBHost_t36.h -> onSpeedCadence(), as it were missing.

in AntPlus:: payload_SPDCAD(), there is a typo in the change logic, it should be:
Code:
	if (cadenceTime == spdcad.previous.cadenceTime
	  && cadenceCt == spdcad.previous.cadenceCt
	  && speedTime == spdcad.previous.speedTime
	  && speedCt == spdcad.previous.speedCt) {

The remaining untested devices/profiles will have to wait until someone with said device comes along and complains, until then, it all looks good to me.

Cartere, What was the tweak that you made?
 
Correct. I intentionally left those unfinished due to not having access to the hardware.

Stride is from an ankle Foot Pod as used by runners to measure speed and distance via stride length, aka: https://www.amazon.co.uk/O-Synce-Max-Run-Foot-Pod/dp/B003Y73LIY/

Power is from bicycle power cranks (either or both sides) and is used to measure rider output wattage, which is a method of garnering overall rider strength and fitness: https://www.amazon.co.uk/Stages-Power-Meter-Ultegra-6800/dp/B01M4FOV0B/
I would dearly love one of these for training, but not while they're costing £400+ plus.

Speed profile is just the single speed element of a speed-cadence sensor, likewise for a singular cadence sensor.

Others:
The 'Fitness Equipment' profile relates to gym equipment, such as a static bike, running or rowing machine.

'Weight Scale' profile is a wireless bathroom scale, usually the kind which also measures body fat (via impedance): https://www.amazon.co.uk/smartLAB-Analyzer-Bluetooth-Android-Connect/dp/B00S6H61H0/
 
Hi. I am trying to get the heart rate measurements with the following hardware plugged into the Teensy 4.1:

Ant+ usb dongle
Heart rate belt

The sketch is pretty simple:

Code:
#include <USBHost_t36.h>

USBHost myusb;
AntPlus ant1(myusb);

void setup()
{
    myusb.begin();
    ant1.begin();
    ant1.onStatusChange(handleStatusChange);
    ant1.onDeviceID(handleDeviceID);
    ant1.onHeartRateMonitor(handleHeartRateMonitor);
}

unsigned long timer = 0;
void loop()
{
    if(millis() - timer > 2000) {
      Serial.println("OK");
      timer = millis();
    }
    
    myusb.Task();
}

void handleHeartRateMonitor(int beatsPerMinute, int milliseconds, int sequenceNumber) {
  Serial.print("HRM: sequence:");
  Serial.print(sequenceNumber);
  Serial.print(", interval:");
  Serial.print(milliseconds);
  Serial.print("ms, bpm:");
  Serial.println(beatsPerMinute);
}

void handleStatusChange(int channel, int status) {
  Serial.print("Channel ");
  Serial.print(channel);
  Serial.print(" status: ");
  switch (status) {
    case 0: Serial.println("STATUS UNASSIGNED CHANNEL"); break;
    case 1: Serial.println("STATUS ASSIGNED CHANNEL"); break;
    case 2: Serial.println("STATUS SEARCHING CHANNEL"); break;
    case 3: Serial.println("STATUS TRACKING_CHANNEL"); break;
    default: Serial.println("UNKNOWN STATUS STATE");
  }
}

void handleDeviceID(int channel, int devId, int devType, int transType) {
  Serial.print("Device found on channel ");
  Serial.print(channel);
  Serial.print(": deviceId:");
  Serial.print(devId);
  Serial.print(", deviceType:");
  Serial.print(devType);
  Serial.print(", transType:");
  Serial.println(transType); 
}

It works fine for about 20 seconds then it stops printing the readings to the serial monitor. This is the output:

Code:
[0] * network key accepted

[0]  * channel assign accepted

[0]  * channel mesg period accepted

[0]  * search timeout period accepted

[0]  * radio freq accepted

[0]  * search waveform accepted

[0]  * set channel id accepted

[0]  * open channel accepted

Channel 0 status: STATUS SEARCHING CHANNEL

 @ capabilities:

   Max ANT Channels: 8

   Max ANT Networks: 3

   Std. option: 0x0

   Advanced: 0xBA

   Advanced2: 0x36

 @ version: 'AP2USB1.05'

HRM: sequence:117, interval:50940ms, bpm:82

Device found on channel 0: deviceId:55062, deviceType:120, transType:1

Channel 0 status: STATUS TRACKING_CHANNEL

HRM: sequence:118, interval:714ms, bpm:82

OK

HRM: sequence:119, interval:721ms, bpm:82

HRM: sequence:120, interval:742ms, bpm:82

OK

HRM: sequence:121, interval:771ms, bpm:81

HRM: sequence:122, interval:799ms, bpm:81

HRM: sequence:123, interval:796ms, bpm:81

OK

HRM: sequence:124, interval:817ms, bpm:81

HRM: sequence:125, interval:822ms, bpm:80

OK

HRM: sequence:126, interval:817ms, bpm:80

HRM: sequence:127, interval:815ms, bpm:79

HRM: sequence:128, interval:819ms, bpm:79

OK

HRM: sequence:129, interval:817ms, bpm:77

HRM: sequence:130, interval:806ms, bpm:77

OK

HRM: sequence:131, interval:793ms, bpm:76

HRM: sequence:132, interval:765ms, bpm:76

HRM: sequence:133, interval:768ms, bpm:75

OK

HRM: sequence:134, interval:771ms, bpm:75

HRM: sequence:135, interval:805ms, bpm:74

OK

HRM: sequence:136, interval:852ms, bpm:74

HRM: sequence:137, interval:844ms, bpm:74

HRM: sequence:138, interval:849ms, bpm:74

OK

I am printing "OK" for debug every 2 seconds. As soon as it stops printing the heart rate, it stops printing the debug message as well meaning the sketch freezes completely excluding a communication problem between the sensor and the usb dongle. I have also tested the belt and the dongle plugged into my computer running the demo provided in the SDK and it prints the heart rate for several minutes without any problem.

I am using Arduino 1.8.13 and Teensyduino 1.53. Currently debugging the library trying to figure out the issue, any suggestion would be much appreciated!
 
I found the problem: the sketch doesn't freeze as I assumed initially, it keeps running but at some point it gets stuck in an infinite loop inside the "do while" in "antplus.cpp" line 184 waiting for the buffer to empty.

As a quick fix I simply added a maximum number of attempts and force the condition to get out of the loop. I replaced the following code:

Code:
do {
      uint32_t tail = txtail;
      if (head > tail) {
         avail = sizeof(txbuffer) - head + tail;
      } else {
         avail = tail - head;
      }
} while (avail < size + 1);

With this:

Code:
uint8_t attempts = 100;
do {
	uint32_t tail = txtail;
	if (head > tail) {
	    avail = sizeof(txbuffer) - head + tail;
	} else {
	    avail = tail - head;
	}
	attempts--;
} while ((avail < size + 1) && attempts > 0 );


I don't like this solution but it works. Been running for more than 20 minutes without issues. I also tried to comment out the "do while" and it still works so I am not sure what would be the best solution as I have not fully understood the whole code yet.
 
Thank you HRBF,

The example AntPlus.ino locked up on me as well. I used 2.0.4 and TeensyDuino 1.57.2 and also a Teensy 4.1. Using your modifications to antplus.cpp fixed the issue. Over an hour of monitoring HR with no hang ups.
 
Thank you HRBF,

The example AntPlus.ino locked up on me as well. I used 2.0.4 and TeensyDuino 1.57.2 and also a Teensy 4.1. Using your modifications to antplus.cpp fixed the issue. Over an hour of monitoring HR with no hang ups.

You are welcome. Glad it was helpful!
 
HRBF, I've been looking at this. First thing I tried was the original code as attached above. This ran perfectly for the ~2hrs I tried - without issue. Next I tried the code as included with the Teensy distribution - this locks up as described.
If I recall correctly, the ANT receiver may deliver to the USB endpipe an incomplete packet. This packet must then be prepended to the proceeding packet and then processed as one. It is possible this process has been disrupted through the conversion of the original code, as attached above, to the CPP port - which also includes updated USB read/write constructs.

The modification to that 'while loop' is brushing the issue under the carpet. I will look at this further.
 
HRBF, I've been looking at this. First thing I tried was the original code as attached above. This ran perfectly for the ~2hrs I tried - without issue. Next I tried the code as included with the Teensy distribution - this locks up as described.
If I recall correctly, the ANT receiver may deliver to the USB endpipe an incomplete packet. This packet must then be prepended to the proceeding packet and then processed as one. It is possible this process has been disrupted through the conversion of the original code, as attached above, to the CPP port - which also includes updated USB read/write constructs.

The modification to that 'while loop' is brushing the issue under the carpet. I will look at this further.

Hi, thank you for taking the time to investigate the issue and for explaining what may be causing the problem.

Have a great day
 
Back
Top