Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage Presentations Bangle.js - Creating a Smart Watch with JavaScript

Bangle.js - Creating a Smart Watch with JavaScript



Gordon Williams talks about how he took an off the shelf smart watch, reverse engineered it, installed a JavaScript interpreter on 400 of them and got them into the hands of the attendees at NodeConf EU. He's currently in the process of shipping another 1500 watches to Kickstarter backers.


Gordon Williams is the creator of the Espruino, a tiny microcontroller board that runs JavaScript. Over the past 6 years he’s designed hardware, written software, and shipped four successful KickStarters from his home in Oxfordshire. Before that, he wrote compilers and 3D graphics software for a range of companies, including Altera, Nokia, Lloyds Register, Microsoft, Collabora, and Curtiss Wright.

About the conference

Software is changing the world. QCon empowers software development by facilitating the spread of knowledge and innovation in the developer community. A practitioner-driven conference, QCon is designed for technical team leads, architects, engineering directors, and project managers who influence innovation in their teams.


Williams: This is about something called Bangle.js. It's a smartwatch that you can program in JavaScript. I did a Kickstarter for it towards the end of last year, as well as having about 400 and go out to NodeConf in Ireland last year. It's a bit different in that a lot of the talks I do are very much about JavaScript. This is about the process of trying to get JavaScript running on something like this. In a way fits quite well with what Alistair was saying in the last talk, that so much stuff now is dependent on online services. You buy it and it's very much a disposable item. Especially if you're trying to buy something from a startup, there's always a question of how long is this actually going to hang around. Even if the startup does well, they may get bought up and the owning company may just shut down the things.

This is kind of an antidote to that. Everything is designed such that all of the code is open, free, it's not dependent on any third-party services. It's basically me and a few contributors working on stuff like this, which means that we don't have a massive R&D budget. To get something that's waterproof, and that you can actually wear on your wrist, and is usable, you really need to lean on other people's hardware. That's kind of the bulk of this talk.

Why would you want one of these? Suppose you have some hobby like sailing, or flying, or orienteering, or a whole bunch of stuff that you want something a little bit unique. You want maybe data displayed in a certain way, maybe you want your current GPS coordinates displayed as an OS map coordinates, or maybe you want to record your data in a certain way, merge your location and heart rate with other data like your cycling computer. Often, there may be devices out there that will do it, but they're probably single use, they're probably rubbish at doing other stuff. The more niche you get, the more expensive things get, and the more unpolished they get. This is really a hope of trying to allow people to develop things that really suit them, and then put them online in a way that everyone can use them really easily.

If you're going to make your own hardware, you can do things like this. This guy has made his own little watch with a display that you can just get off eBay and a bunch of other stuff. It's quite fun, but realistically, it's not adding a bunch of utility to your life. In fact, it's probably going to make your life way harder. It's not waterproof. It's not going to do a bunch of stuff. You want a proper molded case, probably some kind of touchscreen, proper buttons, stuff like that. You can go for commercial stuff maybe. In lots of cases, this is very locked down. It's also going to be dependent on other people's services.

The technology in something like an Apple Watch will be completely cutting edge. You really have no hope of reverse engineering it, or doing anything that Apple didn't intend you to do with it. On the other end of it, you can have some cheap Android watches. You may well get some stuff done with that, but you're looking at quite low battery life, quite expensive watches. If you do something wrong, it's a very expensive mistake.

There are actually a whole bunch of really cheap watches that you can get hold of. The hardware is kind of okay. It's not amazing, but actually, it's a reasonably high standard. The problem is the software's often absolutely rubbish. These are like a really good thing where you could actually add some value by changing the software. They come in a whole bunch of different types. You've got some that actually run Android. Some of these use a chipset made by a company called MediaTek. They're basically feature phone chipsets. They're just about capable of running like a proper OS, but again, reverse engineering these is going to be quite difficult. There's an awful lot of stuff going on. Everything's at quite a high level. You've also got very low end stuff, which uses Chinese chipsets by people called [inaudible 00:04:37], I think it is. Unless you can speak Chinese, they're completely out of reach. All the data sheets are Chinese language.


