Welcome Guest,Register Now
Log In

ANT Forum

Welcome guest, please Login or Register

You are here: Forum Home → ANT+ Forums → ANT+ Heart Rate Monitor → Thread

   

<solved> Rollover Handling for R-R Intervals via Page 4

Rank

Total Posts: 12

Joined 2020-02-12

PM

First, thanks in advance! I need some feedback on my script. I'm using python 3.7 to capture my various device data streams for later analysis. That later portion will eventually deal with DFA-a1 analysis using this data.

Here's the code portion that calculates the R-R interval based on Package (Page 4) as noted on Section 7.2, page 33 of the HR device profile (file excerpt attached to this message):
# This section is for the POLAR sensor, deviceNumber=18990
if msg.deviceType == 120:
    
mv memoryview(msg._content)
    
# Page 0x04. Use the recommended main page 4 only
    
if mv[0] == 4:      
        
# Assembled computation elements (LSB/MSB)
        
val_HR mv[7]  # Calculated HR (bpm)
        
val_HRV abs( ((mv[5]<<mv[4]) - (mv[3]<<mv[2])) *1000/1024 )  # HRV (milliseconds) 

The resulting R-R interval value (val_HRV) seems reduced a bit when compared to a concurrently running HRV reader app. using the same Polar H10 strap as my script above... close, but not a match. They should be the same correct? This brings me to the next part, rollover handling. I'm certain I don't have the intent coded correctly to address rollover for the heartbeat count and the heartbeat event time. I'm not certain what to do with the differences. Here's what the code portion looks like:
# Handle rollover events
self.heartbeatCount mv[6]
self
.heartbeatEventTime val_HRV

if self.heartbeatCountOld self.heartbeatCount:
    
# The rollover correction at 2^8
    
heartbeatCountDiff = (self.heartbeatCount 256) - self.heartbeatCountOld
else:
    
heartbeatCountDiff self.heartbeatCount self.heartbeatCountOld

if self.heartbeatEventTimeOld self.heartbeatEventTime:
    
# Rollover correction at 2^16 = 65536, or 63.999 * 1024 either is about 65,534.976
    
heartbeatEventTimeDiff = (self.heartbeatEventTime 65536) - self.heartbeatEventTimeOld
else:
    
heartbeatEventTimeDiff self.heartbeatEventTime self.heartbeatEventTimeOld 

Also, I'm not certain that the "else" conditions belong as Section 7.1 doesn't mention it. I sure would appreciate where I'm going off-track as I don't want to get into the DFAa1 phase with inaccurate data.

What to do with the rollover adjustments/corrections?

TIA,
Eric      

Image Attachments

p33.png

Click thumbnail to see full-size image

RankRankRankRank

Total Posts: 370

Joined 2012-06-27

PM

"val_HRV = abs( ((mv[5]<<8 | mv[4]) - (mv[3]<<8 | mv[2])) *1000/1024 )" does not correctly handle rollover in python. Ex abs((10 - 65535)*1000/1024) = abs(-63989.26) = 63989.26. It should be 11*1000/1024. In embedded c with unsigned types the rollover is handled by the nature of unsigned math.

The hr timestamp values rollover at 65535 to 65536 transition. They got from 65535 to 0. This maps to 2^16 in sec 7.1. This means you should be using

"if self.heartbeatEventTimeOld > self.heartbeatEventTime:
# Rollover correction at 2^16 = 65536, or 63.999 * 1024 either is about 65,534.976
heartbeatEventTimeDiff = (self.heartbeatEventTime + 65536) - self.heartbeatEventTimeOld
else:
heartbeatEventTimeDiff = self.heartbeatEventTime - self.heartbeatEventTimeOld "      

Signature

Ian Haigh

RankRankRankRank

Total Posts: 370

Joined 2012-06-27

PM

Note: The app you are comparing against may be using section 7.3 and therefore not match if you only use 7.2. You would have to reach out to the app creator to determine what is causing the difference.      

Signature

Ian Haigh

Rank

Total Posts: 12

Joined 2020-02-12

PM

Thanks so much! I'll check it out when I get home tonight! Best!
Eric A.      
Rank

Total Posts: 12

Joined 2020-02-12

PM

Ian,
That other app creator's work is based on Polar's BLE implementation, so I'd expect the output values wouldn't be an apples-to-apples comparison.

I re-thought the integration of the rollover condition in the above script, changing it to:
# This section is for the POLAR sensor, deviceNumber=18990
if msg.deviceType == 120:
    
mv memoryview(msg._content)
    
# Page 0x04. Use the recommended main Page 4
    
if mv[0] == 4:       
        
# Assembled computation elements (LSB/MSB)
        
val_HR mv[7]  # Provided HR (bpm)
        # Initiate event values
        
self.heartbeatEventTime = (mv[5]<<mv[4])
        
self.heartbeatEventTimeOld = (mv[3]<<mv[2])
        
# Check for rollover by comparing new vs. old values
        
if self.heartbeatEventTime self.heartbeatEventTimeOld:
            
# Rollover has occurred. Correction at 2^16 = 65536
            
val_HRV = ((self.heartbeatEventTime 65536) - self.heartbeatEventTimeOld )*1000/1024
        
else:
            
val_HRV = (self.heartbeatEventTime self.heartbeatEventTimeOld)*1000/1024 

I haven't found another reader/tracker app that uses the ANT+ Device Profile (Section 7.2 specifically) but will continue to search. Thoughts on the above?
TIA,
Eric
     
RankRankRankRank

Total Posts: 370

Joined 2012-06-27

PM

The above looks correct. SimulANT+ parses R-R information.

     

Signature

Ian Haigh

Rank

Total Posts: 12

Joined 2020-02-12

PM

Ahh, very good. Many thanks, Ian.
Cheers,
Eric A.