Draw a simple HR chart on watchface & Unhandled exception on device

Hello Grin

I'm creating a new watchface for EPIX2.

I tried to draw a HR chart using history data thanks to ActivityMonitor.getHeartRateHistory()

I was inspired by the example availlable at https://developer.garmin.com/connect-iq/api-docs/Toybox/ActivityMonitor.html but I had to fix the "Watchdog Tripped Error - Code Executed Too Long" by replacing the while(true) { }

Here I am now:

            var hrDuration = 240; //! x last minutes of HR
			var hrIterator = ActivityMonitor.getHeartRateHistory(hrDuration, true); //! get  last minutes of HR
			var hrMax = (220-(info.year-profile.birthYear)*1.1); //! 10% margin added to the basic calculus rule
			var hrMin = profile.restingHeartRate; //! data store in the user profile 
			var previous = hrIterator.next(); //! get the previous HR
			var lastSampleTime = null; //! get the last
			
			var hChart = 44;
			var xStartHr = 280;
			var yStartHr = 150;
			var genericZoneInfo = Us.getHeartRateZones(Us.HR_ZONE_SPORT_GENERIC);
			var hrOrd;
			
			//! Draw the cHR chart
			for (var i=0;i<=hrDuration;i+=1) {
			   var sample = hrIterator.next();
			   if (null!=sample) { //! null check        
			        if (sample.heartRate != ActivityMonitor.INVALID_HR_SAMPLE && previous.heartRate != ActivityMonitor.INVALID_HR_SAMPLE) { //! check for invalid samples
		                if (sample.heartRate != null && sample.heartRate != 0) {
		                	hrOrd = ((sample.heartRate-hrMin)*(hChart-2)/(hrMax-hrMin)); //! Height in pixel of current HR in chart / -2 to substract 2px of the frame line
							dc.setColor(Gfx.COLOR_BLUE,Gfx.COLOR_TRANSPARENT);
							if (sample.heartRate >= genericZoneInfo[1]) {dc.setColor(Gfx.COLOR_GREEN, Gfx.COLOR_TRANSPARENT);}
							if (sample.heartRate >= genericZoneInfo[2]) {dc.setColor(Gfx.COLOR_YELLOW,Gfx.COLOR_TRANSPARENT);}
							if (sample.heartRate >= genericZoneInfo[3]) {dc.setColor(Gfx.COLOR_ORANGE,Gfx.COLOR_TRANSPARENT);}
							if (sample.heartRate >= genericZoneInfo[4]) {dc.setColor(Gfx.COLOR_RED,   Gfx.COLOR_TRANSPARENT);}
							if (sample.heartRate >= genericZoneInfo[5]) {dc.setColor(Gfx.COLOR_PURPLE,Gfx.COLOR_TRANSPARENT);}
		                	dc.drawLine(xStartHr-i,yStartHr-hrOrd,xStartHr-i,yStartHr); //! Draw chart if with have a HR value
		                } else { //! Draw a blank if we have no value
		                	dc.setColor(Gfx.COLOR_DK_GRAY,Gfx.COLOR_TRANSPARENT);
		                	dc.drawLine(xStartHr-i,yStartHr-hChart,xStartHr-i,yStartHr);
		                }
			        }
			    }
			}

It seems to work on the simulator. But I got instant unhandled exception with the device.

Have you ever experienced this kind of trouble ?

Thank you for your help Slight smile

Gautier

  • in

    for (var i=0;i<=hrDuration;i+=1) {

    What is hrDuration?  You might want to use 

    while(sample!=null) there.

    (maybe include a max number of samples you want to display too)

    and then do the sample=hrInterator.next() at the end of that while loop instead of the beginning

  • Hi Jim,

    Thank you for your help! Raised hands

    in

    for (var i=0;i<=hrDuration;i+=1) {

    What is hrDuration?

    hrDuration is the duration in minutes I want to get: 240 for 4 hours of heart rate history.

    If I understand correctly getHeartRateHistory() , I can substitue it with:

    var hrDuration = new Time.Duration(14400);

    You might want to use 

    while(sample!=null) there.

    (maybe include a max number of samples you want to display too)

    and then do the sample=hrInterator.next() at the end of that while loop instead of the beginning

    OK: I tried this new lite version:

    var sample=hrIterator.next();
    var i=0;
    
    //! Draw the HR chart
    while(sample!=null) {//! null check
        if (sample.heartRate!=ActivityMonitor.INVALID_HR_SAMPLE && previous.heartRate!=ActivityMonitor.INVALID_HR_SAMPLE) { //! check for invalid samples
            if (sample.heartRate!=0) {
                hrOrd=((sample.heartRate-hrMin)*(hChart-2)/(hrMax-hrMin)); //! Height in pixel of current HR in chart / -2 to substract 2px of the frame line
    			dc.setColor(Gfx.COLOR_BLUE,Gfx.COLOR_TRANSPARENT);
    			   dc.drawLine(xStartHr-i,yStartHr-hrOrd,xStartHr-i,yStartHr); //! Draw chart if with have a HR value
            }
        }
        sample = hrIterator.next(); //! Get the next sample
        i+=1; //! shift to the next px of the chart
    }

    It works perfectly with the simu:

    But still the same unhandled exception with the EPIX2. instant crash ! Rage

  • On which line of code do you get the exception?  on the device under garmin\apps\logs there is a ciq_log file where you can see your crash

  • You are right!

    I've a line number in the debug now! 325:

    hrOrd=((sample.heartRate-hrMin)*(hChart-2)/(hrMax-hrMin)); //! Height in pixel of current HR in chart / -2 to substract 2px of the frame line
    And it works perfectly now on my device if I replace the line by a simple

    hrOrd=10;

    The problem is in hrOrd calulation finally!