Sitting right in the middle, you've got chips by someone called Nordic Semiconductor. These are really good. They've got an ARM Cortex M4. They're not super-fast. They're 64 megahertz, but they're really very low power. The nice thing is that, especially this NRF52832, Nordic only basically make one of these chips. You can use a development board or whichever watch you get that uses one of these chips will basically run the same code. All you really have to care about is how to connect the display up, how to do the buttons, and all of that stuff. The actual Bluetooth side of things, once you've got it working on one chip, it'll work on all of them.

Because there are microcontrollers, when you open them up, often they've got something like this. It's a debugging port, but the kind of the pins are something called SWD. You only need two connections for SWD and then to connect ground. Once you've got that, you can start writing your code directly to the watch.

The sad thing is that in a lot of cases you have to open the watch. Many of these things are designed to be disposable effectively, and they're glued shut, which means that you basically destroy waterproofing by getting into them. Ideally, you would find a way, once you've maybe done your development watch, of getting another one and writing software to it wirelessly. You wouldn't think that the company would let you just wirelessly update the firmware to whatever you want. Actually, they do.

When the Nordic chips were first released, they were shipped with a SDK, which had a kind of proof of concept bootloader in. Everyone basically just use this bootloader as is. There was no check to see whether it was actually the right firmware for the device. There was not even a check to make sure that you were allowed to access the device. For instance, anyone who's wearing one of these cheap fitness bands, you could run the firmware update code right now and overwrite their firmware. Again, this is a really good reason why you want to replace the firmware on these devices. In reality, it's a little bit more complicated than this because the bootloader is broken, but you can still wirelessly update firmware on a lot of these devices.

The First GPS, BEIDOU, GLONASS - Three Satellites Global Positioning System

I really wanted to try and do a device with GPS because it's just hard to get a low power GPS tracker or any kind of device that you can program yourself. It fills a nice niche. That basically limits the amount of watches. You've got about five. This was the one I ended up using in the end. It does GPS, BEIDOU, and GLONASS as well. It's a little bit chunkier than the lots of other watches you might hope for, but actually having the ability to get that real-time location can be really handy.

It's got reasonably big screen, accelerometer, compass, and a big flash tip, which is kind of quite important because the chip itself only comes with half a megabyte of flash, which gets used up quite quickly when you start using Bluetooth functionality in it. The four mega flash gives you a lot of data available to store your applications and everything else. The slightly worrying thing is that this 240 by 240 16 bit screen, it uses 120 bytes of RAM as a buffer. There's over twice as much RAM inside the screen as there is in the processor. It requires a bit of thought in making that available in a nice, fast way that doesn't use up all your available storage space.

These are not the first watches. It's not the first watch I came across. This is a small selection of watches from my watch graveyard of various things. They've been taken apart and looked inside. The biggest problem with a lot of these is not the hardware. In fact, the hardware, you could run a screen on pretty much all of them. It's to do with the manufacturer. Most manufacturers tend to get quite scared. Because, again, there's a language barrier thing. Often it's very difficult to explain what you want to do. If they do understand what you want to do, often they're quite scared of the idea and they don't want to get involved at all. Again, you're a little bit limited.

Anyway, once you found watch, this one's quite nice in that when you open it up, you've got this really nice little puck basically. There's a screen on top, a little GPS area at the back. You can see a little flex PCB working around the corner. You can see on the back that the flex PCB goes all the way around, you've got some buttons on it, and a heartrate monitor, and the speaker, and a bunch of other stuff. You can start to peel it off, you can unravel it, and you can spread it out. This is not something that you would do with your watch. It's something that effectively we do so that no one else has to. As is, this watch, you've got the green circuit board with the actual guts that does stuff, and the battery, and then the backside of the LCD. This whole thing still works when it's completely unraveled. It's quite handy to be able to look around.

At this point, to figure out really how it works, we actually have to look at the underlying hardware. Given a bunch of you have soldering irons, you know what this is about. As a quick aside, this is a very low level circuit board that people might have been producing 30 years ago. You've got a glass fiber sheet. There's copper on one side of it, and that copper acts as wires. You basically poke components through the holes, you solder them up with what's effectively molten lead, and then that makes the connections for you and holds everything in place. This is a rubbish way of making the compact electronics. Not only is it very big, but it takes an awful lot of time and manual labor to get this stuff working. You can't quite see the chip, but there's a really big chip with the two rows of pincer that will require you to manually fiddle the pins to get into the holes. It's not something a machine can do very easily.

