Posts tagged with "devices"

Edge Device Discovery - an Unfinished Project

The Team

Team Member Project
Masha Reutovski Project Manager
Bret Stateham BLE Communicator
Gandhali Samant BLE Scanner
Kristin Ottofy Sync Engine
Joe Raio API
Jeremy Foster UI

A diverse group of technical engineers and one project manager from Microsoft’s Commercial Software Engineers (CSE) group. This project was an initiative that Bret Stateham submitted for Sync Week hacks.

Project Overview

This IoT Edge Device Discovery project is built on the Azure IoT Edge service. First, we’ll discuss Edge and then this project’s added value.

Azure IoT Edge

IoT Edge is a service that comes as part of Azure’s IoT offering. It is intended to run on field gateway devices (“edge” devices) and facilitate the aggregation of data from other devices in an on-site IoT solution - devices that may not have the ability to communicate directly with the cloud or for whatever other reason should send their data through a gateway.

Azure’s IoT Edge service is undergoing a big transformation from version 1 to version 2. Version 1 is already in the wild. Version 2 offers some dramatic benefits such as containerized modules that can be run on the edge or in the cloud, but this version is still in private preview and undergoing breaking changes.

In this project, we opted to focus on IoT Edge v1. We are fairly confident that any value added would not be difficult to port to version 2 in case the opportunity arises. We also recognize that IoT Edge v2 may include some functionality that partially or perhaps even entirely overlaps with this project.

IoT Edge v1 offers multiple development paths, including native development in C++, NuGet packages to boot strap .NET development, Maven packages to get started with Java, or npm packages for Node.js developers. We chose to go with the Node.js development path in based on initial research around the noble npm package for access Bluetooth Low Energy (BLE) devices in Node.js.

IoT Edge v1 can be run on a variety of devices and operating systems. For this project, we opted to use the Raspbery Pi 3 running Raspbian Jessie as the gateway device because it was known to be compatible with IoT Edge v1 and had an integrated Bluetooth hardware stack that was known to be compatible with the noble npm package.

Finally, BLE is a popular standard and there are countless devices that could be discovered and communicated with. For this project, we focused on the TI Sensor Tag CC2541 and CC2650 as our reference devices. These sensors have a number of sensors we could leverage and provided a good model for other BLE devices.

IoT Edge Device Discovery

In IoT Edge as it exists today, if a solution administrator needs to pull a new device in to the network to start recording and sending data to the cloud, the process is a bit difficult. The devices that might be added could be speaking various protocols, but for this project we focused on BLE devices.

The current process for bringing new BLE devices into a solution to start getting new data looks something like this…

  • new BLE device is brought into the proximity of the solution
  • admin manually retrieves the device’s MAC address and characteristics array
  • admin adds the MAC address and characteristics to the IoT Edge configuration file
  • admin restarts the edge service

This solution would provide a means for these devices to be discovered automatically and simply approved by solution administrators. The process would look more like this…

  • new BLE device enters the premises
  • Edge service sees the device (including its MAC address and entire characteristics array) and submits it to a cloud service for storage and approval (Edge does not yet begin receiving communication from the device or acting on its reported data)
  • admin is notified and directed to a web portal to approve the device and configure the system’s behavior for using the device’s data
  • admin either clicks approve or deny for the device
  • upon approval, the Edge service begins acting upon data reported from the new device

This system would obviously be extended to support other network protocols besides BLE.

Architecture

In its current state, the solution consists of the following components…

  • BLE Scanner: the BLE Scanner module is specific to the BLE protocol and would be duplicated for other network protocols. The scanner is just another Edge module and constantly scans for BLE devices in the proximity of the gateway’s BLE radio. Upon seeing a device, the scanner reports the device and its characteristics array (the data points the device is capable of communicating) to the Sync Engine (also an Edge module) using the IoT Edge Message Broker. The Sync Engine is not concerned with whether devices have been discovered and reported in the past or whether they’ve already been approved or denied. It simply reports what it discovers.

  • Sync Engine: the Sync Engine is also an Edge module and contains the majority of the business logic for this project. It receives information from the BLE Scanner module about what devices have been discovered nearby, their MAC address, and their characteristics array, and it keeps information about these devices synchronized with the data service in the cloud (via the API). It likely receives duplicate devices from the device scanners, but maintains last known state both locally and in the cloud.

  • BLE Communicator: The BLE Communicator is specific to the BLE protocol and would be duplicated for other network protocols. The communicator is also an Edge module and is responsible for communicating with the entire array of approved BLE devices. This is in contrast to IoT Edge’s default, native BLE module that is delivered with the product, which is only capable of speaking with a single BLE device. The BLE Communicator module maintains configuration on disk as well as in memory and relies on the Sync Engine module to update its configuration and let it know which devices (and which characteristics) it should be communicating with.

  • API: the Sync Engine runs serverlessly as an Azure Function. It provides endpoints for the Sync Engine and UI. The API allows the Sync Engine module to submit newly discovered devices (and their characteristic arrays) or update existing ones. The API then provides this information to the UI. The API is designed as a REST-compliant interface and thus relies on HTTP GET, POST, PUT, and DELETE operations against entity endpoints - the primary endpoint being the list of devices which may be more clearly understood as device approvals.

  • UI: the UI is the only interaction point for solution administrators and allows the admin to determine which discovered devices should be considered by the Edge service, which of those devices’ characteristics should be read, which should be written, and on what schedule (i.e. once, periodically, etc.). The UI obviously relies on the API to ultimately take effect in the Edge service.

