BeagleBone Black and Pulse Width Modulation (PWM),
Controlling a Servo Using HTML5, JavaScript, and Node.js.
Part 5 of 5

In the previous post we set up a Node.js WebSocket server on the BBB, and automated the process of setting the run, period, and duty cycle.

In the final post of this series we will create an HTML5/JavaScript web client that will communicate with the BBB via a WebSocket connection in order to turn the servo.  The source code for this post can be downloaded from Github.

To better organize our code we’ll use AngularJS for our JavaScript framework, and Bootstrap for our CSS framework in order to take advantage of some predefined styles and user interface widgets.  The web page is very simple consisting of the following:

  • two buttons to turn the servo on and off.
  • slider to turn the servo.
  • dynamic text field displaying messages received from the WebSocket connection.

servo_web_client

Figure 1

Setting up the Controller and View

First, let’s set up our controller logic in web-socket-controller.js to handle button clicks, slider events, and make a WebSocket connection with the BBB.  The first half of the code establishes a WebSocket connection:

Make sure to set the host variable to the correct IP address assigned to your BBB if you have it connected to your network via ethernet or wifi.  Otherwise, use the standard, 192.168.7.2, address if the BBB is tethered to your computer via the USB cable.

Next thing our controller will do is listen for slider events and button clicks, and send the values over the WS connection to the BBB:

That’s it for our controller, now lets move on to the HTML.  Slider for Bootstrap is nice Bootstrap themed slider that we’ll use for turning the servo:

The above markup allows us to declaratively specify the min, max, and step values for the slider.  I empirically determined the above values for my servo/BBB combination, so feel free to experiment with your own setup.  Lets also add two buttons to turn the servo on and off:

Finally, we’ll complete the html by displaying any status messages we receive from the WS connection at the top of the page:

Running the Web Client

First thing to note: we will not run the web client from the node server running on the BBB. Instead, this implementation focuses on making a cross-domain connection with the BBB which is what makes WebSockets so exciting!  That being said, we need to run a web server from another computer that will host our web client.  Included in the websocket-client project directory you’ll find a simple node web server, web-server.js.  Make sure you have node installed and then run it command line as follows:

The web server defaults to running on port 8000, but you can easily change the port by editing line 9 in web-server.js:

Open up a web browser and point the URL to:

You should see a page identical to Figure 1 above.  That’s it, If all went well you should be able to turn the servo using the slider!

Extending AngularJS Controllers Using the Mixin Pattern

In this post we are going to look at extending the functionality of AngularJS controllers using the mixin pattern.  While developing large scale applications it is desirable to break out general functionality into base controllers that can be used across multiple controllers. In addition, the mixin pattern provides a great deal of flexibility to not only inherit instance methods and properties, but $scope properties and methods as well.  Examples used in this post can be downloaded from GitHub.

A quick look at prototypal inheritance

A great way to extend the functionality of JavaScript objects is to use prototypal inheritance.  Lets begin with a simple example using cats and dogs, and create a base class that describes common properties across all animals.  Animals vocalize to one extent or another so lets start with defining the following base Animal class:

Since dogs vocalize by barking, we can inherit from Animal using the following declaration:

And cats meow:

Now we can instantiate Dog and Cat and invoke the vocalize method:

Lets move to AngularJS controllers. Suppose we have a DogController, and we want it to inherit from Animal as we did above. It would be tempting to do something like this thinking our controller has the instance method, “vocalize”:

Sadly we would run into, “TypeError… has no method ‘vocalize’”, once our $scope.bark() gets invoked.  The reason for this error is simple.  Angular controllers do not get instantiated, and without an object instance, no instance methods get inherited from the prototype’s properties.  The developer guide states, “Note: … controllers are not instantiated directly by Angular, but rather are applied to the scope object.”

Applying mixins with angular.extend

Luckily we have options, and a very good one is to use mixins.  I highly recommend reading these excellent posts on using JavaScript mixins:

In short, the mixin process is very simple and consists of copying the properties of one object to another. Here is AngularJS’s implementation of “mixing in” functionality from source object(s) to a destination object using the extend method:

The mixin pattern provides a great deal of flexibility by allowing us to not only “inherit” instance methods and properties, but $scope properties and methods as well.  Lets create a base AnimalController that applies these scenarios:

Now we can mixin AnimalController into DogController:

And then use DogController in our template:

What about Angular services?

You might be asking why not just use Angular services?  Services are great, I use them all the time, but primarily for the purpose of sharing information across controllers via dependency injection.  I don’t believe in passing a $scope object into a service to augment controller behavior.  That practice violates encapsulation, and completely exposes your controller logic to potentially dangerous conditions.  That being said, you could invoke a service method using call/apply with $scope as the context, for example:

