Sessions is temporarily moving to YouTube, check out all our new videos here.

JavaScript for Microcontrollers and Bluetooth LE

Gordon Williams speaking at JS Monthly London in June, 2017
Great talks, fired to your inbox 👌
No junk, no spam, just great talks. Unsubscribe any time.

About this talk

Learn how you can use the Web Bluetooth APIs, JavaScript and Espruino to control things in the real world, straight from a webpage.


So yeah, I'm gonna talk a bit about controlling specifically, this microcontroller Puck.js, with Bluetooth Low Energy and Web Bluetooth. So what is a microcontroller? I'm sure a load of you know this already, but it's basically a tiny computer with everything it needs on chip. I mean there's a huge array of different ones. But on the whole, these things, you can just apply a battery to certain pins, and it will boot up, it will start running whatever code you've written on it. So it's got RAM in it, it's got Flash, it's got voltage regulators and oscillators and pretty much everything. So they come in a huge range from just a few single bytes of RAM to a megabyte or more. And there are loads of them made. So ARM, who makes the microcontroller in this particular one, they licenced 15 billion cores in 2015. So two for every person on the planet. And they're only one of a whole bunch of different microcontroller manufacturers. So, I mean there are massive amounts out there in all kinds of different things. And these can be quite powerful. So this is a decidedly mid-range chip that costs around, like, in quantity it's $2.00 or so, one off, you're talking 5 pounds. It's about the same amount of performance as the first Pentium chip that Intel produced. So it's kind of the same as a desktop computer from not that long ago. And these things, they're absolutely everywhere stuff that you wouldn't really expect. So you probably interact with a whole load of them every day without realising it. Sometimes they'll be, they'll obviously be in key fobs for your car where they do rolling codes to make sure that no one can snoop on it very easily. You've got bike lights that go through different modes. And some things that could have been actually made with single purpose chips and made with microcontrollers. Because if you take the bike light for an example, you've got maybe, someone will produce a million bike light chips. But someone that's producing a general purpose microcontroller may sell a hundred million. And despite the fact that it's probably a very slightly more complex device, devices can be much slower and it's gonna be much easier because you can actually differentiate your product in certain ways by like, flashing pattern or whatever. Who's actually done anything with microcontrollers? Okay, not that many of you. Who's done anything with the Arduino or who's started off with that? Yeah, so it's basically everyone who's done stuff with microcontrollers has used one of these. And this is like the classic Arduino. This big chip here is a microcontroller. But you've actually got another microcontroller up here which handles the USB communications. All this stuff here is just passive play. So what happens is, this is the Arduino ID that you instal in your computer. You write some code and you click Upload. And that code gets compiled down to binary code and then the binary code gets sent through USB from here onto here and then it executes. But it's a very one way sort of thing. It's like, I guess trying to develop a web page with no debugging tools, no Chrome developer console or anything. So basically if it's not doing what you expect, then you've got a real problem. You've actually got to start inserting bits of text into that page to kind of figure out where things are going. It's a bit weird. For small projects, it's absolutely fine. You never have a problem. But the second you start to do things a bit more complicated, you really start to have issues. So this was the BBC micro that was released about 35 years ago. It cost about, I think in today's money it's about 1,000 pounds. It has a keyboard, it has video output, it has a BASIC interpreter on it. So you can write code in BASIC and if your code has an error, a reasonable amount of the time it will tell you about that error and actually where it was in the code. But this was substantially less powerful. I mean like, probably 10 times less powerful than the computer, the little microcontroller what I showed you at the start. So there's no reason really that you can't have that interpreter and all that stuff running on a microcontroller. And in that case, if something went wrong or something that you weren't expecting you'd actually be able to see what had happened. Now I mean, things like the Arduino boards above, so this one, this is actually a in-circuit debugging connector here. And a lot of boards have this and you can get external tools to connect to it. Some boards have it built in but generally the tools still aren't that great for it. If you're willing to pay for it, they get really good. But, esepecially for the hobbyists or if you're just trying to get started you want something that kind of has everything that's needed and just works straight off. So you could choose a whole bunch of different languages to run on this thing. And I really quite like the idea of JavaScript. Because I think it's about the only language that's pre-installed on pretty much every computing device. You might find that most of the code for various devices is written in C. But no one's actually exposing that C compiler to you out of the box on virtually any of their devices. Whereas even your TV now has probably got a web browser in it that will be executing JavaScript code. And it'll be executing that in an environment that is more or less standard. You know what things are gonna be called, you can do at least basic stuff on every device with the same bit of code. And if you make all that code run on the microcontroller as well, you can do some really cool things. If you're making an internet of things service, maybe you have some kind of data aggregator, so you're taking a reading every second and then you want to squish that down into a reading for that hour. You could write that code and have it on your microcontroller, if you really cared about the amount of bytes you were sending along the data link. Or you could put it on the server which would be kind of the sensible thing to do and then you can deal with all your data. But you could also stick it on the client, and then someone could play with sort of the coefficients or whatever this algorithm was and see what effect it was having on the data in real time. And you don't have to rewrite your code at all for that. You just use exactly the same code. One of the other reasons that JavaScript's really good is that it encourages you to write event based code, and it's got closures. So this is like, a really simplified bit of code, something you might want to do maybe, where you take a reading from some sensor and then you turn a heater on and you wait for it to heat up and then you take another reading and then you call this function which'll compare the two readings. But in this case, you've actually, you've just got two small functions. If you look at the Arduino code that was above, we just had delay and it was a very procedural thing. It would just stop execution, unless you were willing to delve into sort of scary interrupt driven stuff. You would really struggle to do anything in-between times. But this, it'll execute this function, it'll execute this function a second later, but in-between times, you can be doing whatever else you want and you don't really have to worry about how it interacts. And the even better thing is that when this is done, this is allocated data for this, but when this function is executed and passed into the callback, all the data's freed automatically. You don't have to worry about allocating memory or memory leaks and stuff like that. So I guess the obvious question is why wouldn't you do it on something like a Raspberry Pi? So these things aren't really microcontrollers, they are full Linux PCs, and as such they'll run Node.js, they'll run whatever favourite language you want to run. And they'll do it quite quickly, quite efficiently. And they've got all the Linux still spaced in. So for a lot of things they're actually really good. The problem comes with the power efficiency. This thing's probably got half a gigabyte of RAM in it. Each bit in that RAM will have a transistor. Which won't be on, but it has to be refreshed every so often. So that's four billion transistors that have got to be refreshed all the time. Not only that, but you've got various other things on the board as well, so the video output. Even like, the most stripped down Raspberry Pi, trying to save as much power as possible, it's gonna draw about 50 milliamps. Which is fine if you're running off mains, but if you're running off a battery, it's not that good. So, like a CR-2032 coin cell is about 200 milliamperes, maybe 250. So you're looking at only four to five hours of this running before it completely flattens that battery. So this is a microcontroller running Espruino, and this is like a logarithmic power usage graph. So the idea is, the code very simply, every second, it wakes up, it lights one LED then another LED and then it lights both LEDs at the same time. So you can see here it's drawing like 3 microamps. That's like 10,000 times less than the least powerful Raspberry Pi, in idle mode. And then it jumps right up when it's executing code. This one's drawing like, I don't know, 20, 30 milliamps, and then it drops back down and now it's got the LED on. Which is drawing 500 microamps. So even the LED is drawing, which isn't a very bright LED at half a milliamp. Even that is drawing a hundred times more power than the microcontroller is. And again it spikes up 'cause a bit more work does the other LED, and it turns both LEDs and then it's off again. And this is something that you can't really get to the same extent with a Linux based computer. Because there's not only your code as well, there's various system tasks like doing the RAM, but there's also various operating system things happening at the same time. Espruino started off as a project to make a whole bunch of microcontroller boards easier to programme. And I started it on some of these green boards up here and it's kind of ballooned. This is like, a few of the ones in my drawer. As of the last time I looked, there were 42 different supported boards in the official Get Help Repository. There are still a few commercial boards that have chosen to forget on top of that. So there's a huge amount of different boards that are supported. And they all have like, a flat API for communicating with them. And so I support basically what I'm doing just by selling these ones which have the JavaScript interpreter pre-installed. 'Cause sometimes it can be a bit of a pain to actually instal the software on it in the first place. So getting on to the actual hardware, what if you want to control something from your computer itself? So the microcontrollers can do a whole bunch of stuff and they can do a whole bunch of stuff autonomously without you having to worry about it. But what if you just simply want to control a bit of hardware for your PC? So 20 years ago, the USB spec had just started out, which is quite impressive for USB to be around for 20 years and to still be able to use the same devices you had before. But computers have these, this was a printer port, or a parallel port. And you really could just jam stuff, this isn't really recommended, but you really could just jam a light straight into it. And this is PASCAL, but with no libraries, no nothing, you could just write to this port, there's an eight bit value, each bit represented one of eight pins that were on the back of the port. And you could write the data straight out. It was really nice and easy. But modern computers don't do that. And for very obvious reasons they don't let random programmes write to any bit of the machine when they want to. So now they've got USB, and USB's like a high speed serial bus. So you've got to have some real hardware on the end to decode that. And then you've got protocol layers on top. So the normal way you'd actually create a device from scratch I guess, is, you'd define the hardware, you'd have the microcontroller, and you'd programme the microcontroller to be a custom USB device. And then you'd write a driver for each operating system and then you'd write an application for each operating system that interfaced with that driver. And that's a complete nightmare. So what I do for Espruino is, I pretend that I'm a serial port, first I'll actually step back, computers also, as well as a parallel port, they used to have the serial port. And people still make these dongles. And it's actually pretty much part of the operating system for most operating systems, that you have a driver for these sorts of things built into it. So all it does is, it's a standard bit of the USB spec and it just pretends it's a USB communications device. So that means that now you've kind of cut out the driver work, you've got this thing that will connect your computer, and it will appear as a communications port. Which is pretty much a file on most operating systems. So this is the Espruino beacon. If I plug one of these in, hopefully we'll see, if I start a terminal application, I'll try and make that bit bigger. Okay, so this is now actually logged in to a rappel that's actually running on this device itself. So we can ask it what it's temperature is. You know, it's got command completion and history and all the rest of it built in. So we can ask it to turn its LED on, for instance. And hopefully the red LED will light up. So we can now write code on here to, for instance, just toggle an LED on and off and then cause the set of them, we can do stuff at the same time so if I just quickly do that, If I can type, actually I forget this cause it's a special command now. Hopefully, it'll start flashing. Now you can not only, it's not doing that by itself, you can actually do other things at the same time. So we can go back and we can just change that now, to do the second LED at the same time. And you know, you can play around with this and you can actually write quite big applications just using this. But if you actually just want to communicate with it from another computer, you can just send the characters directly. So, suppose we want to communicate with this from BASH itself. So if I just write the command I want, actually let's do toggle again, and I just send it directly to the device, hopefully, we should see it lighting up. And at the same time if I take this big light button thing and plug it in, this is connected to pin B3, so all we have to do is change LED to B3 and it should hopefully light up. In fact we can do sort of, command substitution. So if you're trying to do a build light say, for when your build fails, this is gonna take the result of the last, executing the last command which'll either be like a one or a zero or the error code. So now everything's going fine. That's fine, if I just do something that causes an error and I run it again, that's gone off. So you haven't actually had to write any software apart from that one line of code there to make something happen. So, right, going back to this, it gets even better, or it did get even better because Chrome had made this, Chrome dot serial thing, which meant that if you wrote a web app in JavaScript, and put it on the Chrome web store, or even loaded it up as an extension, you could get access to the serial devices directly from within the web app. So I've got a web IDE which is, it's not quite this one, but it is like this. All JavaScript, HTML, CSS, and this will actually access your device and give you a proper editor, even like a graphical editor if you want it to write your code. However, Google is disabling this. So you're not gonna be able to do that anymore. But what happens next year or the year after when Apple decides that they don't like USB anymore? There's got to be some other way of communicating this stuff. And there is. There's something called Web Bluetooth. So Web Bluetooth lets you access Bluetooth LE devices from a web page. And Bluetooth LE is not quite Bluetooth, it's a separate protocol that happens on mostly the same frequencies, but it's designed to be much, much simpler. I think the licensing's better on it as well. But the whole thing is designed such that it can be implemented in a very cheap, low power microcontroller. And Web Bluetooth lets you do fun things like this. So this is a little Bluetooth BB-8 toy, and you can actually just go to a website you can click connect, and you can start rolling it around with this. Now this actually could end up being quite a useful thing, because, especially for something like a toy, you probably don't want the 100 megabyte app that's gonna be sitting on your phone, auto-updating. It'll probably give you notifications when a new toy is out, and it'll probably have security holes. Because the people that made this toy are probably not deftly good app developers. So it would be nice just to be able to maybe even have NFC on this. Tap it with your phone, go to a website and then be able to control it straightaway. And Web Bluetooth lets you do that. I'll take what we've seen basically on this with the Espruinos that just go by USB. And I'll do the same thing, implementing a serial port over Bluetooth Low Energy and putting it in a little device, which is one of these. So it's got a battery, it's got Bluetooth, it's got a magnetometer so it can sense magnetic fields, it's got a few lights, it's got an infrared transmitter, so it can for instance, control things like the television from your phone. And you can control it in much the same way as before with the serial port type stuff. The other thing it does is advertising which is a standard part of Bluetooth. Well, with Bluetooth Low Energy. When you don't have a connection, these devices just sort of indiscriminately throw out data saying exactly what they are, what services they offer to other people. So you can have a certain amount of two-way communication. This can just request extra data. It can't do anything else. And then this'll send a little bit more data. But it does allow you to do things like a Bluetooth beacon. So you can have Eddystone and iBeacon. And these things will actually broadcast the URL. And if your phone's set up, I think most Android phones are set up by default, it will appear as a little notification in your swipe down area. Showing you this URL, the web page description, and you can click on it and go there. And you can programme this to do those. But you can also programme it to kind of swap between them as well. The next thing you can do is when you're connected, you end up with this proper sort of two-way communication. And to be honest, none of this really matters except what's really annoying is that all of these names are hugely confusing. So, peripheral and central are more or less understandable. This would be the peripheral if it was being connected to by a computer like a central or by a phone that's a central. But then it starts calling, your phone that's actually doing the connecting would be called the client or the master or it's a bit messed up. But basically, your phone starts pushing things every so often. And these are very, very compressed. So this might happen, maybe two times a second, but happen for like a fraction of a millisecond. So it's drawing very little power, and it's not completely hogging the Bluetooth spectrum. What it means when you're actually connected, is that you've got these things exposed. You've got services that are like a, a thing that the device does. If you've got a Bluetooth Low Energy light bulb. It will have a light bulb service but it might also have a firmware update service. And that service will have characteristics, like the light bulb might have the brightness, it might have the colour, it might have whether it's on or off as a different characteristic. And there's kind of a standard produced by the guys that make the chips for these that's a serial port. And that's just got transmit and receive characteristics so you can just push data backwards and forwards quite easily. And to do this, this is finally the actual Web Bluetooth code, it'll be a bit hard to see, but you do navigator dot bluetooth dot request device and then you give it a set of filters which it uses to filter down all the devices it sees. And then display a little picker on the screen where you have to choose the device you want to connect to. So it can't just randomly connect to stuff without your authorization. And then you say get the service and this UUID is actually the same one that was up here. And then you're using promises and after that you do get characteristic. So all of this stuff is kind of asynchronous. And then when you've finally done that, you can say LED dot set. This works fine, but there are issues with for instance, Bluetooth has limits on the maximum size of characteristic you can write. So if you try to write more than I think, 20 characters here, it would fail. So I've come up with a little library that kind of handles some of those edge cases and just makes it really easy. So you can just write an html file, you can put two buttons in, you just include the library and you say dot write and then whatever you want to do. So if I try and find the example of this, now this is where we hope it works because Linux isn't amazing at this, at Web Bluetooth at the moment. Macs are great and I'm sure most of you have Macs. So okay, we'll choose this one. I'm sure there are a lot of Bluetooth devices in this room. But it's only showing the ones that match this specific filter that's in this file, which is basically devices that have a serial port. So if I try and pair to this, hopefully, you ee the light's lit up, you can do some much more interesting stuff with this as well. So it's not just sending single commands. You can upload code, you can do full debugging, you can get data back as well. So, one example I have which again may work, may not work. Okay. Please work. Almost, okay. So this is, at home I have a bunch of tomato plants and I have one of these that's actually connected up, there are some little pins on here that you can solder to. So it's connected up to a little flow monitor that turns water on and off and turns an actual feed on and off for some tomato plants at home. So I have this, this is just a website that's really quite basic. Is that on? Yeah, okay. So there's not very much in it at all it's just using a little library to display the dashboard and then it gets the data back. And all it has to do to get the data back is, where are we? So it sends a command to execute. Which is basically just returning JSON, which is then parsed and comes back and we can just basically put the data back into these values here. Now if it was working a little better, it would have actually displayed the data there. But it still pulled up the battery percentage and hopefully if this was working, yeah it still would be able to turn the pump on and then this would actually go and I've shortened all the times 'cause it would usually be on for a few minutes, but after a few seconds it should then turn that light off of its own accord. So it's like a really nice easy way to just make stuff very quickly without having to do anything platform specific at all. And this, the Web Bluetooth it works on Linux, works on Mac OS, Google have said they're trying to get it going for Windows as well, but there's actually someone else has produced a kind of hack to get it working. It works for Android and there's also an app called Web BLE that lets you make it work on iOS because it's not built in the OS web browser yet. So you can do also other stuff, like this web ID, but I'm basically out of time, so you can do, a lot of people ask, how do you connect to the internet? And the answer is really that there's, this is kind of designed for device to device communication rather than actually giving it over an internet connection. There are kind of, things that people are working on at the moment, but this is a standard type of service and you basically, if the device implements this service, it provides a proxy server that lets you get on the internet. And there's something on the Espruino Get Help Repository that you can run on Raspberry Pi which exposes this service and then you can let any Bluetooth Low Energy device, it doesn't have to be the Espruino based ones, access the internet. If you don't want to do that, there are devices with WiFi on them already. You've got this switch is the Espruino board which'll do HTTPS and some other stuff. This thing is the ESP866, which is quite an interesting device, 'cause it's a very cheap WiFI enabled microcontroller. These things cost around 2 pounds in volume. And if you buy them like one off from Ebay, they're like 5 pound delivered. And that will run JavaScript with kind of the same API. There's this sort of node like API with a HTTP library where you do get, you can create a web server, and you can do some really interesting things with these. And I say, they're ridiculously cheap. So, you can make loads of stuff with them. I mean, I've only shown lights flashing on and off 'cause it's only half an hour. But it's got a graphics library, it's got GSM, you've got WiFi, you've got Ethernet support, you can, like, all kinds of sensors. This is just a few of them from ages ago. But yeah, loads of stuff. And I have a book coming out actually, with making random, sort of Blue Peter style machines, but where you use a microcontroller to make what's actually a really dodgy machine do something that's quite fun and quite interesting. So like this is actually just printed out using a block of wood and aluminium poles, some fishing wire and some cheap step motors from Ebay. So I'm also giving a talk at Fullstack in a few weeks, I think. And NodeConf I'll be doing a talk and a workshop which'll be really cool, but I'm not allowed to say why yet. And yeah, this is me, I'll be hanging around for a bit, if anyone's got any questions now, or are we out of time? - [Man] You said that Bluetooth stuff was having trouble here, but you said it works better on Mac, not on Linux, do you know why that is? - Mainly it's a library called Blues, so the Google team have actually put a whole bunch of effort into that for the Chromebook and on the Chromebook it works pretty well. But it's still difficult getting that back. And it's still basically, 'cause the Google developers are pushing this and they haven't really put that much effort into Linux. It was kind of a side effect of them having done Chromebook. But at the same time you've got, you've actually got functionality built into Node as a Node.js library. So if I try and list things here, hopefully, yeah, it'll be able to connect really, really easily now I think. It's kind of specifically Chrome stroke Blues interacting. Okay, maybe it's not that good. But yeah, also this laptop's not great for Bluetooth connections.