Showing the steps and HR each second

Hello, guys!

I've faced with the problem of showing of the steps and HR for every second

Here is my code

function onUpdate(dc) {
    View.onUpdate(dc);
	drawInterface(dc);
	
	if (System.getClockTime().sec%5 == 0){
		System.println("GO");
		onPartialUpdate(dc);
	}
}

function onPartialUpdate(dc){
	new ODR001Fields().drawFieldsPart(dc);
}

function drawFieldsPart(dc){


    	if (info has :steps) {
			steps = info.steps;
		}
		
    	dc.setColor(BGF, Graphics.COLOR_TRANSPARENT);
		dc.setClip(	0.207*length - dc.getTextDimensions(steps.toString(), digitFieldsFont)[0]*0.5, 
					0.5728*length - dc.getTextDimensions(steps.toString(), digitFieldsFont)[1]*0.5, 
					dc.getTextDimensions(steps.toString(), digitFieldsFont)[0]*1, 
					dc.getTextDimensions(steps.toString(), digitFieldsFont)[1]*1);			
		dc.fillRectangle(	0.207*length - dc.getTextDimensions(steps.toString(), digitFieldsFont)[0]*0.5, 
							0.5728*length - dc.getTextDimensions(steps.toString(), digitFieldsFont)[1]*0.5, 
							dc.getTextDimensions(steps.toString(), digitFieldsFont)[0]*1, 
							dc.getTextDimensions(steps.toString(), digitFieldsFont)[1]*1);					
		dc.setColor(TBGF, Graphics.COLOR_TRANSPARENT);
		dc.drawText(0.207*length, 0.5728*length, digitFieldsFont, steps, Graphics.TEXT_JUSTIFY_CENTER|Graphics.TEXT_JUSTIFY_VCENTER);
		dc.clearClip();
		
		
	    var previous = "";
	    if ((Toybox has :SensorHistory) && (Toybox.SensorHistory has :getHeartRateHistory)) {
	    	var sensorIter = Toybox.SensorHistory.getHeartRateHistory({});
	    	System.println(sensorIter.next().data);
	    	previous = sensorIter.next().data;
	    }
	    
	    if (previous == null) {
	        previous = "00";
	    }
	    
		
		
		dc.setClip(	x - dc.getTextDimensions(previous.toString(), pulseDigitFont)[0]*0.5, 
					0.78*length - dc.getTextDimensions(previous.toString(), pulseDigitFont)[1]*0.5, 
					dc.getTextDimensions(previous.toString(), pulseDigitFont)[0]*1, 
					dc.getTextDimensions(previous.toString(), pulseDigitFont)[1]*1);
		dc.setColor(BGA, Graphics.COLOR_TRANSPARENT);

		dc.fillRectangle(	x - dc.getTextDimensions(previous.toString(), pulseDigitFont)[0]*0.5, 
							0.78*length - dc.getTextDimensions(previous.toString(), pulseDigitFont)[1]*0.5, 
							dc.getTextDimensions(previous.toString(), pulseDigitFont)[0]*1, 
							dc.getTextDimensions(previous.toString(), pulseDigitFont)[1]*1);
		dc.setColor(TBGA, Graphics.COLOR_TRANSPARENT);
		
		dc.drawText(x, 0.775*length, pulseDigitFont, previous, Graphics.TEXT_JUSTIFY_CENTER|Graphics.TEXT_JUSTIFY_VCENTER);	
		
		dc.clearClip();
		
    }

So, it's working just fine in the sim, but on my Fenix 5X neither steps neither HR updates every second. These fields update in a minute instead

