Anyone else been checking out the new features in the 2.3.0.beta1 SDK?

I've been checking out a few:

  • the "Always active" watchfaces (kind of a marketing term, as users have been able to see a watchface at any time on garmins, and really a "1hz update with watchfaces" so always on seconds, and 1 hz update of other things on the display!)
  • The whole background process part (WAY cool!)
  • The debugger ("lions, and tigers, and breakpoints, oh my!" - Hey, Garmin is in Kansas! :) )


Initial reaction:

  • 1hz - Once you learn the technique, doing seconds on a digital WF is fairly straightforward. When to clip, and when to clear the clip!. Analog watch faces with a second hand, a bit more is involved, but the Analog sample in the SDK shows you how... The thing to note here, is while a WF can update parts of the screen at 1hz, the underlying data is still changing at the same rate as before, For example,if you update the HR on the watchface at 1hz, it doesn't change that getHeartRateHisory() still will only changed every minute or two.
  • background processes are VERY COOL. No more details on what I'm trying so I can publish my apps first! :)
  • Debugger - still a bit green IMHO, but this is a beta and garmin is looking for feedback. I have used it a number of times to set a breakpoint and check out what's in certain variables, and avoid the Sys.println() that never seem to be commented out when building for the store!
  • Did you check out the Finite Impulse Response (FIR) and Infinite Impulse Response (IIR)? Any idea what it's all about?
  • Nope, not looked at that at all.
  • I wanted to check it out, but kinda blocked by the blue triangle issue to really get into using it...
  • 1hx watchfaces and a few tips (in parts)

    The forum is acting up, so this will be ain a few posts...

    I did a bug report about the delegate used when onPartialUpdate() passes it's power budget in the Analog Sample. Just something you can easily change and use in your own code here. The sample doesn't exceed the budget, so might not have been noticed)

    If you just starting with this feature, having the delegate is useful so you can see when you exceed the max (and by how much), and your watchface can adjust. There are a few things you'll see in the Analog sample to look at as far as some difference the watchface may want to do based on if onPartialUpdate() is available. (or if the budget is exceeded)
  • next...

    After that, the two key things are dc.clearClip() and dc.setClip(), as that controls what part of the screen will be updated. For example, in onUpdate(), I start with a clearClip() and can change the entire screen, while if I do something driven by onPartialUpdate(), setClip() to define exactly the area I'll be changing (not having the setClip() is a way you'll probably exceed the budget within minutes). The budget is the average time a call to onPartialUpdate() can takes over 1 minute, and the max is 30 milliseconds (it's all about the battery! :) )

    You want to watch how large an area you define with setClip(), as well as how many different clip areas you use.

    To help with the budget, a couple of things you can do. For one, you can only update things in onPartialUpdate() when they change. With seconds, that's every second, so not so much you can do there, but in the case of something like heartrate (from getHeartRateHistory()), there's really no point in updating the screen every second, as the underlying data only changes every 1-2 minutes, so you can really help the average for the budget by only doing 1 update every 90 seconds or so, vs 90 every 90 seconds. Also, for data that changes faster, maybe only update the screen every other time.
  • last...

    As far as "how much can you do?", I have a watch face that updates seconds, steps, the move bar and the icons and runs fine, as well as another that does seconds, hr, and steps, and I feel I add more if it comes up. (BTW, steps are another thing that actually don't change every second, so I use "only when it changes" for them too, and same with the icons and the moverbar). You do want to be very careful about what you do in general. I hear that trying to load resources is something to avoid at all costs, for example!

    A last tip, is that for testing, you may want to set things to a different color when they change based on onPartialUpdate(), as that way you can see where the change comes from (see the times that onUpdate() is called when not in low power mode at 1hz vs when it comes from OnPartialUpdate() at 1hz).
  • Another neat thing I've been checking out is the new background processes (f5 family and 935), where a watchface for example, can go out and get data off the internet that can be displayed on the watch face! In this case, I get weather data every 15 minutes.



    The tricky thing here is background processes have limited memory (I believe it's 32k, but possible lower), and often the data you get is a bit complex, so you could have a bit of a memory problem. Also, with the whole "HTTPS only" bit Apple is kind of forcing with iPhones, the simulator now gives you and error if you use http, so smaller data and https are a good guidelines!

    Next test, a background process for a widget!
  • Did you check out the Finite Impulse Response (FIR) and Infinite Impulse Response (IIR)? Any idea what it's all about?


    These are general signal filters. You can make a high- or low-pass filter with these. You can also combine them to make a band-pass or notch filter.
    This is great for accelerometer data -- you can filter the signal and leave for example only the frequency range that corresponds to walking frequency, or toothbrushing frequency (the rate at which you expect the user will be swooshing their tooth :))
    You can also filter out any spikes in the signal (using low-pass filter).

    This will save you a lot of math and enable you to detect complex motion gestures and especially specific periodic motion.

    The only challenge is to find out the correct coefficients for the filters.
    For FIR, here is a nice app to calculate them: [HTML]www.arc.id.au/.../HTML]
    For IIR, I could not find anything simple, so if you find anything, please post...
  • Former Member
    Former Member over 8 years ago
    I've been checking out a few:
    • 1hz - Analog watch faces with a second hand, a bit more is involved, but the Analog sample in the SDK shows you how...

    I've studied the Analog example a bit as I plan to add second hands to my analog watch faces.
    But as soon as I try to modify the example to use one of the system fonts instead of the custom one in the example the watchface crashes with an exception.

    I haven't had time to look into it in detail, but do you know of any obvious reason this happens?

    -Torstein
  • Former Member
    Former Member over 8 years ago
    I've studied the Analog example a bit as I plan to add second hands to my analog watch faces.
    But as soon as I try to modify the example to use one of the system fonts instead of the custom one in the example the watchface crashes with an exception.

    I haven't had time to look into it in detail, but do you know of any obvious reason this happens?

    -Torstein


    The custom font in the example is drawn into a offscreen BufferedBitmap that has a limited color set applied to it to save memory. If you look at the updated documentation for Dc.drawText(), you will see that it throws the InvalidPaletteException if you attempt to use an anti-aliased font with a paletted bitmap. The system fonts for most devices are anti-aliased fonts and won't work in this context.

    To change the font used to draw the 3/6/9/12 in the sample, you would have to remove the code that draws them into the offscreen BufferedBitmap. You could create small buffers to hold each of these draws, or you could just draw them directly to the screen at the end of the update because the analog hands don't pass over them, and they don't actually need to be in there in the first place.