Sunday, July 27, 2014

Comparing the BeagleBone Black and the Spark Core: Remotely turning on an LED



After writing the Spark Core iOS library I started thinking more about being able to control the BeagleBone Black from my iOS devices.  The BeagleBone Black does not have built in Wi-Fi but I normally have my spare BeagleBone Black (non-robot one) connected to my Wi-Fi router with a network cable.  So I started asking myself; how could I control my spare BeagleBone Black from my iOS device with it connected directly to my router?  The answer came in the form of socket.io and bonescript.  

Lets look at how we can use socket.io with bonescript to control one of the user LEDs on the BeagleBone Black.  I used the Cloud9 IDE to write this application so the first thing that I needed to do was to install socket.io where Cloud9 can use it.  To install socket.io run the following commands (Note: I am using Agnstrom Linux, you may need to adjust the paths depending our you flavor of Linux):

cd /var/lib/cloud9
npm install socket.io

Once socket.io is installed, we can open the Cloud9 IDE in our favorite web browser by going to port 3000 of our BeagleBone.  You can do this by opening your favorite browser and entering the IP Address of your BeagleBone followed by colon and 3000 IE:  10.0.1.18:3000. 

Now that we have everything setup, lets write the application to control one of the user LEDs on the BeagleBone black.  In the Cloud9 IDE, create a folder called “RemoteLED”.  We will be creating two files within this folder called toggleled.js and index.html.  Lets look at the toggleled.js file first:

var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
var fs = require('fs');
var b = require('bonescript');

//Set socket.io to listen on port 2080
app.listen(3080);

//my constants
var ledPin = "USR3";
var STATEON = b.HIGH;
var STATEOFF = b.LOW;

//called to initilize the device
setup = function() {
    b.pinMode(ledPin, b.OUTPUT);
    b.digitalWrite(ledPin, STATEOFF);
};

//function called to setup our page
function handler (req, res) {
  //load our index.html page
  fs.readFile('RemoteLED/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading page');
    }

    res.writeHead(200);
    res.end(data);
  });
}

//on method listener
io.sockets.on('connection', function (socket) {
  socket.on('led', function (command) {
    console.log(command);
    if (command == 'on'){
        b.digitalWrite(ledPin, STATEON);
        socket.emit('ledstatus', 'LED is on');
    }else{
        b.digitalWrite(ledPin, STATEOFF);
        socket.emit('ledstatus', 'LED is off');
    }
  });
});

We begin by adding the external modules needed using the require function that comes with node.js.  Next we set socket.io to listen for requests on port 3080 and define three constants.

The setup function is called when the application starts up.  It initializes the LED pin and also turns the LED off so the LED will begin in the OFF state.   The handler function is called when a HTTP request comes in and sends the index.html page, which we will look at shortly, to the client. 

Finally we add an “on” method listener that listens for incoming actions.  In this example, we listen for the ‘led’ action and when a ‘led’ action is received it runs the inner function.  This inner function will turn the LED on if it receives the “on” command otherwise it will turn the LED off.  It also uses the emit function to send a ‘ledstatus’ action back to the client with the current status of the LED.

Now lets look at the index.html file. 

<html>
<head>
    <style>
        .button {height:100px;width:140px;font-size:34px;margin-left:30px;margin-top:50px;}
        .status {font-size:34px;margin-top:50px;margin-left:30px;}
    </style>
    <script src = "/socket.io/socket.io.js" > </script>
    <script>
        var socket = io.connect();
            socket.on('ledstatus', function (data) {
                console.log(data);
                var statusDiv = document.getElementById("status");
                statusDiv.innerHTML = data;
            });
    </script>
    <script>
        function ledOn(){
            socket.emit('led', 'on');  
        }
        function ledOff(){
            socket.emit('led', 'off');
        }
    </script>
</head>

<body>
    <input type="button" name="on" id="onButton" class="button" value="ON" onClick="ledOn();">
    <input type="button" name="off" id="offButton" class="button" value="OFF" onClick="ledOff();">
    <div id="status" class="status">LED is off</div>
</body>
</html>

