Fenix 3 HR White Watch Screen erro

Former Member
Former Member
Good evening,

I have been playing around with some new watch face designs and when uploading the watchface to the actual device, it shows a blank, white screen. However, the watchface simulates just fine on Eclipse on the computer simulator. I'm fairly new to coding with the Garmin SDK but not new to coding in general. Any insight or ideas as to whats causing this would be much appreciated!

Regards,

Nash
  • The problem is most likely that you are not filling the background.

    If you are not using layouts, the first draw operation you want to do would be something like this...

    function onUpdate(dc) {
    dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_BLACK);
    dc.clear();

    // draw your foreground stuff
    // dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT);
    // dc.drawText(...);
    }


    If you are using layouts, you need to ensure the background is drawn, either with a background drawable or by explicitly drawing the background...

    function onUpdate(dc) {
    dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_BLACK);
    dc.clear();

    // this may not work...
    View.onUpdate(dc);

    // if it doesn't, this will...
    //for (var i = 0; i < mLayout.size(); ++i) {
    // mLayout.draw(dc);
    //}
    }
    [/code]

    Travis
  • Former Member
    Former Member over 9 years ago
    Travis-

    I have gotten it down to this code that is causing the error. Whenever this is excluded from the build, the watchface works great. When included, it throws a white screen error.

    Code:
    using Toybox.Math as Math;
    using Toybox.ActivityMonitor as AM;

    ...//

    var activity = AM.getInfo();
    var percentage;

    ...//
    percentage = activity.steps/activity.stepGoal;
    percentage = percentage * 100;
    percentage = Math.round(percentage);
    End of Code

    Am I just having a lapse in skill here or am I missing something?

    Thanks for the quick response.
  • Wait a second. Is it an error with a IQ icon, or is it just a white screen? If it is an IQ error, you probably need to check the values in activity are not null before you use them.

    var percentage = 0;

    if (activity.steps != null && activity.stepGoal != null) {

    // might want to check stepGoal != 0 before dividing
    percentage = activity.steps/activity.stepGoal;
    percentage = percentage * 100;
    percentage = Math.round(percentage);
    }


    Otherwise, I'm still betting that you're not clearing the screen with the background color before drawing your visual elements. If you send me your onUpdate() function, I can probably help.

    Travis
  • Former Member
    Former Member over 9 years ago
    Travis-

    Please see below code. If the lines commented as -1-, -2-, or -3- are included in the file, the screen literally shows the correct image for about one clock cycle, then turns to white. As if you were drawing a white circle on the screen. By excluding all of those lines, the watch face looks like it should and keeps time etc etc. I'm just attempting to get a whole number value between 0 and 100 for the percentage based on number of steps taken and the set goal.. shouldn't be that hard, right? I added what you suggested and have the following:

    function onUpdate(dc) {

    dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_BLACK);
    dc.clear();

    dc.drawBitmap(0, 0, background); //background BMP file


    var percentage = 0;
    var activity = AM.getInfo();
    if (activity.steps != null && activity.stepGoal != null) {
    // might want to check stepGoal != 0 before dividing
    if(activity.stepGoal > 0) {
    percentage = activity.steps/activity.stepGoal;
    }
    else {
    percentage = 0;
    }
    percentage = percentage * 100;
    percentage = Math.round(percentage); // -1-
    }


    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);
    dc.drawText(150,150,Gfx.FONT_TINY,percentage,Gfx.TEXT_JUSTIFY_CENTER); // -2-
    dc.drawText(150,180,Gfx.FONT_TINY,activity.stepGoal,Gfx.TEXT_JUSTIFY_CENTER); // -3-

    //everything below here is independent of the above functions and variables

    //.....

    }



    Thanks again,

    Nash
  • It might be the same problem I encountered: you can't write a number with drawText. The simulator accepts it, the watch itself does not, you have to convert it to a string first. Use something like percentage + "", or better percentage.format('...')


    Nasty bug.
  • Former Member
    Former Member over 9 years ago
    on line "-1-", I think your problem might be that Math.round was very recently added to the API, and the Fenix 3 HR is unlikely to have updated to the VM that supports it yet.

    The other 2 lines, I am guessing Harry is correct.

    When watchfaces crash, they should revert to one of the built in faces, but I do remember the Fenix 3 ending up at the white screen you describe int he past. You might also want to make sure you have the latest firmware installed on your Fenix 3 HR.
  • I think everyone except me was right... I'm posting your code with some comments below.

    function onUpdate(dc) {

    // I suggested you add this, but it may not be necessary. If the background
    // bitmap is full screen and has no transparency, you can remove these two
    // lines.
    dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_BLACK);
    dc.clear();

    dc.drawBitmap(0, 0, background);

    // Check that activity tracking is on before drawing the activity tracking
    // stats.

    var deviceSettings = Sys.getDeviceSettings();
    if (deviceSettings.activityTrackingOn) {

    var activity = ActivityMonitor.getInfo();

    var steps = activity.steps;
    var stepGoal = activiity.stepGoal;

    // We know activity tracking is on, so neither of these should be null.
    // I'm leaving the null/zero checks commented out, but you can probably
    // remove them entirely.

    //if (steps == null) {
    // steps = 0;
    //}

    //if (stepGoal == null || stepGoal == 0) {
    // stepGoal = 1;
    //}

    // Both steps and stepGoal are of type Number, which means you are doing
    // integer division. The result will be rounded to the nearest whole. If
    // you pre-multiply by a floating point value, you'll get a Float back.
    // i.e., 1500 / 3000 = 0, but 1.0 * 1500 / 3000 = 0.5.

    var percentage = 100.0 * steps / stepGoal;

    // As pointed out by Brian, you might not be able to use Math.round()
    // on all device firmware yet. You have two options. You can round
    // manually all of the time, or you can check for it and fall back.

    //if (Math has :round) {
    // percentage = Math.round(percentage);
    //}
    //else {
    percentage = (percentage + 0.5).toNumber();
    //}

    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);

    // As pointed out by HarryOnline, you have to pass strings to drawText.
    // At this point, both values are of type Number, so you don't need to
    // use `format', you can simply get the string representation.

    dc.drawText(150, 150, Gfx.FONT_TINY, percentage.toString(), Gfx.TEXT_JUSTIFY_CENTER);
    dc.drawText(150, 180, Gfx.FONT_TINY, stepGoal.toString(), Gfx.TEXT_JUSTIFY_CENTER);
    }
    }
  • Former Member
    Former Member over 9 years ago
    Got it working!

    The code that does it is below. The activity.steps a whole number integer and so to make it a double (in order to work for division), I just multiplied it by 1.00. At least that is my theory. The division of steps/goal is broken down into a few lines for simplification, but it could obviously be written in one line. The Math.round() is causing the white screen on the fenix 3, I'm going to try updating everything and seeing if it supports it. For right now, I've just left it out.

    I also went with printing the numbers.toString(). When HarryOnline mentioned it, I remembered that tidbit of information.

    Thanks for all the help guys!

    function onUpdate(dc) {

    dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_BLACK);
    dc.clear();

    dc.drawBitmap(0, 0, background); //background BMP file


    var percentage = 0.00;
    var activity = AM.getInfo();

    if(activity.stepGoal > 0) {
    percentage = activity.steps;
    percentage = percentage * 1.00; //multiply by 1.00 to get trailing decimal values
    percentage = percentage/activity.stepGoal;
    }
    else {
    percentage = 0;
    }
    percentage = percentage * 100;


    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);
    dc.drawText(150,150,Gfx.FONT_TINY,percentage.toString(),Gfx.TEXT_JUSTIFY_CENTER); //
    dc.drawText(150,180,Gfx.FONT_TINY,activity.stepGoal.toString(),Gfx.TEXT_JUSTIFY_CENTER); //
    }
  • Here's now I do the percent thing... I've never seen stepGoal be 0 (I check that activityTracking is on before this), so no divide problem.

    value=((activityInfo.steps*100)/activityInfo.stepGoal).format("%d");
  • Just to be clear, Jim's code will round down. 14999 steps out of 15000 would give value="99". If the proposed rounding was used you would get value="100" for 14925 of 15000 steps, and that seems wrong.

    Travis