BeagleBone Black and Pulse Width Modulation (PWM),
Controlling a Servo Using HTML5, JavaScript, and Node.js.
Part 3 of 5

written by Babak Parvizi

In the previous post we configured pin 13 on the P8 header of the BBB for PWM. Lets get familiar with the device path and how to set the run, period, and duty cycles along with connecting a micro servo to our BBB.

Device Path and Setting Period, Run and Duty

In order to control the PWM signal on P8 13 we need the ability to specify the period, run, and duty cycles.  The last configuration step enabled us to do that by creating a new device folder:

Notice, the placeholders, “#”, after the “ocp.” and “pwm_test_P8_13.”  The numbers assigned to those locations will differ depending on the BBB device.  For example, my BBB has the numbers “2″ and “10″, respectively:

Taking a closer look at the device folder reveals how we can set the period, run, and duty cycles:

Notice the files, “duty”, “period”, and “run”.  All we have to do is write to these files to set their values.  This can be done command line, for example, to set the period to a value of “5000000″:

However, we are not interested in manually setting these values.  Just note the device path specific to your BBB for now, as we will use Node.js and JavaScript to automate writing to these files in the next post:

Connecting a Micro Servo to Pin 13

Lets connect a Micro Servo, model 9g A0090, to the BBB with following connection points:

  • Power line to pin 3, P9 header 3.3V
  • Ground line to pin 1, P9 header
  • PWM line to pin 13, P8 header

BBB-MicroServo
(Click to enlarge)

Next- BeagleBone Black and Pulse Width Modulation (PWM), Controlling a Servo Using HTML5, JavaScript, and Node.js. Part 4 of 5

BeagleBone Black and Pulse Width Modulation (PWM),
Controlling a Servo Using HTML5, JavaScript, and Node.js.
Part 4 of 5

written by Babak Parvizi

In the previous post we learned about the device path and how to set the run, period, and duty cycle along with connecting a micro servo to our BBB.  In this post we will set up a Node.js WebSocket server on the BBB, and automate the process of setting the run, period, and duty cycle.

WebSocket Server Using Node.js and the WS Library

Our next major step is to setup a Node.js WebSocket server on the BBB in order to communicate with an HTML5 web client. WebSockets are extremely powerful as they allow real-time communication between client and server in a seamless bidirectional manner.  Node.js comes preinstalled on the BBB Angstrom Linux distribution:

The WebSocket server code can be downloaded from Github, and then run using the Cloud9 IDE. First, lets create a new project folder called ‘websocket-server’ under the Cloud9 directory, “/var/lib/cloud9/”:

initialize a new git repo from the “websocket-server” directory :

Now pull down the code:

Once the code has been downloaded navigate to the “beaglebone-black/bbb-pwm/” folder:

We only need to be concerned with the following in the above project folder:

  • bbb-pwm.js- JavaScript file for controlling PWM and setting the period, run, and duty cycle.
  • websocket-server.js- JavaScript file for running the Node.js WebSocket server.
  • node_modules- Directory containing the project dependencies.

websocket-server.js uses the WS module to create a Node.js WebSocket server running on port 8080:

Our new server instance can handle connections as well as send and receive messages:

Lets take a closer look at this line:

In the last section we mentioned we would automate the process of writing the values for the period, run and duty cycle using Node.js and JavaScript. The bbb-pwm.js module provides this functionality, and we begin by instantiating a new instance of the bbbPWM function by passing in the device path we noted earlier along with the period.  The WebSocket is configured to receive 3 types of messages:

  • servoOff- sets the run path to 0.
  • servoOn- sets the run path to 1 (instantiating a new instance of  bbbPWM automatically sets the run path to 1).
  • duty cycle values- sets the duty cycle to the particular value passed in.

 Lets test our WebSocket server by running it in the Cloud 9 IDE. Navigate to  ”http://192.168.7.2:3000/”.  Find the project folder we set up from the git download, open websocket-server.js, and hit the run button.  You should see the following:

Cloud9-pwm
(Click to enlarge)

Our WebSocket server is running and ready to handle connections! In the next post we will create an HTML5/JavaScript web client that will make a WebSocket connection with our BBB and turn the servo!

Next- BeagleBone Black and Pulse Width Modulation (PWM), Controlling a Servo Using HTML5, JavaScript, and Node.js. Part 5 of 5

BeagleBone Black and Pulse Width Modulation (PWM),
Controlling a Servo Using HTML5, JavaScript, and Node.js.
Part 2 of 5

written by Babak Parvizi

In the previous post we got acquainted with the project overview, and made sure our BBB was running the latest Angstrom Linux distribution. Now we will configure the BBB for PWM!

Configuring Pin 13 on P8 Header for PWM