The interesting parts of this page are between the two “script” tags.  In the first “script” tag we set up a listener that listens for an ‘ledstatus’ action and when it is received it will call the inner function that sets the status label to the message that was received.  This action is sent from the toggleled.js script with the following command:  socket.emit('ledstatus', 'LED is on'); 

The second ”script” tag contains two functions.  These functions are called when the on and off buttons are pressed and uses the emit function to send a ‘led’ action back to the listener in the toggleled.js script that turns the LED on or off.

If you run this code within the Cloud9 IDE you should be able to control User LED from any computer or mobile device that can connect to the BeagleBone Black.  The web page should look like this: 



Now lets look at how we would control the User LED on the Spark Core. I will use Spark’s standard tools and then write an iOS app using my Spark Core – iOS Library that will control the User LED on the Spark Core.  If you do not know how to use Spark’s IDE or flash the Spark Core, please refer to Spark’s getting started page.

Lets begin by looking at the code that we will flash to the Spark Core:

int userLed = D7;
int ledStatus = 0;

void setup()
{
   Spark.function("led", ledController);
   pinMode(userLed, OUTPUT);
   Spark.variable("ledStatus", &ledStatus, INT);
}

void loop()
{
   //doing nothing
}

int ledController(String param)
{
    if (param == "on")
   {
        digitalWrite(userLed, HIGH);
        ledStatus = 1;
        return 1;
   }

    if (param == "off")
    {
        digitalWrite(userLed, LOW);
        ledStatus = 0;
        return 1;
    }
    return -1;
}

In the setup function we begin by making the ledController function available through the Spark cloud by using the Spark.function.  We can send information to the ledController function using a POST request from our client. We also define a variable that can be read using the Spark.variable function using a GET request.  We will turn the LED On or Off with the ledController function and read the LED status from the ledStatus variable.

The ledController function looks at the parameter that was sent in the POST request.  If the parameter is “on”, the function turns the LED on and sets the ledStatus variable to 1.  If the parameter is “off”, the function turns the LED off and sets the ledStatus variable to 0.  If something besides “on” or “off” was sent, the function returns -1.  Once you have the code in Spark’s IDE, you should flash it to your Spark Core.

Now lets look at the iOS application to see how it works.  If you are not familiar with my iOS library for the Spark Core, you can read my blog post about it.  You can download the code from the GitHub repository.  The full source for the iOS application is in the Spark Core GitHub repository under the “SparkComparisonApp” directory.

I do not want to go over the full ViewController class here but I do want to highlight two methods.  

-(void)getStatus {
    SparkTransactionGet *getTransaction = [[SparkTransactionGet alloc] initWithAccessToken:ACCESS_TOKEN deviceId:DEVICE_ID andProperty:STATUS_VAR];
   
    [SparkCoreConnector connectToSparkAPIWithTransaction:getTransaction andHandler:^(NSURLResponse *response, NSDictionary *responseDictionary, NSError *error){
        if(error == nil) {
            NSLog(@"Response: %@",responseDictionary);
            int status = [[responseDictionary objectForKey:@"result"] intValue];
       
            NSString *statusStr = @"off";
            if (status == 1)
                statusStr = @"on";
            _statusLabel.text = [NSString stringWithFormat:@"LED is  %@", statusStr];
        } else {
            NSLog(@"Error: %@",error);
            _statusLabel.text = @"Error Getting Status";
        }
    }];
}

The getStatus method makes a GET request to Sparks Cloud API and retrieves the current status of the LED.  When the status is returned it sets the statusLabel UILabel with the status of the LED.  If an error is returned it sets the statusLabel UILabel to an error message.

-(void)sendRequestWithParameter:(NSString *)parameter {
    NSLog(@"Params: %@",parameter);
    SparkTransactionPost *postTransaction = [[SparkTransactionPost alloc] initWithAccessToken:ACCESS_TOKEN deviceId:DEVICE_ID functionName:FUNCTION andParameters:parameter];
   
    [SparkCoreConnector connectToSparkAPIWithTransaction:postTransaction andHandler:^(NSURLResponse *response, NSDictionary *responseDictionary, NSError *error){
        if(error == nil) {
            NSLog(@"Response: %@",responseDictionary);
        } else {
            NSLog(@"Error: %@",error);
        }
         [self getStatus];
    }];
   
    NSLog(@"Continueing with app");
   
}