Instead, everyone's moved to surface mount. What you do is you take the same basic circuit board. This one's got this green solder-resist layer on which effectively stops the solder from moving out too much. Then you silkscreen solder paste, which is like microscopic blobs of solder into the locations where you want things. Then you have a machine that just pushes all the components into place. You put it in a big oven, it cooks it at about 200 degrees C. All the solder melts, and it makes the connections. This lets you get everything a little bit smaller.

This is actually a reasonably approachable circuit to look at and figure out what's happening. Because it's got two layers. It's got one layer on the top, one layer on the bottom, but they're all completely human visible. In fact, you can take all components off, sand back the little layer of solder-resist, and figure out exactly where will the wires go. At this point, you could even scan this in and send it off and get a complete clone of the circuit made and you could assemble your own.

People want to get things even smaller. This is a Raspberry Pi. Quite an early one actually, I think. The circuit almost looks simpler than the first one, but there's an awful lot more going on. This chip is a ball grid array chip. Instead of having the physical legs along the edge, you've got a whole bunch of pads on the bottom of it covered in [inaudible 00:13:11] solder. The machine puts that down on the board, and then goes through an oven and it melts on. The issue then is that you've got all of these pins, you can't get the connections out. They don't just use two layers. They use multiple layers of boards sandwiched inside. I forget how many the Raspberry Pi is. I think it might be six layers or so. They can go all the way up to 12 individual layers of copper right inside the board. At this point, it becomes a complete nightmare to figure out what's actually going on.

For our watch, it's a four layer board, but it has the old-style surface mount chips. You can still see all the connections around the edge. In fact, you can often look at the board, read the numbers on the chips, google them, get a datasheet, and it will tell you what all the pins are. On this one, you can hardly see because it's yellow. I've tried to label the pins. We can kind of work through this. If we're interested in where the SWD pin goes, it's one of these, but you can see they go to these holes here. This is kind of the mirror side of the back of the board. You can look them up there, and then you can follow them around. You can figure out that they go to here and here. Something like this pin, this just goes through and you find like a single dot there. Nothing's s happening at all. That means it's a four-layer board. That goes to a wire that is hidden somewhere inside. We have no idea where it's going. We can get a few things, figure out where the connections go here, but we can't do very much.

What else can we do to figure out what's going on in the watch? You can actually write your own software to it and start playing around. You can, for instance, read the values of the 32 pins on the watch. They're all ones and naughts, so it's just a string of ones and zeros. You press a button, and then you do it again and you see what changes. You can work out some things quite easily like this. You've got your 32 pins and you're just ticking them off. If you know the buttons, then those are pins that you don't have to worry about for other things. That still doesn't get us all the way. It would be much better if we could figure out what the original engineers did in their software. The chip manufacturers have added something called the protector bit. If you set that when you're uploading the firmware, it stops people using those debug connectors at the back to read out any of the firmware, which seems like a really sensible idea. They've done it. At this point, you think that it would be impossible for us to get the original firmware out of the device, but that nasty bootloader strikes again.

If you look inside, this watch manufacturer provides an Android app to do the updates. The Android [inaudible 00:16:19] a zip file. If you look inside the zip file, you find a whole bunch of hex files. These are files that contain all the actual code for the watch. The slightly worrying thing here is that you notice they have names like blinky, and ble_app_hrs. These are the exact names of examples in the SDK provided by the chip manufacturer. It means that the people who have written the software for this watch have based their whole firmware on an example application from Nordic and haven't even bothered to rename it, which, again, gives you an idea of why you really want to be looking at replacing the software.

Anyway, if you look inside one of the files, you find there's just random data, but you can see there are definitely patterns to it. If you look inside the arm datasheet, you find there's this thing called a vector table. The vector table is just a load of pointers right at the beginning of memory. You've got the first one, it's a stack pointer, and all the rest of them are pointer bits of code. You could look at this, look at where the code was, use GCC toolchain maybe, and disassemble it, and get a much better idea of what was going on. There are some tools that make this really nice and easy. This is an example of how it decodes. On these arm chips, everything's kind of memory mapped in its own location. Right at the bottom end of memory, 0x000, you've got the actual program code. Then when it starts with 2, you know that that's RAM.


