Category Archives: VB.NET

Pebbles, rectangles and stack overflow

UntitledWhile working on my Pebble watchface “Future Time” I have encountered persistent annoying problem – watchface would run for a while and then crash – and not only crash, but actually restart the watch. What made this even more frustrating – after 3 restarts in a row Pebble would revert to recovery mode and complete firmware reinstall was required (did I accidentally write a Pebble virus?).
When I dug into device logs I found out that every restart was given reason: “Dangerous Stack Overflow”. Which is kinda strange – I don’t have any recursions nor deeply nested function calls nor large local variables. I tried lots of things – including extreme ones like declaring all local function variables as global or static – nothing helped.
Finally Christian form Pebble developers forum shed a light. He pointed out that I use a lot of GRect constructs which is basic rectangle building block for pretty much anything from defining layers to graphics functions. I used GRect inline directly inside function calls, which I thought wasn’t a big deal, after all “everybody does that” – including Pebble in its examples. Well, as Christian pointed out those GRects are kind of local variables, and either memory is not reclaimed fast enough when they go out of scope or they spring memory leak.
Keeping this in mind I created a global GRect variable and when needed to use a GRect in local function, first I’d assign it’s value to the variable and then use variable in the function.
So something like this:

static void layer_update(Layer *layer, GContext *ctx) {
   //...
   graphics_draw_rect(ctx, GRect(10, 10, 30, 30));
   //...
   graphics_draw_bitmap_in_rect(ctx, bitmap, GRect(20, 20, 40, 40));
}

Becomes thus:

GRect temp_rect;

static void layer_update(Layer *layer, GContext *ctx) {
   //...
   temp_rect = GRect(10, 10, 30, 30);
   graphics_draw_rect(ctx, temp_rect);
   //...
   temp_rect = GRect(20, 20, 40, 40);
   graphics_draw_bitmap_in_rect(ctx, bitmap, temp_rect);
}

That’s it. This simple change cured the plague, no more crashes, restarts or recovery – just smooth sailing.

Unblock my heart, i mean, iPhone for Pebble geocoding

Cobblestyle I’ve recently updated code for Cobblestyle Pebble Watchface to take advantage of very cool geocoding service called Nominatim by Open Street Maps.

Nominatim is used in two places: Direct lookup is used in watchface’s config page to lookup coordinates of a place by its name for custom location setting; reverse lookup is used to lookup location name by its coordinates to display name on actual watchface.

It was working fine – on Pebble watches connected to Android phones. It was failing miserably on iOS, so iPhone Pebble users were getting neither location nor weather updates. And it was pretty puzzling for a while until I obtained logs from running watchface thanks to invaluable help from Robin.

Turned out iPhone Pebble app was plain simple blocked by Nominatim service, every attempt to retreive location resulted in message being sent back “You have violated acceptable policy”. Which was kinda surprising since I just started using the service. When I contacted Nominatim support, they told me that apparently some Pebble app running from iPhone abused the service pretty badly, running hundreds of requests per second. And since the only way they can detect requesting app is by it’s User Agent string – all apps spotting iPhone Pebble UA were blocked.

Support suggested to set UA string specific to the app so it could be easily identifiable. Standard approach to set headers on xmlHttpRequest object is .setRequestHeader(..). Unfortunately by many browsers and clients it is considered unsafe to spoof UA via request headers. Fortunately iOS allows that, so all I have to do is catch and ignore erros in other clients. Basically this line of code solved the issue:

try {xhr.setRequestHeader("User-Agent", "Cobblestyle Pebble Watchface");} catch(e){}

Thanks to this as of version 2.19 Cobblestyle watchface correctly displays weather and location information. Yay.

Fire on High or Framebuffer in Rocky.js

First things first. DISCLAMER: Everything described here is a hack upon a crude hack and most likely, barring a divine intervention, won’t work in final product. And I apologize in advance to Pebble dev team if my attempts at “hacking” seem silly. Now to business. Pebble SDK offers very cool framebuffer API that allows developers to address display memory of the watch directly. This makes possible creation of many cool special effects (matter of fact EffectLayer library uses framebuffer extensively).
Rocky.js is JavaScript incarnation of Pebble SDK and it made me wonder whether it offers framebuffer access. Turned out it is hidden, but it’s there. At least at the latest commit at the time of this article it is. If you take a look at source file html-bindings.js you will see that binding function looks something like this:

Rocky.bindCanvas = function(canvas, options) {
  
  //...
   
  var framebufferPixels = new Uint8Array(module.HEAPU8.buffer,
                                         framebufferPixelPTR,
                                         canvasW * canvasH);

  //...

  var binding = {
  
  //...

  }

  //...

  return binding;
};

Continue reading →

Persistent configs in Rocky.js watchfaces

Rocky.JS is the first step in Pebble journey to run JavaScript directly on the watches (unlike Pebble.JS which runs on your phone). Previously I described how to convert a simple watchface from C to Rocky.js. But that was a static watchface with unchangeable settings.

Here I will show how to create a configurable watchface in Rocky.js similarly how classic SDK faces can be configured. You will be able to reuse your existing config page – and if it was set to work with Pebble emulator as well as real watch – you will reuse it without any changes at all.

First let’s review how classic Pebble SDK calls config page. In PKJS (JavaScript) portion of Pebble code usually there’s a piece like this:

Pebble.addEventListener("showConfiguration",
  function(e) {
    Pebble.openURL("http://my.cool.server/pebble/my_cool_config.html");
  }
);

If user requests config of face/app – this event fires and opens page with configurable options from specified URL. After user modifies settings usually “Save” button is clicked on that page and code similar to this executes:

$('#xbtnSave').click(function () {
   var location = (decodeURIComponent(getURLVariable('return_to')) || 
                   "pebblejs://close#") + 
                   encodeURIComponent(JSON.stringify(settings));
   document.location = location;
})

Here, first we determine which location to redirect config page to. If parameter "return_to” is passed in query string (here custom function getURLVariable() is used to extract individual parameters – look it up), so if this parameter is passed – it means config page is called form the emulator and we use it for redirection. Otherwise we use standard "pebblejs://close#" URL to save settings into real watch. We also take settings object which has our collective options combined, convert it to string and add to the URL as a parameter. Page then is redirected to resulting URL and Pebble emulator or real watch takes care of processing parameters.

So, how can we (re)use it in a Rocky.js watchface? Continue reading →

Restore natural picture look on Samsung smart TV

I really like my new smart TV from Samsung it has tons of bells and whistles. But one thing I noticed – no matter what I watch – series or movies, streaming or broadcast – picture has a “teleplay” feeling – like the action is happening on stage in the theater. If you recall what later Twilight Zone episodes look like you’d know what I am talking about. Maybe it’s supposed to look like this, but I like “film” feeling more. So I found a setting that restores natural picture look:

CYMERA_20160202_215011
Go to your TV menu, then select Picture -> Picture Options -> Auto Motion Plus and turn it off.

Fix Roku problem connecting to 802.11ac 5Ghz WiFi

I recently got a Roku 4 – at the time of this post the latest and greatest streaming players from Roku family. It comes with many bells and whistles – including ability to connect to 5Ghz WiFi networks. But for the life of me – it could not connect to mine. Player was seeing the SSID of the network, able to connect to wireless, but chocked on joining to LAN. Extensive chat with support lead nowhere – they wanted me to change WAN DNS and many other hoops that achieved nothing. For the record – my router is a dual-band one, and Roku had no problems connecting to 2.4Ghz band. But Internet speed falls dramatically over 2.4Ghz connection and I needed 5Ghz.

Finally I found one thing that worked.
AC Network
AC connection has 3 bandwidth modes: 20Mhz, 40Mhz, and 80Mhz. My router was set to 80Mhz to take full advantage of 1300 speed. None of my devices had problem with this (including, I might add, my previous Roku 3 player). But apparently Roku 4 couldn’t handle it. But as soon as I switched bandwidth to 40Mhz – boom, instant connection.

Streaming doesn’t suffer from this change, but it does lower LAN speed, so I’d like alternative solution from Roku if possible. Is this a known issue? Would an update fix it?


UPDATE 2016-02-01: Found a better workaround with the help of this awesome device.
Bridge
WUMC710 is a bridge between 4 Gigabit Ethernet connections and full 802.11ac WiFi. And it has no problem with 80Mhz channel. So I basically tell Roku it has a wired connection (and it does to the bridge) and the bridge has beautiful wireless connection to my router. You can grab the WUMC710 pretty cheap (I got mine for $10) and besides not having to slowdown your main network it makes actual Roku internet Speed much faster. Shame Roku’s own WiFi is not on par, but hopefully it will catch on

Fixing problem with Yahoo geolocation service

Recently two Pebble watchfaces I’ve developed based on Paul Joel designes: Clean&Smart and Cobblestyle began to experience weather update issues – as in “weather was not updated at all”. Looking into the issue I found a weird thing: If you set your location manually – weather worked. But automatic weather based on phone location did not.

The way automatic location works is pretty straighforward. First this function is called to determine location:

function getLocation() {
  navigator.geolocation.getCurrentPosition(
    locationSuccess,
    locationError,
    {timeout: 15000, maximumAge: 60000}
  );
}

It uses phone location services (GPS, if its available, otherwise network-based location). In case of success it calls locationSuccess function. And in my tests it always called it, so location was determined successfully. Continue reading →

Solved: Issue with Pebble framebuffer after notification is dismissed

Effect Layer Issue I’ve encountered a weird issue while working with EffectLayer Library (a visual effect library for Pebble smartwatch). In this particular watchface called Clean & Smart I used “invert” effect which inverts colors of the watchface should the user choose that option in settings. It was working fine when option changed when watchface was loaded/unload and behaved weirdly only in one particular scenario: when you would receive a notification (email, text etc.) and then dismiss it. Upon coming back from notification to watchface invert effect would only partially cover the watchface (as seen on the screenshot).
I don’t know exactly what was happening, but had a theory. Continue reading →

How to make your Pebble smartwatch really tick

“Tick tock, goes the clock, And Now what shall we play?”.

Pebble smartwatch is an amazing piece of hardware with no less amazing software to support it. Pebble appstore boasts huge variety of watchfaces from intricately carved art pieces to simplicity personified. And the apps, my gods the apps! You want to track your sleep, count swimming stokes, automate your home – Pebble can do all those things and more. But something was missing. Something that ordinary mechanical clocks could do since the dawn of time.

Tick tock, goes the clock, And then what shall we see?
Continue reading →