What I'm doing wrong?

  • One thing to consider is that things don't always change every second, so you may want to only update things when they do change (it helps the power budget).

    Also, you are using getHeartrateHisory, which itself only changes every minute or two,  The logic you want to use here is first check Activity.getActivityInfo().currentHeartrate, and use that if it's not null.  If it is null, then fall back to getCurrentHeartrateHisory()

    I don't see where you are getting steps.  You need to do that.  Where do you update "info"?

    You really don't want to call onPartialUpdate directly from onUpdate.  Maybe they can share functions but in onUpdate(), you don't need to set clips.  And the only place you need to clear clips in in the start of onUpdate()

    In the sim, things may look like they work, but I'm thinking you're not running in Low Power mode, so onUpdate is called every second.  On the watch, most of the time it's running in low power mode.

    You really don't want to call onPartialUpdate directly from onUpdate.  Maybe they can share functions but in onUpdate(), you don't need to set clips.  And the only place you want to clear clips in in the start of onUpdate()

    Here's a whole thread about doing 1hz:

    https://forums.garmin.com/developer/connect-iq/f/discussion/5156/1hz-watch-faces---q-a

  • Here's how I'd do steps.  In onUpdate() it's called as doExtra(dc,true) and in onPartialUpdate(), doExtra(dc,false).  Notice how everything that can be is pre-calculated (in onLayout actually) as it only needs to be done once.  I save off what's currently displayed (curSteps), and when called by onPartialUpdate(), nothing is done unless what's display had changed.

    In onLayout() there is this:

    exFont=Gfx.FONT_SMALL;
    exHeight=dc.getFontHeight(exFont);
    exY=timeY+timeHeight;
    exW=dc.getTextWidthInPixels("8888888", exFont);	//handle up to 100K with 1 char extra
    exX=centerW-(exW/2);

    And the function.  If the value is updated on the screen from onPartialUpdate(), it's yellow and you'll se the "!" in the cconsole, from onUpdate(), blue. 

    var curSteps=0;    
         function doExtra(dc,isFull) {
         	var steps=ActivityMonitor.getInfo().steps;
         	if(!isFull) {
         		if(steps==curSteps) {return;}
         		Sys.println("!");
      			dc.setClip(exX, exY, exW, exHeight+1);
      			dc.setColor(Gfx.COLOR_BLACK,Gfx.COLOR_BLACK);
      			dc.clear();
      			dc.setColor(Gfx.COLOR_YELLOW,Gfx.COLOR_TRANSPARENT); 
         	} else {
         		dc.setColor(Gfx.COLOR_BLUE,Gfx.COLOR_TRANSPARENT);
         	}
         	curSteps=steps;
         	
         	dc.drawText(centerW,exY,exFont,""+steps,Gfx.TEXT_JUSTIFY_CENTER);
         }

    This gets back to doing as little when onPartialUpdate is involved to help with the power budget.

    In the sim, if you set something like 10 steps a minute, you can see how things work.

  • Jim, thanks a lot for your help. I did everything exactly as you described. This works fine in the simulator, but still doesn't work on my Fenix 5X. Could it be that the problem is precisely in the update that I received a couple of months ago and after that all the information in onPartialUpdate began to be updated once a minute?

  • What's not working?  It could be the actual steps aren't changing the same way on the device.

    Here's similar but with HR (notice the clip region is wider)

         var curSteps=0;
         var curHR=0;
         function doExtra(dc,isFull) {
         	var steps=ActivityMonitor.getInfo().steps;
         	var hr=Activity.getActivityInfo().currentHeartRate;
         	var dHR=hr;
         	if(hr==null) {dHR="--";}
         	if(!isFull) {
         		if(steps==curSteps && hr==curHR) {return;}   		
      			dc.setClip(0, exY-1, width, exHeight+2);
      			dc.setColor(Gfx.COLOR_BLACK,Gfx.COLOR_BLACK);
      			dc.clear();
      			dc.setColor(Gfx.COLOR_YELLOW,Gfx.COLOR_TRANSPARENT); 
         	} else {
         		dc.setColor(Gfx.COLOR_BLUE,Gfx.COLOR_TRANSPARENT);
         	}
         	curSteps=steps;
         	curHR=hr;
         	
         	dc.drawText(centerW,exY,exFont,"s:"+steps+" h:"+dHR,Gfx.TEXT_JUSTIFY_CENTER);
         }

  • I mean, updating steps each seconds is working in the sim. But when I try to get the same on my watch, steps update just once per minute. It's not matter: LowPower Mode or it's just Normal Mode. Watch face doesn't update steps per second. But the color changes into yellow

  • That could be the underlying data is only updating every minute in a WF.  I've honestly never looked at steps  Try it with HR, as generally, on a watch, that will be updating every few seconds.

  • The same result with HR
    I'm getting dissapointed :( 
    I do reckon Garmin made something with the last update for Fenix 5X's firmware and all activity information for watch faces updates only once per minute 

  • (light just went off!)  The f5x is a weird device,  It's got a main processor and a display processor, with some common memory, and the result, is you can't get HR in real time from a WF, and likely steps.  it will work on other devices, except the Approach S60 if I recall, as it's also got a display processor.

  • An interesting feature is that three months ago I remember exactly that I could update the steps in the watch face every second. It worked. But after the 20.00 update, this feature was gone. I am very upset by the fact that now I cannot test the working of the dial on a real device. Maybe I need to look into buying a new model like the Fenix 6X.

  • I also noticed that the heart rate is updated in real time if you go to the watch face settings. While I'm in the watch face selection window, everything is refreshed every second, but as soon as I press the confirmation button the problem comes back.