Components

The Scanner

Principal Developer: Gandhali Samant

Overview

The role BLE Scanner module, as mentioned above, is to discover BLE devices in range of the IoT Edge v1 gateway device. The module was written using Node.js and leverages the noble (https://github.com/sandeepmistry/noble) npm package. Noble supports both Windows and Linux and is the most popular node.js package for BLE communication. This module is intended to constantly scan for new BLE devices and their characteristics. When a new device is discovered the module generates a new message containing the devices MAC address and GATT characteristics and publishes the message to the IoT Edge v1 Message Broker for consumption by other modules.

Challenges

  1. IoT Edge v1 implementation doesn’t support the use of native Node.js modules. The noble npm package is a native npm package (meaning it has to be compiled for the platform) and we were unable to create an IoT Edge module that tried to load the noble package. The solution was to use the proxy, or remote, module patter as discussed here: https://github.com/Azure/iot-edge/blob/master/samples/proxy_sample/README.md . However, that presented it’s own challenge as discovered in #2.

  2. The Node.js implementation of the out of process proxy module is buried in a subfolder of the IoT Edge v1 GitHub repository and can’t be referenced directly from Node.js We attempted to extract that folder only and create a locally linked npm package to depend on, but ultimately ended up having to move that code into our own repo (https://github.com/bretstateham/azipg) so we could create a dependency on it from our IoT Edge v1 module.

  3. The noble BLE implementation was great in that it was able to discover BLE devices, but it turns out there were hundreds of BLE devices available. We added a MAC address filter to discover and report only on BLE devices with MAC Addresses that started with “54:6c:0e”, the prefix used by Texas Instruments CC2650 Sensor Tags to limit the number of devices we published.

Successes

Once the challenges above were overcome, the module was able to successfully scan and discover the two TI CC2650 Sensor tag devices we had on hand. Once discovered, the details of a BLE device were collected, placed in a JSON payload, and published via the IoT Edge v1 Message Broker.

Future Development

The module will currently continue to publish the MAC address of a BLE device even if it has been previously discovered and approved or rejected. It would ideal for it to be able to use a local data store to identify only new BLE devices that need to be reported.

The Sync Engine

Principal Developer: Kristin Ottofy

Overview

The Sync Engine IoT Edge module awaits to receive a message from the Scanner module that a new BLE device has been discovered. It then checks a local file to determine if the device has been approved or not. If the device is not listed in the file, then the Sync Engine calls the get-approval API to alert the user of a new approval request on the UI and adds the device information to the local file. The Sync Engine asynchronously and routinely calls the get-devices API to check if the UI has updated the database. If it has, then the Sync Engine will reflect those changes in the local file to retain state on the gateway device and publish a message on the IoT Edge broker for the BLE Communicator Module to begin communication with the newly approved device. This module was written in Node.js and developed using Raspian Jesse on a Raspberry Pi 2.

Challenges

Many of the challenges with this module were presented during the architecture phase. Retaining state across device power cycles or updates proved to be one challenge. The decision to use a local JSON file to store important information allowed us to get up and running quickly during the hackathon.

Successes

As this portion of the project is continuing development, successes have been made so far with communicating across the gateway message broker, storing information into the local file, making necessary API calls, and posting messages to the broker through various npm packages.

Future Development

There are opportunities available within the gateway device that could support the Sync Engine module through IoT Edge v2. Having a localized database would eliminate the need for the local file and allow for quicker checking of approved devices.

The BLE Communicator Module

Principal Developer: Bret Stateham

Overview

The BLE Communicators role is to implement the actual communication with the approved BLE devices. A single instance of the module is used to communicate with ALL of the configured BLE devices as opposed to a single module instance per device. In addition to multiple devices, the module needed to support multiple communication patterns with the GATT characteristics on any given BLE device. The actual GATT characteristics and their usage pattern is be supplied to the BLE module via the IoT Edge v1. configuration mechanism:

  1. Read Once at Init: A characteristic that is read once at the beginning of communication with the device. The GATT Characteristic value would be read, and included in a message sent to the IoT Edge v1 Message Broker. Read Once values typically include device metadata like Manufacturer, Firmware version, Serial Number, etc.

  2. Write Once at Init: A characteristic that would be written to once at the beginning of communication with the device. The value to be written would come from the module configuration. This is often used to initialize the BLE device itself by enabling sensors, notifications, etc.

  3. Write Once at Exit: A characteristic that would be written to once at the end of communication with the device. The value to be written would come from the module configuration. This is often used to turn off sensors, or features on the device to help reduce it’s power consumption when not in use.

  4. Read Periodic: A characteristic that is read at a regular interval (the interval specified in the config). All periodic read sensor values would be collected and published to the Message Broker in a single payload.

  5. Read Notification: A characteristic on the BLE device that supports notifications. The characteristic’s value will be published individually to the IoT Edge v1 Message Broker.

Challenges

This module shares the same core development foundation as the BLE Scanner above, and as such the same challenges around IoT Edge v1’s limitation around native npm packages. See the BLE Scanner challenges above for more details.

In addition to those challenges, we had some concurrency issues in the Node.js code that we were unable to resolve during the timeframe of the hackfest. The noble implementation is naturally asynchronous, but we were having issues maintaining the context of a characteristic read once the value was returned. We attempted numerous patterns include the use of promises, and the “async” module, but were unsuccessful.

Successes

We were able to get the module to read it’s configuration via the IoT Edge v1 configuration mechanism and initiate communication with the specified BLE devices.

Future Development

The code for this module needs to be refactored to properly leverage the asynchronous behavior of the noble module. In addition, the implementation of the various usage patterns above need to completed.

The API

Principal Developer: Joe Raio

Overview

We exposed four Azure Functions as our API for device management. This would be accessed by the front end to list all devices, get details on a specific device, create a new device, and update the properties of a device. All functions were written in node.js and setup and triggered via HTTP.

API Development, Debugging & Testing

We developed the functions locally using both the Azure Functions Core Tools and VS Code. This allowed us to rapidly iterate through changes as well as debug our code. This saved us a tremendous amount of time vs having to deploy to Azure each time we needed to verify our code updates.
Postman was used to both test API calls locally and against the live site. This allowed us to modify our request body on the fly and send GET, POST, and PUT requests to the API.
Challenges

  1. Proxy Routes using /api – We set out with a goal of being able to call /api/device using different methods (i.e. POST, PUT, GET) which would in turn route to different Azure Functions. To do this we had to enable the use of Function Proxies. When doing this though it would not allow us to use /api in the route prefix because /api is the default route when creating a new function. To overcome this we modified the host.json and changed the default route for functions to /func. This allowed us to then use /api/device with our proxies.

  2. MongoDB API – It was decided that that MongoDB API would be used to interact with CosmosDB. Because of this we were unable to use the built in CosmosDB bindings for Azure Functions. We had to use the Mongo npm packages and write custom code to read / write / update records in the database. While this was not a huge hurdle it would have been cleaner (and faster) for us to use the default DocumentDB api. Future version of the API will use this.

  3. CORS – Early on we ran into CORS issues when trying to access the API from our front-end application. We found that when using proxies our default CORS rules were overwritten. We got past this by adding custom headers to each function directly in the code. Further testing needs to be done to determine the exact cause of this issue.

The UI

Principal Developer: Jeremy Foster

Overview

One part of the overall project workflow required a user interface – the authentication of found devices. For this, we turned to Angular and got a bit creative and modern in how we hosted this application – serverlessly!

Angular

Angular’s CLI makes getting started with a new website pretty quick and easy. Angular is a good, modern choice for a UI and offers plenty of features for this application.

Using the CLI, we had a basic site in just a couple of minutes. Then we added a simple DeviceList component and displayed this component on the main page… nothing fancy… one component.

The most interesting part of the UI was the DataService, which is responsible for fetching devices from the API, displaying them in the UI through the device list component, and keeping the list up to date as new devices are discovered and administrators approve or deny devices.

The next step in this part of the project would be to create another Angular component – perhaps called Device – that the DeviceList component would repeat. That Device component would then contain all of the UI and logic for user interactions for managing the devices – for instance, an Approve button and an Always Ignore button.

Next, because we started with BLE devices for this project, the individual found devices would need to have their characteristics (the properties on each device we’re able to read/write data values from/to) enumerated and give the administrator the ability to determine which characteristics are interesting and how those characteristics should be read (i.e. once, periodically, etc.).

REST Architecture

The API was designed to follow a pure REST architecture, so the higher level operations were absorbed by the UI’s DataService. In the future, a data access layer of sorts could be implemented in a separate or the same API project to make calling from our UI or other UI formats simpler and more consistent.

As an example, in order to keep the API pure REST, a call to approve a device would be something like…

PUT /api/device { "id":14, "approved":false }

In the UI’s DataService, however, that would simply be a call to a higher level function like this…

approveDevice(14);

Serverless Hosting

Being the UI is composed of all static files, we could serve it as a Serverless website by using an Azure Function with a custom proxy.

To do this we first created an empty blob container. In this container, we placed the production output of the Angular App (i.e. the /dist folder). Then, using a custom proxy route we routed all requests for /{restofpath} to the public url for the container.

The route definition is as follows:

"root": {
"matchCondition": {
"route": "/{restOfPath}"
},
"backendUri": "https://%mycontainer_uri%/client/{restOfPath}"
}

With %mycontainer_uri% being an app setting for the URI for the blob storage account.

By doing this we avoid having a web app using 24/7 just to serve up static files. When a request is made, the Azure function simply pulls the file from blob storage and serves it to the browser.

You can view the live site here: https://edgediscover-functionapp.azurewebsites.net/index.html

To deploy the UI we used VSTS to create a custom build process with the following steps:

  1. Get Sources – This gets the latest files that were committed to the repo

  2. npm Install – installs all the required npm packages

  3. npm run build-prod – this produces the output of the UI in the /dist folder

  4. AzCopy – this then takes the output and copies it to the specified blob container.

Conclusion

Like many good projects, this one is unfinished, but I hope you have learned like I have to embrace unfinished projects. If you have to bring everything to completion, you may not start some things even though there may be a lot to learn. I certainly learned a lot on this one.

The Intel Edison

I am playing with the Intel Edison a lot these days. I’m a big promoponent of it, because I’m a big proponent of both power and simplicity. This device has enough power for whatever maker, robotic, gadgeteer project I can conceive of, and it’s all set up to easily run JavaScript via Node via Linux. This means I can use higher level libraries like Cylon.js. This means if I want to turn a motor, it’s easy. If I want to read accelerometer data from an ADXL377, it’s easy. If I want to include a Node module for storing temperature and humidity data in Azure, it’s super duper easy. I like easy - just not at the cost of power.

I’ll stop being wordy, though and just index the posts that I’ve creating (and am still creating) for the Intel Edison. Here they are.

Getting Started with the Intel Edison should help you pull it out of the box, mount the device to the dev board, flash the latest OS to the device, and get your toes wet writing code.

Writing JavaScript for the Intel Edison intends to pick up where the former left off and should help you get started writing Node.js apps using Cylon.js for the device.

Using Visual Studio to Write Node for Devices will bring a bit of awesome to coding for devices. You’ll have a rich development environment including remote debugging so you can actually step through breakpoints and watch your gadget react!

Flashing an LED when you get a Tweet (up next) will use what we’ve learned so far along with a Node.js module to hook into Twitter’s streaming API to turn your LED on for a couple seconds when you get a tweet.

Tweet Monkey is actually similar to the flashing LED sample I was going to do, but more fun. Would you rather see an LED flash or a monkey clanging symbols?! The real value in this tutorial is the JavaScript that combines calling in to the Twitter Streaming API with the using of the cylon library to talk to the monkey.

Command Monkey is Tweet Monkey’s older brother. Command Monkey is a fun and full-featured scenario where Cortana on the Windows Phone is used to tell the monkey to dance. This tutorial will teach you a pretty wide scope. You’ll learn to integrate Cortana, write a Windows Phone app using JavaScript, write a Node.js service on Azure, and how to communicate down to the device (the monkey in our case) using web sockets. It’s surprisingly little code overall.

Network IoT Devices (queued) is all about getting devices to form local or extremely broad networks that form huge logical apps and scenarios.

So you can actually check out posts in progress before I’ve polished them and called them done. Do please feel free to engage in the comments and offer feedback, advice, or questions.

Writing JavaScript for an Intel Edison

In my last article about the Intel Edison, I showed you how to take yours out of the box, and get it set up. Consider this article a follow-on. I’m going to pick up pretty much where the last one ended.

We actually wrote a little bit of code in the setup article, so you got a taste. Now we’re going to learn…

  • how to use the power of Node.js to bring in libraries and command our device
  • how to deploy code to the device wirelessly (zoing!)
  • how to use the excellent Cylon library to make our code elegant and expressive

Let’s start off in this article without employing the help of Visual Studio, and then my next article will capture the many productivity benefits of VS. It’s always nice to start at the base and climb up to awesome tooling. That way, we’re thankful for the conveniences it brings. :)

Using Node.js

Installing Node.js

I’m assuming your host PC is Windows. I’m running the technical preview of Windows 10 and it’s all working great. I like to live on the edge.

The easiest way to install Node.js is by simply clicking the big green button you’ll find at nodejs.org

You’ll see in the installation wizard, that you’re actually getting the NPM utility installed along with the Node.js engine. The installation should take care of a lot of busy work for you such as adding node and npm to your path so you can actually call it from the CLI. My CLI of choice, BTW, is PowerShell. To be clear, I’m talking here about installing Node.js on your host PC. Node and NPM should already be installed on the device if you flashed it according to the instructions in the last post.

After you have Node.js installed, we’ll walk through a few steps to create a new node project on your host PC. When we’re done with that, we’ll turn our attention to getting that code over to the Edison and running it there.

Creating the Folder and File Structure

Node.js projects have a pretty well defined, convention based folder and file structure. They’re very simple too - all of the metadata is in one spot. I don’t know where you keep your development projects, but I keep all of mine under c:\repos and I’ll start there. Watch the following video as I create a new project folder, generate an app package description file (package.json), and then create my initial app.js file…

As you can see, the npm init makes the creation of our package.json file very easy. The package.json file describes your node project and has a few purposes - the two most prominent that I can think of are a) it provides the metadata necessary in case we end up publishing this package to the node package store and b) it defines the project dependencies so that when the project is copied somewhere else, a simple command is all that’s necessary to actually go out and copy in all binaries necessary for the app to work.