There are tools like this, which is Ghidra. This is actually tool created by the NSA for looking into firmwares and binaries and trying to figure out what's going on. It supports a whole load of different architectures. One of them is the ARM Cortex for these little devices. You boot this up, and you get something like this. You can see you've got the same vector table here, but now it's noticed that these things are actually addresses that point to certain locations. For instance, if you look at the [inaudible 00:18:39] one here, this is basically a segfault. If something goes horribly wrong in your code, it will call here. You can see it's actually not only disassembled it, but it's decompiled it, and it figured out it was just a wild true loop. Something bad happens, your watch just bogs up.

Now we can kind of look in from the vector table and see where bits of code are. We can also look out at bits of memory and see where peripherals are being accessed. Here you've got address, 0x5, lots of zeros. You've got these IO ports. These directly control where pins are. For instance, those buttons we were looking at before, if you're interested in the button, you go for 0x50000510. If you just do a search through the code, you find it's being used and you see the disassembly. You see it's reading that whole number, and that whole address in memory, which is a 32-bit number for 32 pins, shifting it right by the pin number and adding one. Now you know you've got a function that accesses GPIO. Why this is used, you can start to get a better idea about other things.

There are other peripherals like the serial port, for instance. You know that the only thing that could possibly use a serial port on this watch is GPS. Anything using that address, you now know is GPS. You can start to build up a table of where everything goes. The other interesting thing you can do is you can find bits of text buried in the firmware. This watch says "Bye!" whenever you turn it off. Again, you know that any code that references this is code that will be shutting the watch down and turning off peripherals. You can start to dig into it that way as well.

The people who did this firmware, obviously just took the totally standard example, added a bunch of stuff to it and shipped it. They didn't actually look at what the compiler was doing. In going through this, I noticed things like this code, I figured out it actually sends data to the LCD. It sends one pixel worth of data, 16 bits. The LCD is wide, eight bits at a time. It just sets the clock pin, it writes eight bits of data, it clears a clock pin, writes eight bits of data, sets it, clears it to kind of toggle it in, and then does the same thing again. The engineers were obviously trying to do something very smart here, because they went to a lot of effort to actually wire this LCD in and address it with parallel data so they could push eight bits out, write in one go. They wired it up so they could do it very efficiently from the microcontroller. They obviously thought that these functions were going to be inlined or something. As it turns out, they're not. The whole watch is running about half the speed that it could do if they're just put one inline keyword near the function call so that they could have forced everything to get put in. I think it shows that even if you think the compiler is doing something, it's well worth diving a little bit deeper to try and get a better idea about it.

At the end of this, it's kind of a process almost like doing a jigsaw. You find bits around the edge and you build in from the edges and the corners, and you can rule certain things out. It makes it quite a fun process trying to figure out this data, which is basically the end result. Just a list of where all the pins and things go.

Chrome Lite Mode

Now we've got this, an idea of how to actually write to the underlying hardware. How do you run JavaScript on something that only has 64K of RAM? This is a graph from the Chrome Developers blog. This is, I think, for the Chrome web browser itself, but you get an idea of their expected memory usage. They've made some really big changes here trying to make a cut-down lite mode for more constrained phones and things. They're still using six megabytes of RAM. It's way too much. It's 100 times more than this watch has. You need to think a little bit more about what you can do to really get things down as far as possible.

Seven years ago, there weren't actually very many JavaScript engines available. Now, if you look, there are a whole bunch. This is just the first three that came to mind. If you look at Wikipedia, there are probably at least 20 different JavaScript engines. There are some of these that deal with very constrained embedded targets, but they pretty much all have 64K RAM. It's that absolute minimum, which is like the minimum you get to by cutting out a bunch of stuff.


Basically, especially seven years ago, I had to do something very different. Espruino was designed specifically to run on these low end microcontrollers. In fact, it'll run in under 6K of RAM. You can write some useful code in it. I'll give you a very quick example of that in a sec. It's not all of ES5, but there's basically everything. If you're just writing normal code, you won't notice the difference. In fact, generally, if you transpile your code, you'll find that it transposed to a subset that runs absolutely perfectly on these. There's a list of exactly what it doesn't support there.

