Bangle.js is an open, hackable smartwatch
Bangle.js 1 is no longer for sale, however you can now purchase the much improved Bangle.js 2!
You can easily install new apps from the web or develop your own using JavaScript or a graphical programming language (Blockly). All you need is a Web Browser (Chrome, Edge or Opera) and you can upload apps or write code to run on your watch wirelessly! Bangle.js is waterproof and AI enabled and comes with Bluetooth Low Energy, GPS, a heart rate monitor, accelerometer and more.
Just got your Bangle.js? Check out The Bangle.js 'Getting Started' page
This means that when idle (in the normal power-on state) you can expect around 30-90 days of battery life depending on whether Bangle.js is moved or not.
Note: These figures are based on the latest Bangle.js firmware. Earlier firmwares have slightly higher power consumption figures.
The supplied charge cable connects to a USB port to charge Bangle.js (there is no data connection, it is power only).
You must connect the cable the right way around or it won't work: With Bangle.js
facing away from you (so you're looking at the shiny back) and the CE Rohs
text
the right way up, the USB cable should exit from the left side of the watch.
The cable is magnetic and the wires are connected directly to USB power. Do not leave your cable plugged in or it might attract itself to the nearest magnetic (probably conductive) object and short out.
BTN2
when at the watch faceBTN3
until you get to Settings
BTN2
to selectBTN3
to Turn Off
BTN2
to select itThis method uses Bangle.js's bootloader to turn off as a last resort. However, the bootloader is not as good at entering a low power state as the Espruino firmware, and so the battery may drain faster than if you could use the main Bangle.js 'off' functionality.
BTN1
+ BTN2
for about 6 seconds until the screen goes blank====
goes across the screenBTN1
+ BTN2
for about 6 seconds until the screen goes blankIf you release the buttons too late you'll enter bootloader mode, in
which case you need to press BTN1
to exit.
If you uploaded some code that runs at startup and breaks Bangle.js you may need to do this.
It won’t delete anything, so unless you fix/remove the broken code (see "Deleting all Code") Bangle.js will remain broken next time it restarts.
BTN1
+ BTN2
for about 6 seconds until the screen goes blankBTN2
but keep pressing BTN1
while ====
goes across the screenBTN1
while Bangle.js bootsNote: In the 2v05 version shipped with Bangle.js KickStarter devices, Bangle.js would still load some parts of the bootloader. If you had turned off Bluetooth in Settings and then broke your Bangle's firmware you would be unable to connect in order to correct the problem. If this happens, install the latest firmware and follow these steps again, and you will then be able to connect.
You can do this either while your watch is connectable, or if you have reset it without loading any code (above).
More... -> Install default apps
This will erase everything and install just the default apps.
More... -> Remove All Apps
Bootloader
and a Clock
from Library
App Manager
app is installed, you can delete apps using the App Manager
Connect
. Under My Apps
your installed apps are listed, and you can click the 'Bin' icon next to them to remove themTutorials using Bangle.js:
Tutorials using Bluetooth LE:
Tutorials using Bluetooth LE and functionality that may not be part of Bangle.js:
There are many more tutorials that may not be specifically for you device but will probably work with some tweaking. Try searching to find what you want.
Certifications:
Bangle.js displays the REPL (JavaScript console) if Debug Info: show
has
been set in settings. If enabled, any calls like print("Hello")
or console.log("World")
will output
to the LCD when there is no computer connected via Bluetooth. Any errors generated when there is no
connection will also be displayed on the LCD.
You can output graphics on Bangle.js's display via the global variable g
that is an instance of the Graphics class. By default the display
is unbuffered, so any changes will take effect immediately.
// Draw a pattern with lines
g.clear();
for (i=0;i<64;i+=7.9) g.drawLine(0,i,i,63);
g.drawString("Hello World",30,30);
Bangle'js's screen is 240 x 240 x 16 bits - which uses substantially more
memory than the microcontroller has RAM. As such, draw commands go straight
to the screen (and g.getPixel
will not work).
Drawing straight to the screen can cause flicker, so for applications that
need to update the screen constantly we'd suggest using Bangle.setLCDMode(...)
to set the screen to a buffered mode. In a buffered mode, draw commands will not
be visible until you call g.flip()
.
Available options for Bangle.setLCDMode
are:
Bangle.setLCDMode("doublebuffered")
- The drawable area is 240x160 16 bit, terminal and vertical scrolling will not work.Bangle.setLCDMode("120x120")
- The drawable area is 120x120 8 bit, g.getPixel
and full scrolling work.Bangle.setLCDMode("80x80")
- The drawable area is 80x80 8 bit, g.getPixel
and full scrolling work.You can also call Bangle.setLCDMode()
to return to normal, unbuffered mode.
Bangle.js comes with a built-in menu library that can be accessed with the E.showMenu()
command.
E.showPrompt()
and E.showMessage()
can also be used for simple
prompts and full-screen messages.
// Two variables to update
var boolean = false;
var number = 50;
// First menu
var mainmenu = {
"" : {
"title" : "-- Main Menu --"
},
"Beep" : function() { Bangle.beep(); },
"Buzz" : function() { Bangle.buzz(); },
"Submenu" : function() { E.showMenu(submenu); },
"A Boolean" : {
value : boolean,
format : v => v?"On":"Off",
onchange : v => { boolean=v; }
},
"A Number" : {
value : number,
min:0,max:100,step:10,
onchange : v => { number=v; }
},
"Exit" : function() { E.showMenu(); },
};
// Submenu
var submenu = {
"" : {
"title" : "-- SubMenu --"
},
"One" : undefined, // do nothing
"Two" : undefined, // do nothing
"< Back" : function() { E.showMenu(mainmenu); },
};
// Actually display the menu
E.showMenu(mainmenu);
See http://www.espruino.com/graphical_menu for more detailed information.
Bangle.js's LCD acts as a VT100 Terminal. To write text to the LCD regardless of
connection state you can use Terminal.println("your text")
. Scrolling
and simple VT100 control characters will be honoured.
You can even move the JavaScript console (REPL) to the LCD while connected via Bluetooth, and use your bluetooth connection as a simple keyboard using the following commands:
Bluetooth.on("data",d=>Terminal.inject(d));
Terminal.setConsole();
Most peripherals on the device are accessible via fields and events on the Bangle object.
There are no LEDs on Bangle.js. There are two 'fake' LED variables called
LED1
and LED2
that create red and green fake LEDs at the top of the watch
screen - these serve no purpose other than to allow tutorials for existing
Espruino boards to be used.
Bangle.buzz()
will make Bangle.js's vibration motor turn on. It takes optional
time and strength arguments, and returns a promise. See the reference.
For example:
Bangle.buzz().then(()=>{
return new Promise(resolve=>setTimeout(resolve,500)); // wait 500ms
}).then(()=>{
return Bangle.buzz(1000);
}).then(()=>{
console.log("Done");
});
Will do a short buzz followed by a long buzz and will print Done
when finished.
You can use Bangle.beep()
in much the same way as .buzz
above to make sounds. See the reference.
To output an entire scale of notes, you could do:
Bangle.beep(200,207.65*8).then(
()=>Bangle.beep(200,220.00*8)).then(
()=>Bangle.beep(200,246.94*8)).then(
()=>Bangle.beep(200,261.63*8)).then(
()=>Bangle.beep(200,293.66*8)).then(
()=>Bangle.beep(200,329.63*8)).then(
()=>Bangle.beep(200,369.99*8)).then(
()=>Bangle.beep(200,392.00*8)).then(
()=>Bangle.beep(200,440.00*8));
Note: The majority of Bangle.js devices do not contain a piezo speaker,
but instead use the vibration motor for sound. If you received your device
and it doesn't make a noise when using Bangle.beep();
, please update
the Bootloader
app via the App Loader.
There are 5 buttons on Bangle.js. The 3 physical buttons on the right are (top to bottom) BTN1
, BTN2
and BTN3
, and the screen has two touch areas, on the left (BTN4
) and right (BTN5
).
BTN1
- ‘Up/Previous’ in menusBTN2
- ‘Select’ in menus, or bring up menu when in ClockBTN3
- Down/Next in menusBTN4
- Left-hand side of touchscreen. Used for some games, but not in menusBTN5
- Right-hand side of touchscreen. Used for some games, but not in menusdigitalRead(BTN1)
or BTN1.read()
(the two commands are identical). BTN
is also defined, and is the same as BTN1
.setWatch
to call a function whenever the button changes state:setWatch(function() {
console.log("Pressed");
}, BTN, {edge:"rising", debounce:50, repeat:true});
The accelerometer runs all the time and produces accel
events on the
Bangle
object.
Bangle.on('accel', function(acc) {
// acc = {x,y,z,diff,mag}
});
See the reference for more information.
When a sudden movement is detected, the accelerations in it are recorded
and a gesture
event
is created.
If .tfmodel
and .tfnames
files are created in storage, Tensorflow
AI will be run on the model with the gesture information and an
aiGesture
event
will be created with the name of the detected gesture.
The compass can be turned on with Bangle.setCompassPower(1)
and when
enabled, mag
events are created 12.5 times a second:
Bangle.setCompassPower(1)
Bangle.on('mag', function(mag) {
// mag = {x,y,z,dx,dy,dz,heading}
});
See the reference for more information.
The GPS can be turned on with Bangle.setGPSPower(1)
and when
enabled, GPS
events are created once a second:
Bangle.setGPSPower(1)
Bangle.on('GPS', function(gps) {
// gps = {lat,lon,alt,speed,etc}
});
GPS-raw
events are also created containing a String for each
NMEA line that comes from the GPS receiver. These contain far more
detailed information from the GPS.
See the reference for more information.
It's also possible to write data to the GPS to configure it. Check out the Bangle.js technical specs page for more info.
You can turn on the heart rate monitor with Bangle.setHRMPower(1)
, which
will cause HRM
events to be generated roughly every second:
Bangle.setHRMPower(1);
Bangle.on('HRM',function(hrm) {
/*hrm is an object containing:
{ "bpm": number, // Beats per minute
"confidence": number, // 0-100 percentage confidence in the heart rate
"raw": Uint8Array, // raw samples from heart rate monitor
*/
}
});
Beats per minute is calculated using autocorrelation.
See the reference for more information.
You can also access the heart rate detection hardware manually with:
Bangle.ioWr(0x80,0); // turn HRM on
var a = analogRead(D29); // read the raw PPG value
Please see the Firmware Update page for detailed instructions.
Check out:
This page is auto-generated from GitHub. If you see any mistakes or have suggestions, please let us know.