Writing the Code

Now, in keeping with a simple workflow at first, let’s open app.js in Notepad++, and fill out the following…

var mraa = require('mraa');
var pin13 = new mraa.Gpio(13);
pin13.dir(mraa.DIR_OUT);
pin13.write(1);

This code depends on the mraa module, but if you followed my setup guide and flashed the Intel with the latest image, then you already have it. The mraa module maps the C libraries for interacting with the Edison’s hardware (the GPIO pins, the I2C bus, etc.) to Python and to JavaScript.

The code simply creates a new pin out of pin 13. Pin 13 is the one that conveniently has an LED on the dev board, so we don’t even have to plug anything in to see it. It then sets the direction of that pin to out. And finally, it raises the logic level of the pin by writing a value of 1.

Deploying Wirelessly

We saw in the last guide how to SSH directly to our device. If you gave your device the name “betty” like I did, then you’ve been provided a DNS name of betty.local which represents the IP address that your device was assigned on the network. If you’re not sure the device or the DNS name are working, just do ping betty.local from the CLI (replacing ‘betty’ with the name of your device of course). I’ve actually started pinging to discover the IP address and then using the IP address explicitly for SSH and SCP, because it takes a little time for the alias to resolve but hitting the IP address directly is snappy.

First, we’ll get our code copied to the device, and then we’ll SSH to the device in order to execute the code. It is also possible to simply execute the node app.js command remotely with SSH, but it’s fun to see what’s actually happening.