The real reason for doing something special is this. If you look at the vague specs of a typical computer, these are just randomly picked out of the air and for a typical microcontroller. The computers are obviously more powerful. It's very interesting when you look at the amount of bytes per megahertz of processing power. Very roughly, you can imagine this would be the amount of time the computer takes to go through all available memory. On PC, it's way more memory available to it per computing instruction than on the microcontroller. If you don't necessarily care about outright speed, which you probably don't if you're trying to run JavaScript on a microcontroller, maybe you should be looking more at trying to spend more of your instructions making the most of the available memory.

One of the ways you can you can make more of the memory is to try and do something about memory fragmentation. Again, not normally a problem on desktop, but on embedded targets, mostly people statically allocate everything. It's because you can't necessarily depend on malloc to always work for you. In this example, you allocate a bunch of stuff, and you just deallocate all the items. That means even though you've now got 15 memory elements free, there's no big contiguous area of storage that you can use.

In Espruino we use, we fixed size memory blocks, which have a few benefits. We can chain the blocks to, for instance, store strings when we're expecting data to come in a bit at a time to save as having to reallocate a big block each time. We also save the overhead of having malloc. Malloc will use at least four bytes to store the length of the data that you allocated. If you're going to do garbage collection, stuff like that, you also need to store a pointer yourself to the data that you allocated. Now you're using eight bytes. Basically half the size of this variable just to have allocated some data. The other thing is that because they're all fixed, they're all in the same place, you can just plow through them really quickly if you need to do something like a garbage collection path.

The other slightly weird thing we do is we execute direct from the source code. We don't compile to a bytecode, or an intermediate code. Again, one of the reasons is, if you want to run an interpreter on your system, you're probably doing it because you want to get a stack trace, because you want to be able to analyze your code and step through it, and do a lot of the things that interpreters are really good at. If you then throw away all your source code, you're kind of losing a lot of the benefits of having a language interpreter in the first place. This is example of just some code that very simply draws out Mandelbrot fractal. The normal JavaScript, 300 bytes, and when you minify it, it starts to go down quite low. Then if you remove all the reserved words, you turn them into single bytes, it gets them really low.

The bytecode that Spidermonkey produces, that's almost as much as the raw JavaScript was. If you do GCC, this is -0s. This is telling GCC to optimize the size. It's still not managing to get any better than the normal JavaScript. To be fair, the GCC compiler will go way faster. At the end of the day, we weren't really up to speed.

This is a quick example of what this looks like. This is a picture of the memory in the JavaScript interpreter that's running with 700 bytes of RAM available. I've just got it running locally. Each red row is an allocated row, each black and blue row is a row that isn't allocated. You can see individual bits in here. It's not at the byte level. White or blue is a one. Red or black is a zero. You can see that as I'm typing, it's filling up characters eight bits at a time in that. When you reach the end of one block, it will allocate a new block. We can do that.

We can now try and split it maybe by space. We'll see it goes through, allocates a whole bunch more memory like that, and then throw it away again after it's not used. Let's write that again. If we now save it in the variable, we'll see allocate the data and then keep that data. You can see how quickly memory gets fragmented here. It doesn't matter in this case. In fact, we can defragment this memory because everything's in a fixed size block, there's where all the references are. It's very easy to push everything back if we ever did need to allocate a big chunk of memory. Doing things this play actually allows us to do quite complicated things in very, very little memory. For instance, there's a regular expression parser in here. Let's just get rid of "a" for a moment. Then we'll just split it again, but we'll do it on maybe "l" and "o". You can see it's gone through. It's been able to run regular expression with extremely low amounts of RAM.

Web Bluetooth

Now we've got this running on our device, how do we actually access it? There are no IO pins on this other than what you get for charging. If you do anything, you've got to do it by the radio that's on there, which is Bluetooth. One of the really nice things that's available to us now is something called Web Bluetooth, which is something that Google introduced in the Chrome browser. It's worked its way now into Edge and Opera, which means it's available as long as you've got one of those devices, which vast, I imagine, population does. Windows 10, Mac OS, Chromebook, Android, even Linux and Raspberry Pi, you can access Bluetooth devices directly from a web browser. This makes your life really easy.

