Wednesday, June 25, 2014

Using Javascript with Bonescript to program the Beaglebone Black

In this blog so far I have used Python for all programming examples however we are not limited to Python.   We can use many different programming languages to program the Beaglebone Black.  The “Offical” language for the Beaglebone Black is Javascript with the BoneScript library.  BoneScript is a Node.js library that is optimized for the BeagleBone and features Arduino function calls.  Since I am more familiar with Javascript than Python, I figured I would give BoneScript a try. 

Whenever we first dive into a new language or environment, we usually show the typical “Hello World” example.  I know I dislike the Hello World example too but it does show the basics of how Node.js, JavaScript and the BeagleBone Black work together.  If you are familiar with Node.js and Javascript, you can skip the Hello World section.

Hello World:

We will begin by connecting to the BeagleBone Black.  You can connect to it using SSH or by connecting a monitor/keyboard/mouse to the BeagleBone Black.  Once you get connected, open up a file called helloworld.js and insert the following line of code:

console.log("Hello, I am trapped inside");

Now run the following command:

node helloworld.js

This should print out the line “Hello, I am trapped inside”.  The console.log function simply prints out the message to the console.  In this case the console is the Linux shell that we are in.  We used the node command, from Node.js, to execute our Javascript code. 

First BoneScript script:

Now that we got the Hello World example out of the way, let create something somewhat useful.  The BeagleBone Black has four onboard user LEDs.  Lets make one of the user LEDs blink.  Here is the code:

var b = require('bonescript');

var ledPin = "USR3";

b.pinMode(ledPin, b.OUTPUT);
var state = b.LOW;
b.digitalWrite(ledPin, state);

setInterval(toggle, 500);

function toggle() {
    if(state == b.LOW)
        state = b.HIGH;
    else
        state = b.LOW;
    b.digitalWrite(ledPin, state);
}

The require function loads Node.js libraries/modules, therefore the first line loads the BoneScript library.  Next we define a variable named ledPin that conatins the string “USR3” which refers to the onboard LED USR3.

We then use the pinMode function to set the ledPin to b.OUTPUT.  This allows us to write to the pin.  Setting a pin to b.INPUT, means we want to read from it.  We now define our state variable to b.LOW and use the digitalWrite function to set the ledPin to low which turns the led off.

Once we have the ledPin configured and turned off, we use the Javascript function setInterval to call the toggle function every half a second.

The toggle function checks to see what the state is (b.LOW or b.HIGH) and reverses it.  The function then uses the BoneScript function digitalWrite to set the ledPin to the new state.

If we run the application using Node.js, the USR3 led will blink on and off until you stop the application with Ctrl-C.

Controlling an LED with the push of a Button

Now that we know how to use the BoneScript library, lets do something that is actually useful.  Let’s connect a LED and a button to our BeagleBone Black and turn the LED on when then button is pressed.

First thing we need to do is to wire up the button and the LED.  Whenever you connect items to your BeagleBone black, it is a very good idea to disconnect the power first.  Using a solder-less breadboard and jumper cables, connect the ground rail of your breadboard to pin 1 of the P9 expansion header.  Then use another jumper to connect the power rail of your breadboard to pin 3 of the P9 expansion header.  This will connect your breadboard to both power and ground.

Now lets add the LED to our breadboard.  Connect the cathode end of the LED (shorter wire) to the ground rail of our breadboard and then connect the anode end of the LED (longer wire) to one of the rows on our breadboard.

Now take the 100 OHM resistor and connect one end to the row on the breadboard that the LED is connected to and the other end of the resistor to another row on the breadboard.  Finally run a jumper from pin 8 of the P8 expansion header to the row that the 100 OHM resistor is connected too.  Now that our LED is connected, lets connect the button.

You will want the button to straddle the middle section as show in the image below.  Using a jumper, connect the power rail of your breadboard to one end of the button.  Next connect the same end of the button to the ground rail of your breadboard using the 10K pulldown resistor.  Finally connect the other end of the button to pin 11 of the P8 expansion header.  The connections should look like this image but hopefully you did a neater job hooking up the wires then I did.



Now lets write our Bonescript code to make the LED turn on with the push of a button.

var b = require('bonescript');

var ledPin = "P8_8";
var buttonPin = "P8_11";

b.pinMode(ledPin, b.OUTPUT);
b.pinMode(buttonPin, b.INPUT);

b.attachInterrupt(buttonPin, true, b.CHANGE, buttonChange);

function buttonChange(button) {
    if(button.value == b.HIGH)
            state = b.HIGH;
        else
           state = b.LOW;
    b.digitalWrite(ledPin, state);
}

We begin by loading the Bonescript library and defining the ledPin and buttonPin variables that define what pins the LED and Button are connected to on the BeagleBone Black.  P8_8 defines that the LED is connected to pin 8 of the P8 header and P8_11 defines that the button is connected to pin 11 of the P8 header.

We use the pinMode function to set the ledPin to b.OUPUT which means we want to write to the pin.  We set the buttonPin to b.INPUT because we want to read the pin.

We then use the attachInterrupt function to define an interrupt whenever the buttonPin changes.  If we used b.RISING or b.FALLING instead of b.CHANGE, the interrupt would be triggered only when the pin went high or low.  The last argument in the attachInterrupt function defines the function to call when the interrupt is triggered; in this case the function to call is the buttonChange function.

The buttonChange function sets the led pin to either b.HIGH or b.LOW depending on the state of the button.


Using Node.js to load external Javascript files

To create really useful applications for the BeagleBone Black, like robots or home automation applications, we will need to use multiple files to organize our code but Javascript is not designed to include one Javascript file in another Javascript file.  Node.js can help us with this problem.   Lets begin by creating a Javascript file called hello.js that includes both a variable and a function that we will use in another Javascript file.

var name = "JON"

function sayHello() {
      console.log("Hello World");
}
module.exports.sayHello = sayHello;
module.exports.name = name;

This file defines the variable name and the function sayHello.  We then use module.exports to expose the internally scoped function and variable. 

Now lets look at how we would use the name variable and the sayHello function.

var hello = require("./hello.js")
console.log(hello.name);
hello.sayHello();

We begin by using the require function to include the hello.js file that we just wrote. We can then use the hello variable to access the name variable and the sayHello function.

Cloud9 IDE

I know the Angstrom distribution comes with a Javascript IDE called Cloud9 preinstalled (not sure about the other distributions).  To use Cloud9, open a web browser and enter the IP address of your BeagleBone Black with port 3000 as the URL.  For example, if the IP address of your BeagleBone Black is 10.0.1.18, the URL would look like this:  10.0.1.18:3000.  The IDE interface looks like this.



Personally, I do not really care for Cloud9 so I have not used it that much but I did want to mention it here in case you wanted to give it a try.

Conclusion


Personally I like Javascript but I do believe that I can do a lot more with Python, like including Bluetooth communication, than with Javascript however for projects that do not need access to external hardware components like Bluetooth adapters or cameras, I might give Javascript/BoneScript a try.

2 comments:

  1. Have you tried the new Cloud9 IDE with the Debian images? http://beagleboard.org/latest-images

    ReplyDelete
  2. No I have not. When I received my second BeagleBone Black (Rev C) I tried to get one of my Bluetooth adapters to work with the latest Debian image but was unsuccessful. Bluetooth support is the main reason that I am sticking with Angstrom right now. Currently I have one BeagleBone Black tied up with my robot and the other with the remote control (that communicate over bluetooth), so I really can not re-image either one right now. Has the IDE been improved since the Angstrom image was made?

    ReplyDelete