We'll assume you've already been through the Bangle.js Development page and have an idea how to get started.
If so you're now connected and can write some simple code - let's have a go at making a timer app.
To do this, it's best to use the right-hand side of the IDE - once uploaded you can tweak values and call functions using the REPL on the left if you want to.
Copy the following code to the right of the IDE and click Upload ():
var counter = 30;
function countDown() {
counter--;
g.clear();
// draw the current counter value
g.drawString(counter, g.getWidth()/2, g.getHeight()/2);
// optional - this keeps the watch LCD lit up
Bangle.setLCDPower(1);
}
var interval = setInterval(countDown, 1000);
You'll now have some tiny text in the middle of the screen, which counts down from 29.
Why is the code formatted like this? Check out the Code Style page for some tips and the reasoning behind it.
First, we'll want to make the text bigger, and properly centered. You have two options here - a bitmap font, or a vector one.
Because we're not resetting the state of the Graphics library with
reset()
every frame, you can now just copy/paste the following
code onto the left-hand side of the IDE.
g.setFontAlign(0,0); // center font
g.setFont("6x8",8); // bitmap font, 8x magnified
You'll now have a bigger, but pixellated, number in the center of the screen.
You can try different numbers (-1/1/0
for setFontAlign
or changing 8
in
setFont
) or can experiment with g.setColor("#00ff7f")
to
change the colour.
When you have it as you want, add the code right after g.clear()
on
the right hand side and re-upload to make it permanent.
If you'd prefer something smooth, you can use the Vector font, 80px high,
by replacing g.setFont("6x8",8)
with g.setFont("Vector",80)
.
Finally, maybe we want to detect when the counter hits zero, display a message, and beep:
var counter = 30;
var counterInterval;
function outOfTime() {
E.showMessage("Out of Time","My Timer");
Bangle.buzz();
Bangle.beep(200, 4000)
.then(() => new Promise(resolve => setTimeout(resolve,200)))
.then(() => Bangle.beep(200, 3000));
// again, 10 secs later
setTimeout(outOfTime, 10000);
}
function countDown() {
counter--;
// Out of time
if (counter<=0) {
clearInterval(counterInterval);
counterInterval = undefined;
outOfTime();
return;
}
g.clear();
g.setFontAlign(0,0); // center font
g.setFont("Vector",80); // vector font, 80px
// draw the current counter value
g.drawString(counter,120,120);
// optional - this keeps the watch LCD lit up
Bangle.setLCDPower(1);
}
counterInterval = setInterval(countDown, 1000);
This will just keep on beeping and buzzing until you reset the watch with a long-press of the button. Let's just make the press of the middle button clear the timer:
if (counterInterval) return;
as the first line in function outOfTime() {
counterInterval = setInterval(countDown, 1000);
with:function startTimer() {
counter = 30;
countDown();
if (!counterInterval)
counterInterval = setInterval(countDown, 1000);
}
startTimer();
To be compatible with both Bangle.js 1 and Bangle.js 2 we need to either
choose which button to use based on the device type (eg by checking
process.env.HWVERSION==2
) or to use a command like Bangle.setUI
that provides an abstraction for both devices.
setWatch(startTimer, (process.env.HWVERSION==2) ? BTN1 : BTN2);
just before the call to outOfTime();
in countDown
.Your code should now look like:
var counter = 30;
var counterInterval;
function outOfTime() {
if (counterInterval) return;
E.showMessage("Out of Time", "My Timer");
Bangle.buzz();
Bangle.beep(200, 4000)
.then(() => new Promise(resolve => setTimeout(resolve,200)))
.then(() => Bangle.beep(200, 3000));
// again, 10 secs later
setTimeout(outOfTime, 10000);
}
function countDown() {
counter--;
// Out of time
if (counter<=0) {
clearInterval(counterInterval);
counterInterval = undefined;
setWatch(startTimer, (process.env.HWVERSION==2) ? BTN1 : BTN2)
outOfTime();
return;
}
g.clear();
g.setFontAlign(0,0); // center font
g.setFont("Vector",80); // vector font, 80px
// draw the current counter value
g.drawString(counter,120,120);
// optional - this keeps the watch LCD lit up
Bangle.setLCDPower(1);
}
function startTimer() {
counter = 30;
countDown();
if (!counterInterval)
counterInterval = setInterval(countDown, 1000);
}
startTimer();
Now we have this, we need to turn it into an app for the watch. To do that we need two basic files on the watch:
info
file describing the app (name/etc) for the launcher.First, come up with a unique ID for your app. Don't use spaces, use lowercase letters, and try and make it reasonably short (under 10 characters is a good idea).
It shouldn't already be listed in https://github.com/espruino/BangleApps/tree/master/apps so that it doesn't interfere with other apps you might install.
We'll use timer
. Now, click the down-arrow below the Upload button,
then choose Storage
, then New File
, and then type timer.app.js
and click Ok
.
Now, click the Upload
button. The app will be uploaded to the watch
and then executed from the file. With this set, you can easily
continue to develop your app as it is on the watch.
Now we have the app, but it won't appear in the launcher because there is no app info file. To fix this, just copy and paste the following into the left-hand side of the IDE.
It'll write the relevant info to the file timer.info
require("Storage").write("timer.info",{
"id":"timer",
"name":"My Timer",
"src":"timer.app.js"
});
If you now long-press BTN3 on Bangle.js 1 (or the single button on Bangle.js 2)
to get to the clock, the press the middle button to get to the menu, you can scroll down and see My Timer
.
If you select it, it'll execute your app!
Note: The Bangle App Loader automatically generated this file - we're just doing it here so you can create an app without requiring the loader.
In the menu, you'd have noticed that there was no icon shown.
To fix this, let's find a 48px icon. Unless you want to create one, we'd suggest using icons8.com as they're free for Open Source projects (we're also paid up just in case).
Timer
into the search boxColor
- this is the style we often use in Bangle.jsSand Timer
or whatever you feel likeDownload
and download the 48px imageNow it's time to convert the image for use in Espruino and upload it. You can use http://www.espruino.com/Image+Converter for this, but the tools are now built into the IDE.
Storage
icon above Upload: Upload a File
timer.img
Convert for Espruino
and Transparency
are checked4 bit Mac Palette
and check the Preview. If the colours aren't good enough, try 8 bit Web Palette
instead.Ok
to uploadNow all you have to do is change the App Info file to reference the icon. Copy and paste this into the left-hand side of the IDE:
require("Storage").write("timer.info",{
"id":"timer",
"name":"My Timer",
"src":"timer.app.js",
"icon":"timer.img"
});
If you open the Launcher now, you'll see the icon!
Note: You can use these images in your app as well. If you want to
draw the timer image, just use g.drawImage(require("Storage").read("timer.img"),x,y)
Ok, so now we've got an app, and we can run it from the launcher.
How about adding it to the Bangle.js App Loader? Check out Adding an app to the Bangle.js App Loader
Or maybe you want to make a clock face
This page is auto-generated from GitHub. If you see any mistakes or have suggestions, please let us know.