In this video, I’m going to SSH to the device, make a directory for our hellonode app, then jump back to my host machine, copy the files to the device (and specifically to that project folder) using SCP, and then back to the device to execute the app. The workflow can be simplified a bit, but I’m not arguing at this point. It’s pretty wonderful actually.

Notice the syntax of the SCP command. It wants scp @:. I do everything as the root user, so the is root and the directory is /home/root/.

You didn’t see anything happen there, but I did. My LED came on.

There are a few things that are cool about this. It’s cool that the mraa library preexists and makes communicating with the device pins so easy from a high-level language like JavaScript. Also, it’s great that we’re remoting and remote deploying our project wirelessly. This means that we can build something like an intelligent camera device, install it in a bird nest, and then remotely upgrade our software without disturbing the birds. That’s just the first example that came to mind.

Alright, now lets make our development really clean and easy by employing the CylonJS library.

Using CylonJS

CylonJS can be found at cylonjs.com. You won’t even need to go there to get the code, because we’re going to use NPM, but you may want to go check it out to get familiar with the project and eventually to research the documentation for whatever device and driver you’re using.
Let’s run through the steps to do something similar to our hellonode app above, but use the Cylon library.

In this video we will: create a project folder, create our app.js file with some sample code from cylonjs.com that will cause pin 13 to blink, generate a package.json file, install cylon.js via NPM using the --save parameter to add it as a dependency in our package.json file, then we’ll deploy to the device, and finally SSH to the device and execute the node program. You’ll actually see a video of the device with the LED blinking. Just a quick warning - we’re not only going to be holding off on Visual Studio at this point, but I’ve decided to use a CLI text editor for the hilarious factor as well as the convenience of showing everything in one window. I actually really like using the command line, but GUI’s are great too. As long as I don’t have to remove my hands from my keyboard, I’m a happy programmer.