iOS actually doesn't support it out the box because Apple not only don't support it in Safari, but they stop you from installing your own actual browser engine. Even though you can install Chrome on iOS, you are still using what's basically Safari browser under the hood. There is an app called WebBLE, which does manage to work around this, and allows you to view websites and let them access Web Bluetooth if you need that. That's open source. If you were developing a project where you needed to access Bluetooth on a bunch of devices, you could fork it, you could add your own code to it, and then you could ship that as a wrapper. Again, it works on Node. The JavaScript interpreter itself that runs on the watch will execute Web Bluetooth code.

You can now make tools like this that will allow you to write code to the device. In reality you don't need very much. You just need a serial terminal that will run on whatever computer you're doing, and will communicate over Bluetooth Low Energy. To actually make your life easier as a developer, it's nice to have syntax highlighting and code completion, the ability to pull in modules and stuff like that. That can all be done online, which, especially for the project, makes life really easy in terms of shipping updates, making sure everyone's all on the same version and stuff like that. We should add that this is also a progressive web app. Even though it's a website, you can still use it completely offline to access things.

In the same way, we've got an app that allows you to load whatever new applications you want on. This is basically the whole thing is hosted on GitHub. You can make pull requests with new applications in order to add what you want. The great thing about this is that none of this stuff is dependent on a server. Even the IDE is all free and open. Regardless of what happens, you are still able to use these devices yourself.

At the end of the day, the code is a very simple example. This is a device for an app that will tell you what your current speed is. You can see the vast majority of the code here is actually accessing G, which is the graphics instance, to just draw the data in the way that you wanted. You can come up with applications very easy that do some quite interesting things without having to do a bunch of work. If you don't have a watch available, you only need to add a small amount of boilerplate to this, and then you can do a [inaudible 00:35:46] GitHub repository. You can make it so that everyone can use it.

Because the JavaScript interpreter is reasonably compact and can be made to run in a fixed area of memory like 64K, we can actually compile it with Emscripten. This is something that's available now. If you don't have a Bangle.js and want to play around, obviously, none of the sensors work in there, but you can still develop applications and run them completely in the web browser with an emulator that's executing your JavaScript code. It's executing in the browser, but it's executing it in the JavaScript interpreter in the browser. If you want to see exactly how capable the JavaScript interpreter on one of these devices is without getting one, you can try it out at a very low level.


These things, in an ideal world, they would have been shipped by now, but because of Coronavirus, there's been a bit of a delay. I'm actually going to be seeing them probably beginning of next week. They're being shipped this week, and then they're going out to people next week. They're should actually be properly available in March.

Bangle.js is based on Espruino, which is an open source interpreter. As such, it's available for a whole bunch of different devices. The work on it's supported by sales of boards that we've developed that run it, but because it's open, it's available in a whole bunch of very cheap hardware. You can go on eBay, you can buy a ESP8266 or ESP32 dev board for about £4 delivered, and then you can start to play around with real hardware.


Now we're communicating with our device completely wirelessly. There's a clock application on here, which at the moment, I've just reset it, so it's come up as completely wrong time. We have the Repl on the left-hand side where you're actually communicating directly with a JavaScript interpreter on the watch. And we have on the right-hand side just some way you can write code and easily upload it. For now, I'm just going to erase any of the currently running code on the watch. So that we can see it, I'll just make sure I force the LCD to be on. Obviously, we can write text to the console. It will appear in a very small font. When you turn on developer mode, you can actually make it so that if your code does create any errors, it will still show them with effectively full stack trace on the device, so when you're using it, you at least have some idea that something might have gone wrong.

Let's just come up with a very simple countdown timer. We have here some example code which will just flash a little fake LED there. It's easy enough to take this and turn it into countdown. Now we can look at trying to draw it onto the screen. We'll clear the screen. We'll draw the count and we'll set it go right in the middle. So that I can update this function on the fly without resetting, I'm just going to take it into a named function outside. Let's upload that. We should now start to see our text appearing very slowly. We can now start to experiment with it. We can change the font size, for instance. If I want to change the font to be effective font, because we've reset it again, let's force the screen to always be on again.

Now the screen is forced to be on. We can do that and next time it updates, it will make the font a bit bigger. Now we'll see it's not aligned properly, so we can just change the font alignment. If that's good, we can move this into the actual code that we're using. Now we've got it right. Maybe when it actually reaches zero, we want to do something. Let's create a new function for alarm. We can test this by just typing along to try and run the function. It's now vibrating once a second.