The BBB was specifically designed to be a dynamic piece of hardware, enabling third-party developers to create their own custom configurations and extensions known as capes. The board is so flexible, it can change its hardware configuration at runtime using an in-kernel mechanism known as the Cape Manager in conjunction with Device Tree Overlays.

The Device Tree consists of a set of human readable text files known as DTS files that end in the “.dts” extension.  DTS files can be edited using a simple text editor to set the configuration for a particular pin. These source files then get compiled into DTB files, a binary format ending in the “.dtbo” extension.  This process creates what are known as device tree fragments or overlays.  The kernels Cape Manager can then dynamically load and unload the DTB files post-boot as well as at runtime to set the hardware configuration.  For a more in-depth look on how to use device tree overlays, I highly recommend the following resources:

Luckily for our purposes, creating a new overlay for configuring PWM is not necessary.  Turns out a set of overlays are already present in the “/lib/firmware” directory:

All we need to do is load them using the Cape Manager, but first, lets get acquainted with a very useful command that will help us determine if our overlays were properly loaded:

Out of the box, the BBB shows the above slots.  Lets add two more slots to configure pin 13 on header P8 for PWM by executing the following commands:

To confirm the overlays loaded properly we run the slots command again:

Our board is now configured for PWM on pin13 of the P8 header!  Before we move on, however, it’s worth noting these changes are not permanent.  If you power off the board, the PWM slots we just added will disappear.  Thankfully, we don’t have to repeat the above steps each time we power up the board.  The Cape Manager supports a method to load the overlays at boot time by adding the following argument to the “uEnv.txt” file:

Make sure to append the argument in a single line like this:

In the next post we will get familiar with the device path and how to set the run, period, and duty cycles along with connecting a micro servo to our BBB.

Next- BeagleBone Black and Pulse Width Modulation (PWM), Controlling a Servo Using HTML5, JavaScript, and Node.js. Part 3 of 5

BeagleBone Black and Pulse Width Modulation (PWM),
Controlling a Servo Using HTML5, JavaScript, and Node.js.
Part 1 of 5

written by Babak Parvizi

A couple of years ago I attended Google I/O where they unveiled the Accessory Development Kit (ADK), which enabled Android developers to start interacting with hardware devices such as the Arudiuno. It had been a while since I felt excited about something, and this really got my attention. Having been primarily a front-end software developer, I had never heard of the Arduino or microcontrollers before, but Christmas was about to come early. The generous people at Google gave us all Arduino ADK boards, and I couldn’t wait to get home and start learning this new world that I had never experienced before.

I started with the “Hello World” equivalent for electronics by making an LED blink.  I learned how to turn a servo, made noise using a piezo, and so on.  It was then time to visit Radio Shack and start experimenting with more advanced sensors like a rangefinder and infrared sensors. Arduino made these experiments easy as the sketches were readily available, and it was just a matter of plug and play.

Ultimately, my goal was to be device and platform agnostic.  I didn’t want to be constrained to just Android devices, and I desperately wanted to expand my efforts to the iPhone or any other device of my choosing.  Unfortunately, Apple turned down my application for the MFi licensing program, and my hopes to connect the Arduino to my iPhone via the 30 pin dock connector or Bluetooth quickly evaporated.  I turned my efforts to using the ethernet and the wifi shields, but found communication via HTTP to be too limiting and underperforming.  Feeling restricted, I quickly grew disenchanted and lost interest.

A lot has happened in the last couple of years, however, that has re-sparked my interest and enthusiasm.  Small, faster, affordable microcomputers running embedded Linux have emerged like the BeagleBone Black (BBB).  Server-side Javascript using Node.js has taken web technologies by storm, enabling devices like the BBB to seamlessly run a web server out of the box in a non-blocking I/O fashion.  Open Web Standards continue to push the capabilities of HTML 5 devices, allowing mobile phones and tablets to communicate with external accessories like the BBB without the need for proprietary technologies or licenses.   

In this series of posts we are going to configure the BeagleBone Black (BBB) for Pulse Width Modulation (PWM) in order to operate a micro servo. We’ll then control the servo using an HTML5/JavaScript web client that will communicate with a Node.js WebSocket server running on the BBB. Here it is in action:

Update to the Latest Angstrom Distribution

First, make sure your BBB has the latest Angstrom distribution installed. You can find the distribution information using the following command once you ssh into the board:

The latest distribution at the time of this post was Cloud9 GNOME Image 2013.06.20. Here are some really excellent tutorials on updating to the latest image:

In the next post we will configure our BBB for PWM!

Next- BeagleBone Black and Pulse Width Modulation (PWM), Controlling a Servo Using HTML5, JavaScript, and Node.js. Part 2 of 5