EDIT: Thanks to Roberto Cervantes in the comments for pointing out a step that I should have called special attention to. In the following video, notice that after I scp the files to the device and then ssh to the device, I execute the command npm install. This looks into the package.json file that we just deployed to see what my project’s dependencies are, it goes out to the internet (to the NPM repository) to fetch the packages, and then it installs them. If you skip this step your app will have no idea what require('cylon') means.

A few things to note about this video…

  • My edit app.js command won’t work for you because that’s a special command line text editor that I use. I’m going to go ahead and assume you have your own favorite way to edit a text file. :)

  • Note that installing the cylon-intel-iot module added dependencies in the package.json for itself as well as for its dependencies. We actually never had to create the cylon module as a dependency. That happened implicitly because the cylon-intel-iot module knew that it needed it. That’s a cool thing about node modules - they each know exactly what they depend on and a single install command recursively takes care of business.

  • We copied over only the app.js and the package.json. We did not copy over the node_modules folder - you’ll notice that I deleted it before deploying. This is the right way to deploy project. You don’t check the node_modules in to source control and don’t copy it over in a deployment. Instead, you rely on the dependencies defined in your package.json file. On the deployment server, you execute npm install and if anything doesn’t get installed correctly, then you need to add it to your package.json file.

And now a bit about the CylonJS code. Here it is…