@end


The sendRequestWithParameter: method sends a POST request to Sparks Cloud API telling it to turn the LED either on or off depending on what the parameter is.  The parameter should be either “on” or “off” to match the commands on the Spark.  When the response comes back from Spark’s API, acknowledging that the on/off command was received, we then call the getStatus function to retrieve the current state of the LED.

One thing I did notice with the Spark Core is there is a noticeable delay from the time I pressed the on or off button to when the status label was updated.  The delay was less then a second but it was pretty obvious.  I would imagine this delay would not be a problem for most applications but you would just need to account for it.  The response from the BeagleBone Black was all but instantaneous which is what I expected from socket.io. 

Spark’s IDE is all right.  I would definitely rate the Cloud9 IDE above Spark’s mainly because the error messages from Spark’s IDE are really unhelpful.  I wasted a lot of time trying to track down a simple typo.

The architecture of the BeagleBone Black’s application is a lot nicer because the client and server components are contained in one application making it easier to update.  However if you plan on making a commercial product, being able to upload the client application to Apple’s app store would be really nice.

The big advantage that the Spark Core has over the BeagleBone Black is the built in Wi-Fi and it was designed/built to communicate with remote devices.  Spark’s Cloud API is also very easy to use with the REST based API.  Both the BeagleBone Black and the Spark Core have advantages and disadvantages; you will need to see which one fits best with your project.  I will say that I wish the BeagleBone Black had built in Wi-Fi but it does not.





Thursday, July 24, 2014

Spark Core – iOS Library

The only issue we have encountered, using the BeagleBone Black with our robot, is the only wireless communication option is Bluetooth.  I know I can communicate from my laptop to the BeagleBone Black over Bluetooth but we want to control the robot from our iPhone/iPad/iPods.  If you are familiar with Apple’s iOS Bluetooth stack, you know that it is very limited and communicating to custom devices like the BeagleBone Black isn’t really an option.

I could add a WiFi USB adapter but it would draw too much power when I use the EasyAcc Battery Charger to power the BeagleBone Black.  After doing a bit of research, I stumbled on the Spark Core.  The Spark Core is a complete WiFi enabled development platform that is code-compatible with the Arduino.  I believe I can use the Spark Core as a communication module for our robot but the first thing I needed to do was to create an iOS library to communicate with Spark’s Web API because Spark does not currently have one.  You can get the library that I created from my GitHub repository at:  https://github.com/hoffmanjon/SparkCoreIOS.

Lets begin by looking at the classes that make up the Spark Core library.  After the class summaries, I will show how to use the library.  If you download the library there is a complete sample application with it and I will discuss that sample at the end of this post.  The library has two main classes:

- SparkCoreConnector:  This class is the main communication class that handles all communication between an iOS device and Spark’s Web API.  This class expose one static method:  connectToSparkAPIWithTransaction:andHandler:
- SparkTransaction:  This class defines the information that is used to build the URL to Spark’s Web API and also the parameters that we need to send.  This class is meant to be sub classed for each of the transaction types.  This base class exposes three public properties, these are:
- baseUrl – the base URL that is used to build the final URL.  By default this is:  https://api.spark.io/v1/devices.
- accessToken – The access token for your Spark Core.
- deviceId – The id of your Spark Core.

Next lets look at the transaction types that subclass the SparkTransaction class.  Currently I have two types defined in the library:

 - SparkTransactionGet:  This library is used to submit a GET request to Spark’s Web API.  This type of request is used to retrieve data from your Spark Core.  You will need to set the “property” property to the name of the variable you want to retrieve.
 - SparkTransactionPost:  This library is used to submit a POST request to Spark’s Web API.  This type of request is used to submit data/commands to your Spark Core.  You will need to set the “functionName” parameter to the function you want to call and the “parameters” property to the commands you want to send.

Now lets see how to use the library with some sample code.  The code to send a SparkTransactionPost request would look something like this:

SparkTransactionPost *postTransaction = [[SparkTransactionPost alloc] initWithAccessToken:ACCESS_TOKEN deviceId:DEVICE_ID functionName:FUNCTION andParameters:parameter];
   