Let's reupload this. Let's actually put a message to show that it's actually got the alarm. There are a few functions built in, which allow you to show messages and things. For instance, we can do showMessage, which gets overwritten very quickly at that point by the countdown if I stick that in that. So that we don't have to wait around just for a minute and a half for this to work, I'll set the countdown to five. Hopefully, now, if I haven't done anything horribly wrong, yeah, there it go. It's canceled timeout. It's done a little alarm. That's just a few minutes of work. You can now take this, you can do a pull request with it. Everyone else can have the fun of 100-second timer that you can only cancel by resetting the watch.

That's what it's like. Again, this software is entirely open so it can run on a whole bunch of different devices to the point where there's even a firmware built available that will run effectively the same code that's on this watch, but on a cheap Chinese fitness band that I think costs about £7 delivered. You can still play around with this, with very little investment.

Questions & Answers

Moderator: I'd like to start just by going straight with kill and asking why JavaScript, why not Lua? Why not something else?

Williams: Because, love it or hate it, it's quite a popular language. It's quite forgiving as well. If you imagine if every web page was written in C, what a nightmare the internet would be. It's not great, but it's kind of got where it is because it works. There's a real question about whether you should write a million-lined enterprise application using JavaScript. I think you can have some very heated arguments about that. If you're doing a page of code like this, really there are no real downsides to that.

Moderator: It's just super fun, right?

Williams: Yes. It looks a bit like C and PHP. Without very little knowledge of it, you can get started very quickly.

Moderator: Awesome. Do we have any questions?

Participant 1: How does the battery life on the custom firmware compare to the base firmware?

Williams: It's remarkably similar. The biggest issue right now is when the CPU is working flat out, it draws, I think it's about four or five milliamps. If you turn the screen on, it draws about 40. If you turn the GPS on, that draws like another 30, 40. Actually, the biggest change to how long the watch lasts in everyday use is the thing you use to turn it on like that, because you don't want it coming in automatically in your pocket. Depending the settings you have set to that, it depends whether it's more or less battery life than you would be getting. At least it gives you the flexibility to choose. You're not stuck with some rubbish way of turning on that's always coming on in your pocket.

Participant 2: The application page that you shared with all the applications that you can download, I was wondering, are there any security mechanisms or any other mechanisms for controlling misbehaving applications, or have you seen anything like that before?

Williams: No. At the moment, it's still at the state where there are about 500 of them out there with people using them. It's not really at the point where people are uploading stuff that would misbehave. The question is what someone might do to it. They're very unlikely to be able to actually destroy the hardware of your watch. What they could do is have a Bluetooth keyboard application that randomly typed up a bunch of characters that backdoored your PC whenever you connected it. It's very difficult to work around that. The real bonus, though, is that the code is just up there on GitHub for anyone to see. If anyone thinks there's anything fishy going on at all, they can just take a quick look and it should be quite obvious if any app is trying to do something dodgy.

For general, everyday problems, we've got little script that runs over it. [inaudible 00:50:03] just as a sanity check to make sure that no one's done something stupid. If there are things that we know could be potential problems, then we can add screening for them. Then even before it gets merged, we should know if there was an issue.

Participant 3: Can you reuse other people's code and write libraries, or maybe even this thing that you just wrote? Can I use it in my software? How does it look like? Does it require import, something?

Williams: Yes, you can. The IDE allows you to require stuff. We did for a while have some MPM support built in, but unfortunately, because when you require one thing, it tends to require another bunch of stuff. It was super hard work. It was like 1% of packages you could actually use on this device, because otherwise they just fill your RAM up with complete garbage. Because this is running in the web browser, you can just require the URL so in a really hacky way you can require a gist. You can require the file that's sitting on someone else's server, as long as it's got the cross origin turned off on it. I suppose a good example is like the GPS. There's a lot of code out there for handling GPS coordinates for online mapping. If you want to turn the latitude and longitude into some random mapping coordinate, you really can just find a bit of code on the internet, either referenced directly or just included in the thing. The JavaScript it supports is at a level where you're unlikely to have any issues at all pulling in someone else's code.


See more presentations with transcripts


Recorded at:

Jun 08, 2020