var Cylon = require('cylon');
Cylon.robot({
  connections: {
    edison: { adaptor: 'intel-iot' }
  },
  devices: {
    led: { driver: 'led', pin: 13 }
  },
  work: function(my) {
    every((1).second(), function() {
      my.led.toggle();
    });
  }
}).start();

Just like in our simpler hellonode app, we are doing a require right off the bat here. We are not, however, requiring the mraa library. Instead we’re requiring the cylon module. The cylon-intel-iot module will be invoked from within cylon and it will make calls to the mraa library. We risen up one layer of abstraction. The big benefit here is that we’re no longer writing device specific code. We could theoretically switch our Edison out for a Spark and it would just work.

The code block is, I admit, unnecessarily heavy if you’re just blinking a light, but ponder for a minute the elegance of this compared to the inevitable mass of imperative code that would occur were we doing anything more complicated.

There are a couple of Cylon terms that I should explicitly call out…

A Cylon robot is the device - the Edison or Beaglebone or Spheo or Tessel or any the other 32 or so devices that Cylon already has adaptors for. You define your robot with a connection and you use an adaptor (in the example it’s intel-iot).

A device in Cylon parlance is more like a component on the device. In our example above, the pin is a component and so it’s registered as a device. The important part of the device declaration is the driver. A driver is the interface that Cylon will use to interact with it. When the led driver is used, then the thing we’re calling led will have functions like .turnOn() and .turnOff(). This makes it so that our we only ever speak to our components with sensible language - you tell a servo motor .clockwise() and you capture a button press with .on('push',function(){}). Sensible is good in my book.

Besides declaring the connections and devices, we declare a function that is to run when the robot is finished with its setup. In this case, we’re using the built-in every function provided by the Cylon library to toggle the led every second. Easy peasy.

Well, folks, there you have it. This is the point in my learning that I felt like the gate was open and I was running free and wild. Oh, the myriad of devices to communicate with. Oh, the plethora of components. Oh, the possibilities.

I have a few more posts to write on this, but I’m keeping them all separate so I can get them out the door. All of these articles are indexed at codefoster.com/edison.

Please feel free to comment below if you have any trouble here. There’s a good chance I ran into the trouble you’re finding, and if I didn’t I’m willing to bang my head against the wall a bit with you - just a bit.

Setting up an Intel Edison

This is a guide to getting started with the Intel Edison.

Intel has published a guide for getting started with this device as well, but I wanted to get everything into one place, tell it from my perspective, and smooth over a couple of the bumps I hit on the way. Let me know with a comment below if you have any questions.

I like to keep things simple, so I’m going to help you get started with the Edison as easily as possible.

In a subsequent post, I’m going to show you how you can very, very easily start writing JavaScript to control your Edison. You won’t have to deal with Wiring code, you won’t have to install the Arduino IDE (argh!), and you won’t have to install Intel’s attempt at an IDE - Intel XDK IoT Edition. You’ll be able to use Visual Studio, deploy to the device wirelessly, and then have plenty of time when it’s done to jump in the air and click your heels together.

In another post, I’m going to show you how to use Azure’s Event Hub and Service Bus (via a framework called NitrogenJS) to not only do cool things on one Edison, but to do cool (likely cooler actually) things on multiple Edisons, other devices, webpages, computers, etc.

Introducing the Edison

The Edison is tiny. It’s the size of an SD card. Despite its size, though it has built in WiFi and Bluetooth LE and enough processor and memory oomph to get the job done.

The design of the Edison is such that it’s pretty easy to implement a quasi-production solution. It’s not always easy getting a full Arduino board into your project, but the Edison is almost sure to fit.

I’m not the only one that’s excited about this System on a Chip (SoC) either. Sparkfun.com is too. They made a great video introducing the technical specs of the Edison and showcasing their very cool line of modules that snap right on to the Edison’s body. Here you can see a few of those modules piled up to produce a very capable solution…

That’s the kind of compact solution I’m talking about. The only problem is that at the time of writing, the modules are only available for pre-order.

Not to worry though, there are a couple of other ways to interface with the Edison and get working on your project. The recommended way is by using the Arduino dev board. This is what the Edison looks like when it’s snapped to the dev board.

This dev board explodes all of the functionality packed into the Edison and makes life easy. It gives you USB headers, a power plug, GPIO (general purpose input/output) pins, a few buttons, and a micro-SD card slot.

