BLOG

WebUSB and JavaScript Robotics

One of the fun tasks in building a Web-based IoT Platform is figuring out ways to connect browsers directly to hardware.

Our first iteration of this concept was through the use of a chrome browser extension which lead to the creation of our Chromebots app. This extension uses chrome's serial API to talk to arduinos and utilizes the johnny-five library. This has been a great way to get started with JavaScript robotics and works anywhere Chrome does, including Chromebooks. Until we get an implemetation of Web Serial, a chrome extension is still the way to go for this.

chromebots

So what other browser-based hardware options do we have?

WebUSB

usb

A newer API being implemented in browsers is WebUSB. While direct browser access to a USB device might sound scary, there's a few precautions in place to keep this secure.

  • The device's firmware itself must specify which URLs can access it.
  • The URLs must be secured with HTTPS, or running on localhost for development.
  • The user must explicitly give permission to ineract with the device via a browser dialog.
  • The dialog must be shown after the user initiates a DOM event (button click).

Getting Started

Reilly Grant of Google has put together an adruino library for developing WebUSB peripherals using Arduino Micro or Arduino Leonardo boards. Unlike the Uno or Nano boards, these have the ATmega32U4 chip required for making USB peripherals.

Micro Leonardo

Having the ability to send data back and forth to a piece of hardware is the first step in using JavaScript robotics commonly referred to as nodebots. Typically an Arduino Uno with the StandardFirmata.ino sketch, node.js, node-serialport, and firmata.js are used under the hood by johnny-five as a quick way to get started building nodebots.

Now we can leverage WebUSB as a new transport from the browser!

webusb-serial

I've put together a webusb-serial npm module to act as the data transport in place of node-serialport. There's a few things to do to use this. As an example, let's get an Arduino configured and connect it to our PageNodes web-based IoT platform:

  • First setup the WebUSB arduino library according to the instructions in the readme, including setting the flag in chrome to enable WebUSB.

  • Instead of using the rgb example sketch, let's open StandardFirmataWebUSB.ino in the arduino IDE and upload it to the device.

  • Next, you can either run pagenodes locally from the instructions in the pagenodes repository or simply go to https://PageNodes.com.

  • From there you'll need to create a johnny-five node and create a new nodebot of type firmata and tranasport of webusb. You'll also need to authorize the Arduino by clicking the Authorize USB button.

Authorize WebUSB

Inside your nodebot function you have full access to the johnny-five API as well as the rest of PageNode's functionality !

pagenodes

The code in your johnny-five node is what executes when the board is ready. You can try something as simple as:

var led = new five.Led(9);

led.blink(500);

as well as handling input from other nodes:

node.on('input', function(msg){
    //do some cool robotics stuff with the msg input!
});

Here's a demo of it running:

Here's the code used in johnny-five node in the video:

var r = new five.Pin(9);
var g = new five.Pin(11);
var b = new five.Pin(10);

var previousButtonState;

node.on('input', function(msg){
    if(msg.payload && msg.payload.buttons){

        var buttons = msg.payload.buttons;
        var updated = !_.isEqual(buttons, previousButtonState);
        previousButtonState = buttons;

        if(updated){

            if(buttons[9].pressed){
                r.high();
            }
            else{
                r.low();
            }

            if(buttons[1].pressed){
                g.high();
            }
            else{
                g.low();
            }

            if(buttons[2].pressed){
                b.high();
            }
            else{
                b.low();
            }
        }
    }
});

Gotchas

You might have to restart your arduino in order for your pagenodes flow to reconnect to the device. Click the reset button on the device, and reload pagenodes when you deploy changes. Hopefully we'll get that bit sorted soon.

-Luis