[SparkCoreConnector connectToSparkAPIWithTransaction:postTransaction andHandler:^(NSURLResponse *response, NSDictionary *responseDictionary, NSError *error){
        if(error == nil) {
            NSLog(@"Response: %@",responseDictionary);
        } else {
            NSLog(@"Error: %@",error);
        }
    }];

We start by creating a SparkTransactionPost object using the initWithAccessToken:deviceId:functionName:andParameters: initializer.  We then call the static connectToSparkAPIWithTransaction:andHandler: method of the SparkConnector class to send the request.

Creating a SparkTransationGet request is very similar to the Post request.  The code looks like this:

SparkTransactionGet *getTransaction = [[SparkTransactionGet alloc] initWithAccessToken:ACCESS_TOKEN deviceId:DEVICE_ID andProperty:COUNT_VAR];
   
[SparkCoreConnector connectToSparkAPIWithTransaction:getTransaction andHandler:^(NSURLResponse *response, NSDictionary *responseDictionary, NSError *error){
        if(error == nil) {
            NSLog(@"Response: %@",responseDictionary);
          } else {
            NSLog(@"Error: %@",error);
          }
    }];

The only difference between the Get and Post requests is we create a SparkTransactionGet object using the initWithAccessToken:deviceId:andProperty: initializer instead of the SparkTransactionPost object.

It is that easy to send requests from you iOS device to your Spark Core with this library.

Lets take a quick look at the sample project that comes with the library.  The first thing we need to do is to wire up two LEDs and flash the Spark Core.  If you do not understand the wiring diagram or the code that needs to be flashed to the Spark Core, please see Spark’s documentation here:  http://docs.spark.io:



Now that we have the LEDs wired to our Spark Core, we need to flash it with the following code:

int ledUser = D7;
int led1 = D0;
int led2 = D5;
int myvar = 0;

void setup() {
    Spark.function("led", ledController);
   
    pinMode(ledUser, OUTPUT);
    pinMode(led1, OUTPUT);
    pinMode(led2, OUTPUT);
   
    digitalWrite(ledUser, LOW);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
   
    Spark.variable("myvar", &myvar, INT);
}

void loop() {
   
}

int ledController(String command)
{
    myvar = myvar +1;
    int ledState = 0;
    int pinNumber = (command.charAt(1) - '0');
   
    if (pinNumber != 0 && pinNumber != 5 && pinNumber !=7) {
        return -1;
    }
   
    if(command.substring(3,7) == "HIGH") ledState = HIGH;
   else if(command.substring(3,6) == "LOW") ledState = LOW;
   else return -2;
   
    digitalWrite(pinNumber,ledState);
   
    return 1;
}

Now lets look at our example application.  If you run the code you will see a screen that looks like this: 



By flipping the switches, you can turn the LEDs off/on.  If you press the count button you will retrieve the number of times the LEDs have been toggled and display that count.

Lets look at the ViewController.m file to see how this application works.  We start by defining a number of constants:

#define ACCESS_TOKEN @"123456789"
#define DEVICE_ID @"my-core"
#define FUNCTION @"led"
#define COUNT_VAR @"myvar"

#define LED_USER @"D7"
#define LED_1 @"D0"
#define LED_2 @"D5"

#define STATE_HIGH @"HIGH"
#define STATE_LOW @"LOW"

These constants are:

ACCESS_TOKEN:  The access token for your Spark Core.
DEVICE_ID:  The device id for your Spark Core.
FUNCTION:  The name of the function that we call in our Post requests.
COUNT_VAR:  The name of the variable to request in our Get requests.
LED_USER:  The pin for the user LED on the Spark Core.
LED_1:  The pin for the first external LED that we connected to the Spark Core.
LED_2:  The pin for the second external LED that we connected to the Spark Core.
STATE_HIGH:  Defines the string for the pin’s high state.
STATE_LOW:  Defines the string for the pin’s low state.

Now lets look at our viewDidLoad method.  This method is called after the view is finished loading.

- (void)viewDidLoad {
    [super viewDidLoad];
       [_led1Switch setOn:NO animated:YES];
    [_led2Switch setOn:NO animated:YES];
    [_ledUserSwitch setOn:NO animated:YES];
    [self getCount];
}