There’s another dev board available for the Edison - a mini board - but it’s less used because it requires soldering and doesn’t offer as many breakouts. If you’re looking for compact, you can just wait for the Sparkfun modules I mentioned. Here’s the Edison mounted on its mini board…

In this guide, I’ll take you end to end with getting the Edison setup on a Windows machine. I am not prepared to detail instructions for Mac/Linux, but Intel did a good job of that on their guide anyway. I’m going to mention the physical setup of the device, installation of the drivers (on your host PC running Windows), then walk you through flashing it with Intel’s custom Yocto Linux image and training it to connect to Wifi. When we’re all said and done, we’ll never have to plug the Edison into our host PC via USB again. We’ll be able to wirelessly deploy software and otherwise communicate with the device. Finally, we’ll write a simple bit of code, but in a follow up post, we’ll get crazy with software, because that’s what we do.

Physical Setup

Physically setting up the Edison once you’ve pulled it out of the box is pretty straight forward. I’ll assume you’re starting with the Arduino dev board.

Add the plastic standoffs to the dev board if you’d like. They’re good for keeping Edison’s sensitive underbelly from touching anything conductive and creating a dreaded short.

Next snap the Edison chip onto the board. You can put the tiny nuts onto the posts to hold the chip on, but I choose to rely on the solid friction fit instead.

Flashing

Before your Edison is going to do anything exciting, you’ll need to connect to it and flash it with the latest version of the Yocto Linux distribution that is provided by Intel. At first, it has no idea how to connect to a Wifi hotspot, so we’ll have to establish a serial connection. It’s quite easy actually.

Intel’s guide does a decent job of walking you through these steps, but again, I’m going to do it on my own to add my own perspective and lessons learned.

The guide asks you to plug in both USB cables. That will work, but it helps to understand why. One of the USB micro plugs (the one closest to the power plug and the larger USB port) is a host plug that will a) power the Edison via USB and b) will cause a certain directory from its file system to appear in Windows Explorer as a drive. The other USB micro plug (the one closest to the edge of the board) is a serial connection that will allow you to establish a 115200 baud serial connection before Wifi is established.

What I prefer to do is power the Edison with a barrel connector, and then just use one USB cable plugged in to whichever header I need. This works well especially since one of them is only need for one step upon initial setup - to flash the device. I have a USB to barrel connector, so I can simply plug my Edison into a USB battery pack and emphasize that it’s completely wireless.

Do make sure the itty bitty switch next to the USB micro plugs is switched toward the USB micro plugs.

Download and install FTDI drivers. First, you need to download and install the FTDI drivers which allow your host computer to communicate with the USB header on the Edison. The file you download (“CDM…”) can be directly executed, but I had to run it in compatibility mode since I’m running Windows 10. I won’t insult your intelligence by telling you how to hit Next, Next, Finish.

Download Intel Edison Drivers. Now you need drivers for RNDIS, CDC, and DFU. It sounds hard, but it’s not. Go to Intel’s Edison software downloads page and look for the “Windows Driver setup”. This downloads a zip file called IntelEdisonDriverSetup1.0.0.exe. Execute the file and comlete installation. The download goofed up for me in IE11 on Windows 10, so if you run into that, go to the link at the bottom of the page that says it’s for “older versions”. The download for that same file is there and it’s not an older version.

Note: In case you want to know, the RNDIS (Remote Network Driver Interface Spec) is for virtual Ethernet link over USB, the CDC (Composite Device Class) is a standard for recognizing and communicating with devices, and DFU (Device Firmware Upgrade) is functionality for updating firmware on devices.

Copy flash files over. With these two driver packs installed, you should have a new Windows drive letter in Explorer called Edison. This is good, because that’s where you copy the files that will be used to flash the device. Go back to the Intel Edison software downloads page and locate and download “Edison Yocto complete image”. Save it local and unzip it. Now make sure the Edison drive in Windows Explorer is completely empty and then copy the entire contents of the zip file you just downloaded into that drive.

Connect to the device using serial. Since we’re finished copying files to the device and ready to connect to it over serial, we need to switch the USB cable from the inner port to the outer port. Do make sure you have the USB to barrel connector in place so you get the reassuring power light on the board.

The Intel guide walks you through using PuTTY (a Windows client for doing things like telnet, SSH, and serial connections). I’m a command line guy, so I use a slightly different approach using PowerShell which I’ll present. You can choose which you like better.

Go to the PuTTY download page, download plink and save the resulting plink.exe file into some local directory. I use c:\bin. Now you’re ready to use PowerShell to connect to a serial port. Very cool.

