-
Whatver the js3 turns out to be, you can count on my pledge!
The Js2 does everything I could want... except light up with vibrant color like the js1...
And for those citing power draing, my js2 kept it's charge over a week at a time for the first month, after that it needed to be charged every day and a half, which doesn't make up for the supposed power drain of the LED js1 screen, so I'd rather have that brilliant color light display.I'd like a big round watch like js1 (feels more classic than the square pebbly things) although I'd like the screen to fill up the watch face fully. That could mean a bigger screen within the large watchface, or a smaller watch to match the screen, either way is fine.
I don't care much about waterproofing or touchscreen. I'd be more than willing to scrap the touchscreen in favor of more buttons.
The main thing I'd like to see is improved processing/RAM/draw speed.
The limitations of both the js1 in terms of bandwidth, and the js2 in terms of resolution and color depth, are a fun part of the project, forcing creativity on our part. I can say that I will for sure sign up for js3 on day 1!
-
-
Oh, good to know about that last manual conversion/upload thing. And I actually haven't had a chance to test any of this on the physical js1 yet since I can't seem to find the charging cable.
I did move all the hands to base64, but yeah the larger face images in base64 crashed the emulation.
So for the larger images, if I declare them as global variables outside of the function, would I be better off declaring that variable as
var image = require("Storage").read("image.img");
orvar image = atob("FrrCAP//Gq657wAA...AAAAA==")
or does it matter at that point since either way it's in RAM?Or is it in RAM? We had previously discussed elsewhere that
"if you store the background image as a file (uncompressed), drawImage
can draw that file directly without ever loading it into RAM"Does that hold true for the global variables?
-
-
Thanks for the quick reply.
Yes, it should read 133. I typed 1333 by accident when manually replacing my variable value to simplify things for this thread.
I'll attach a picture of the results of
g.drawImage(require("Storage").read("MinĀHand.png"),0,0);
it is off to the left of the screen now, still looks weird.And here is the base64:
atob("FrrCAP//Gq657wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVQAAAAVVVQAAAVVVVAAAFVVVQAAFVVVVAABVVVVQAAVVVVUAAFVVVVAABVVVVQAAVVVVUAABVVVUAAAVVVVAAABVVVAAAABVUAAAAAFUAAAAABVAAAAAAVQAAAAAFUAAAABVVVAAAAVVVQAAAVVVVAAAFpBpQAABqQakAAAakGpAAAGpBqQAABqQakAAAakGpAAAGpBqQAABqQakAAAaUFpAAAGlBaQAABpAGkAABaQBpQAAWkAaUAAGpAGpAABqQBqQAAakAakAAGpAGpAABqQBqQAAakAakAAGpAGpAABpQBaQAAaUAWkAAGlAFpAAFpQBaUABaQAGlAAakABqQAGpAAakABqQAGpAAakABqQAGpAAakABqQAGpAAakABqQAGlAAWkABpQAFpABaUABaUAWlAAWlAFpQAFpQBqQAAakAakAAGpAGpAABqQBqQAAakAakAAGpAGpAABqQBqQAAakAaUAAFpAGlAABaQFpQAAWlBaUAAFpQWlAABaUGpQAAWpBqQAABqQakAAAakGpAAAGpBqQAABqQakAAAakGpAAAGpBpQAABaQaUAAAWkWlVVVVpVVVVVVVVVVVVVVVVaqqqqVRWqqqqlQVaqqqlUBWqqqpUAFaqqpUABWqqqVAAFaqqVAABVqqVQAAFaqlQAAAVqlQAAAFapUAAAAVpUAAAAFaVAAAAAVVAAAAABVAAAAAAVQAAAAABQAAAAAAUAAA")
-
I've been very thorough and I can't figure out what's going on here.
The picture on the left shows my image (the minute hand of the clock) as it should look, the one on the right shows how it's coming out in the emulator. My second and hour hands are working fine, but for whatever reason, the minute hand image just looks crazy! All three images were created from the same photoshop file, using two colors plus transparency, and I've tried saving with every possible option and file type that supports transparency. For all three I used the "optimal 2 bit" option in the uploader, with transparency on. I can't figure out why the other two work just fine but not this one.g.drawImage(require("Storage").read("MinHand.png"),120,1333,{scale:1,rotate:0});
-
This is all through Android, I've never actually figured out how to connect via a computer. Windows 7 and 10 I just can't get either jswatch to show up at all. In Linux I can get my computer's bluetooth to pair with the js2, but can't get the app loader or web ide to find the watch, paired or unpaired with the computer bluetooth.
Actually, I've been hoping to get that figured out as well, to make it easier to type in notepad++ and not have to send a file to my phone to test through the ide there, but maybe that's another issue for another thread. I was working on trying to get the connection going through Linux a bit more today, but for now I'm gonna call it a night, and will try more things over the weekend.
-
Picking up the JS2 again after a couple busy months, I was immediately notified to upgrade my firmware via the Firmware Update app.
It simply won't work. It just stops around 20%.
I did a factory reset, and tried again, but that didn't help.
I tried to use the old firmware update method via the DFU app, and tried again, but that didn't help.
I set the screen timeout to zero, and used the coffee app to keep my phone screen from going to sleep, and tried again, but that didn't help.
I'm out of ideas, anyone else overcome a similar issue? -
Oh riiight, that's what Gordon was saying about the uncompressed files... If they were compressed it would require RAM to decompress and present them via heatshrink. I'm reminded of how illustrator files are smaller on disk because they're a collection of vectors, but can get pretty heavy when open because of having to be interpreted by gpu in real time, whereas a photoshop file that's larger on disk might run more quickly. So much to learn... Banglejs is a great intro to javascript for me, there's nothing better than a practical application!
-
-
Okay.... here's what I have:
const xc=88, yc=88; var twoPi = 2*Math.PI; var Pi = Math.PI; var halfPi = Math.PI/2; //daylight_images var faceDaylight = require("Storage").read("FaceDaylight.gif"); var hourHandDay = require("Storage").read("HourHandDay.gif"); var minHandDay = require("Storage").read("MinHandDay.gif"); var secHandDay = require("Storage").read("SecHandDay.gif"); //nightglow_images var faceGlow = require("Storage").read("FaceGlow.gif"); var hourHandGlow = require("Storage").read("HourHandGlow.gif"); var minHandGlow = require("Storage").read("MinHandGlow.gif"); var secHandGlow = require("Storage").read("SecHandGlow.gif"); // var drawTimeout; function daylight() { var d = new Date(); var h = d.getHours() % 12 || 12; var HoursAngle = (d.getHours()+(d.getMinutes()/60))/12 * twoPi - Pi; var MinutesAngle = (d.getMinutes()/60) * twoPi - Pi; var SecondsAngle = (d.getSeconds()/60+d.getMilliseconds()/60000) * twoPi - Pi; g.reset(); g.clear(); g.drawImage(faceDaylight); //DateWindow g.setFont("6x8"); g.setFontAlign(0,0); g.setColor(0,0,0); g.drawString(d.toISOString().substr(8,2), 138, 88, 0); g.drawString(d.toISOString().substr(8,2), 139, 88, 0); g.drawImage(hourHandDay,xc,yc,{scale:1,rotate:HoursAngle}); g.drawImage(minHandDay,xc,yc,{scale:1,rotate:MinutesAngle}); g.drawImage(secHandDay,xc,yc,{scale:1,rotate:SecondsAngle}); queueDraw(); } function nightglow() { var d = new Date(); var h = d.getHours() % 12 || 12; var HoursAngle = (d.getHours()+(d.getMinutes()/60))/12 * twoPi - Pi; var MinutesAngle = (d.getMinutes()/60) * twoPi - Pi; var SecondsAngle = (d.getSeconds()/60+d.getMilliseconds()/60000) * twoPi - Pi; g.reset(); g.clear(); g.drawImage(faceGlow); g.drawImage(hourHandGlow,xc,yc,{scale:1,rotate:HoursAngle}); g.drawImage(minHandGlow,xc,yc,{scale:1,rotate:MinutesAngle}); g.drawImage(secHandGlow,xc,yc,{scale:1,rotate:SecondsAngle}); queueDraw(); } function draw(){ if(Bangle.isLocked()){ daylight(); } else { nightglow(); } } function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(() => { drawTimeout = undefined; draw(); }, 250 - (Date.now() % 250)); } Bangle.on('lock', on => { draw(); }); draw();
Still getting the tiniest delay, though I think it is better than it was.
-
-
-
-
-
-
-
Of course! Here is my entire code:
const xc=88, yc=88; var twoPi = 2*Math.PI; var Pi = Math.PI; var halfPi = Math.PI/2; function daylight() { var d = new Date(); var h = d.getHours() % 12 || 12; //var time = (""+h).substr(-2) + ":" + ("0"+m).substr(-2); var HoursAngle = (d.getHours()+(d.getMinutes()/60))/12 * twoPi - Pi; var MinutesAngle = (d.getMinutes()/60) * twoPi - Pi; //var SecondsAngle = (d.getSeconds()/60) * twoPi - Pi; var SecondsAngle = (d.getSeconds()/60+d.getMilliseconds()/60000) * twoPi - Pi; g.reset(); g.clear(); g.drawImage(require("Storage").read("FaceDaylight.gif")); //DateWindow g.setFont("6x8"); g.setFontAlign(0,0); g.setColor(0,0,0); g.drawString(d.toISOString().substr(8,2), 138, 88, 0); g.drawString(d.toISOString().substr(8,2), 139, 88, 0); g.drawImage(require("Storage").read("HourHandDay.gif"),xc,yc,{scale:1,rotate:HoursAngle}); g.drawImage(require("Storage").read("MinHandDay.gif"),xc,yc,{scale:1,rotate:MinutesAngle}); g.drawImage(require("Storage").read("SecHandDay.gif"),xc,yc,{scale:1,rotate:SecondsAngle}); queueDraw(); } function nightglow() { var d = new Date(); var h = d.getHours() % 12 || 12, m = d.getMinutes(), yyyy = d.getFullYear(), mm = d.getMonth(), dd = d.getDate(); //var time = (""+h).substr(-2) + ":" + ("0"+m).substr(-2); var HoursAngle = (d.getHours()+(d.getMinutes()/60))/12 * twoPi - Pi; var MinutesAngle = (d.getMinutes()/60) * twoPi - Pi; //var SecondsAngle = (d.getSeconds()/60) * twoPi - Pi; var SecondsAngle = (d.getSeconds()/60+d.getMilliseconds()/60000) * twoPi - Pi; g.reset(); g.clear(); g.drawImage(require("Storage").read("FaceGlow.gif")); //DateWindow g.setFont("6x8"); g.setFontAlign(0,0); g.setColor(0,0,0); g.drawString(dd, 137, 88, 0); g.drawString(dd, 138, 88, 0); g.drawImage(require("Storage").read("HourHandGlow.gif"),xc,yc,{scale:1,rotate:HoursAngle}); g.drawImage(require("Storage").read("MinHandGlow.gif"),xc,yc,{scale:1,rotate:MinutesAngle}); g.drawImage(require("Storage").read("SecHandGlow.gif"),xc,yc,{scale:1,rotate:SecondsAngle}); queueDraw(); } function draw(){ if(Bangle.isLocked()){ daylight(); } else { nightglow(); } } var drawTimeout; function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(() => { drawTimeout = undefined; draw(); }, 250 - (Date.now() % 250)); } Bangle.on('lock', on => { setTimeout(0); draw(); }); draw();
-
Ah, ok I see now where I went wrong. I misunderstood that Gordon's code was meant to be placed in the main draw function, I was confused whether it was meant to replace of part of yours, malaire. One thing I don't fully understand is why we need
Bangle.on('lock', on => { draw(); });
if we're going to call the draw function right afterward anyway.
I tried removing the former, and it seems to work just the same.Anyway, here's what I have now:
function draw(){ if(Bangle.isLocked()){ daylight(); } else { nightglow(); } } var drawTimeout; function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(() => { drawTimeout = undefined; draw(); }, 250 - (Date.now() % 250)); } Bangle.on('lock', on => { draw(); }); draw();
Calling queuedraw() at the end of the draw() function resulted in a frozen clock face, so I moved it to the end of my dalight() and nightglow() functions and that got it ticking again. Hopefully I didn't miss anything else and have implemented everything correctly. I'm still seeing the lag when changing images, so perhaps I'll rethink using the lock as the method of changing modes. Either way, I'm learning a lot.
-
Thanks, I did upload them through the IDE, and since they're showing up, I'm assuming that's the uncompressed format, even though my code is still calling for glowface.gif and so on?
Here's what I'm working on for that end segment:
var drawTimeout; function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(() => { drawTimeout = undefined; if(Bangle.isLocked()){ daylight(); } else { nightglow(); } }, 250 - (Date.now() % 250)); } queueDraw(); Bangle.on('lock', on => { daylight(); }); Bangle.on('lock', off => { nightglow(); });
So my goal was to do a face that switches to a "glow in the dark" theme when the screen is unlocked, and back to a daylight theme when locked. I'm still seeing about a half second delay between switching modes, so when I'm in the dark and unlock the screen, I see the daylight style before the glow theme kicks in, which I'd like to eliminate if possible.
Also I'm trying out a second hand that actually moves every quarter second in smaller increments, just for cosmetic effect really. It's working fine, but I'm wondering what the ramifications of the more frequent refresh rate would be in terms of power usage, RAM, and wear on the LCD and processor.
-
Great ideas, thanks for the tips folks!
@Gordon that did answer my question about choosing two separate draw functions, and good to know more about how the background image files load. Is there a preferred file type? Gif? Png? -
I did a test using the first method, and it works, although it waits until the setInterval rate, so the backlight comes on, but it takes up to a second to switch to the other face. I'll have to figure out how to have the change in lock/unlock state trigger an immediate reset of the interval so the change is instantaneous.
-
As per the title, I'm working on a clock that has different color schemes based on whether the bangle.js2 is locked or unlocked. I'll be drawing strings, filled polygons, and circles, as well as loading a background image from heatshrink, all depending on lock state.
For the sake of best practices, ram usage, etc. I'm wondering if I should have two different conditions within the same function, and using
if(Bangle.isLocked())
within that function to decide at each updateinterval what background image to load, FG and BG colors, and what to draw... or should I have two separate functions that are called/killed depending on state? If the latter, how do I kill a function that is currently running? -
I was thinking about trying something like that, I think that means I can't call g.clear(); to clear the second hand, for example. I suppose I can redraw the previous second's second hand in the background color just to cover it up, before drawing the new one in the foreground color. Of course if I consider sacrificing the second hand, I can set the clearInterval to 60000, which is as long as the screen will stay on anyway, so the user won't ever see the flicker.
Btw, I also tried loading a 3bit image of my watch face, something I hadn't tried because I figured it would be even slower. It was. It took much longer to draw the image. Still under a second, but much more noticable flicker, with a slight rolling wipe from top to bottom.
Ok I got the DFU method to work, apparently I didn't have the watch in the right mode the first time.