We start off my using the setOn:animated: method of the UISwitch class and set all of the switches to off since our LEDs will be in the off state to begin with.  We then call our getCount method to retrieve the count from the Spark Core.  The getCount method looks like this:

-(void)getCount {
    SparkTransactionGet *getTransaction = [[SparkTransactionGet alloc] initWithAccessToken:ACCESS_TOKEN deviceId:DEVICE_ID andProperty:COUNT_VAR];
   
    [SparkCoreConnector connectToSparkAPIWithTransaction:getTransaction andHandler:^(NSURLResponse *response, NSDictionary *responseDictionary, NSError *error){
        if(error == nil) {
            NSLog(@"Response: %@",responseDictionary);
            NSString *cnt = [responseDictionary objectForKey:@"result"];
            _countLabel.text = [NSString stringWithFormat:@"Count:  %@", cnt];
        } else {
            NSLog(@"Error: %@",error);
            _countLabel.text = @"Error Getting Count";
        }
    }];
}
In this method we create a SparkTransactionGet object using the initWithAccessToken:deviceId:andProperty: initializer. 
We then use the connectToSparkAPIWithTransaction:andHandler: static method to send the request to Spark’s Web API.  For the handler parameter we pass in a block object that will run after Spark’s Web API returns a response.  In the block object we check to see if there was an error.  If there was no error we display the count.  If there was an error we display the error message.  The request created by this method is the same as using curl like this:  curl –G https://api.spark.io/v1/devices/my-core/myvar –d access_token=123456789

Next we need to create methods that will be called when the user flips the switches.  These methods look like this:

-(IBAction)ledUserSwitchAction:(id)sender {
    NSString *pin = LED_USER;
    NSString *state = STATE_HIGH;
    if (_ledUserSwitch.on)
        state = STATE_LOW;
    NSString *param = [NSString stringWithFormat:@"%@:%@",pin,state];
    [self sendRequestWithParameter:param];
}

-(IBAction)led1SwitchAction:(id)sender {
    NSString *pin = LED_1;
    NSString *state = STATE_HIGH;
    if (_led1Switch.on)
        state = STATE_LOW;
    NSString *param = [NSString stringWithFormat:@"%@:%@",pin,state];
    [self sendRequestWithParameter:param];
}

-(IBAction)led2SwitchAction:(id)sender {
    NSString *pin = LED_2;
    NSString *state = STATE_HIGH;
    if (_led2Switch.on)
        state = STATE_LOW;
    NSString *param = [NSString stringWithFormat:@"%@:%@",pin,state];
    [self sendRequestWithParameter:param];
}

Each of these methods does the same thing.  They begin by setting the “pin” NSString to the pin on the Spark Core that we want to set.  We then set the “state” NSString to High or Low depending on the state of the switch.  We use the “pin” NSString and the “state” NSString to create our “param” NSString.  Finally we call the sendRequestWithParameter: method to send the request to Spark’s Web API.  Now lets look at the sendRequestWithParameter: method.

-(void)sendRequestWithParameter:(NSString *)parameter {

    SparkTransactionPost *postTransaction = [[SparkTransactionPost alloc] initWithAccessToken:ACCESS_TOKEN deviceId:DEVICE_ID functionName:FUNCTION andParameters:parameter];
   
    [SparkCoreConnector connectToSparkAPIWithTransaction:postTransaction andHandler:^(NSURLResponse *response, NSDictionary *responseDictionary, NSError *error){
        if(error == nil) {
            NSLog(@"Response: %@",responseDictionary);
        } else {
            NSLog(@"Error: %@",error);
        }
    }];
}

This method begins by creating a SparkTransactionPost object using the initwithAccessToken:deviceId:functionName:andParameters: initializer.  We then call the same connectToSparkAPIWithTransaction:andHandler: static method that we saw in the getCount method.  In the block object that we pass to the handler, we simply log the response from the Spark’s Web API or we log the error depending on if we received an error or not.  The request created for this method is the same as using curl like this:  curl https://api.spark.io/v1/devices/my-core/led –d access_token=123456789 -d params=d0,HIGH


I have just started using the Spark Core so I put in the functionality that I think I need to communicate to my robot.  If anyone has any suggestions or recommendations on what functionality they would like to see in the library, please let me know.  I hope you find this library useful.