Note: plink in PowerShell does something goofy with the backspace key. It works, but it renders ?[J for each time it’s pressed. If you know a way around this, let me know.

Before you connect, you have to see what the COM port is for the Edison. Go to Device Manager and expand the Ports (COM & LPT). Now look for USB Serial Port (COMX). Mine is COM5.

Here’s the line I use to connect (actually, I put a plink function in my $profile to make it even easier… ask me if you want to see how)…

. c:\bin\plink.exe -serial COM5 -sercfg 115200,8,1,n,Namely

…if you saved your plink.exe into a different location or if your COM port is different then change accordingly.

Execute that line and then hit enter a couple of times. You should find yourself at a root@edison:~# prompt. That’s good news. Your on the device!

Initiate the flash. To flash your Edison using the files you copied into the drive, you simply type reboot otaand hit Enter. Watch your device do a whole bunch of stuff that you don’t have time to understand, and rejoice when it finishes and returns you to the login prompt. Your login is root and you don’t have a password. You should be sitting at root@edison:~# again.

Setup wireless. You have a full Linux distribution flashed to your Edison now, and it’s ready to talk Wifi. You just have to configure a couple things. Namely, you have to a) give your Edison a password (technically, provide a password for the root account), b) make sure your host PC is on the same network as your Edison, and c) provide your SSID and password. The first point is one thing the Intel guide skips - the need to set a password on the root account. If you don’t do it, you won’t be able to SSH to the device over Wifi. To initiate, execute configure_edison --setup. You’re prompted for a device name. I like to name mine (mine are called Eddie and Betty) so they’re easier to differentiate in terminal windows. I provide easy passwords for mine, because I’m not exactly worried about getting hacked. Next, you’ll be prompted to setup up Wifi. Follow along, choose the right hotspot, and enter the Wifi password when prompted.

Connect to the device using SSH over TCP/IP via the Wifi. Let’s get rid of this silly hard link and serial connection and join the modern era with a Wifi connection. Disconnect from the plink connection using CTRL+C. You can pull that USB cable out of your Edison’s dev board too. Your Edison is now untethered! Well, except for power, but a battery could take care of that.

Now again, I’ll diverge from the Intel guide here so I can stick with the command line. I use Cygwin on my box to allow me to SSH via PowerShell. I like it a lot. EDIT: Thanks to @palermo4 for pointing out that it’s not Cygwin that’s giving me this functionality, but rather my install of GitHub for Windows and the fact that I subsequently added GitHub’s bin folder to my path in Windows. Simply install GitHub for Windows and then go to your Environment Variables in Windows, edit the PATH variable, and append your bin directory to the end. On my system, it’s at _C:\Users\jerfost\AppData\Local\GitHub\PortableGit7eaa994416ae7b397b2628033ac45f8ff6ac2010\bin; I’m guessing yours is different :) After adding this, test it by typing SSH<Enter> in PowerShell and see if you get something besides an error.

You can use this approach, or you can go back to the Intel guide and use the PuTTY approach.

Before you can SSH to your device, you have to figure out what it got for an IP address. But the Edison has done something nice for you there. It created name.local as a DNS entry, so to connect to an Edison with the name eddie, you can simply use eddie.local. Mine is resolving to 192.168.1.9. If this doesn’t work for you, you can always log in to your router and find out what IP address was assigned to it or you can go back to the serial connection and type ifconfigat the prompt and look for the wlan0 network and see what address was assigned.

From my PowerShell prompt, I can just type ssh root@eddie.local. You’re connected to your Edison over Wifi now, and you’re so very happy!

Ready to Write Code!

From here, you’re ready to write some code. I’m going to write an extensive blog post on the topic, but for now, let’s get at least a taste.

First, make sure you’re SSH’ed to the device. So run that same ssh root@eddie.local command and sign in with your password.

Hello World! First things first. Let’s greet the world using JavaScript (via NodeJS). Type node and hit Enter and you should be at a > prompt. You’re in NodeJS… on your Edison. Man, that was easy.

Now type console.log('Hello World'); and hit Enter. There you have it.

Hit CTRL+C twice to get back to your Linux prompt.

Blink the light, already! You haven’t gotten started with an IoT device until you’ve blinked an LED, so let’s get to it. Still SSH’ed to your device, execute each of these lines (each at the prompt) followed by Enter…

node //enter NodeJS again
var mraa = require('mraa'); //create a reference to the built-in mraa library (which provides easy access to hardware capabilities)
var led = new mraa.Gpio(13); //setup a variable for pin 13 which also happens to be an LED on the board (how convenient)
led.dir(mraa.DIR_OUT); //tell pin 13 that it should act as an _output_ pin for now
led.write(1); //turn the LED on
led.write(0); //turn the LED off

And this is full-on JavaScript, so you can go crazy with it (recommended). Try this…

var state = 0; //create a variable for saving the state of the LED
var blink = function() { state = (state==1?0:1); led.write(state); setTimeout(blink,500); } //create a function that changes the state, waits 500ms, and then calls itself</span>
blink() //start blinking

The light should be flashing on and off, but your state of bliss should be sustained high!

It’s obviously not sustainable to write our code at the prompt, so stay tuned for my next guide on writing code for your Edison.

Have fun!