Internet of Things with BeagleBone

Yogesh Chavan

December 2015

In this article by, Yogesh Chavan, author of the book, Programming the BeagleBone, we will see that BeagleBone has lots of capabilities. It has a full-fledged Linux operating system running in it. It has an Ethernet port built-in. We have not used many of its capabilities yet. We can run it as a web server and extend our physical computing programs to be executed from the Internet. In this article, you will first learn about Internet of Things (IoT). Then, we will create a node web server running on BeagleBone and control the connected LED remotely. This will be our first step towards the Internet of Things.

This article will cover the following topics:

  • Why Internet of Things?
  • What is Internet of Things?
  • Program for creating new node.js HTTP server
  • Program to control LED through web browser

(For more resources related to this topic, see here.)

Why Internet of Things?

Internet of Things (IoT) is the buzz word these days. The popular business analyst company, Gartner, has put IoT at the highest place in the hype cycle of emerging technologies for the years 2014 and 2015. There is lots of growth predicted in this technology by analysts. Many start-ups are working on this. Crowdfunding websites such as Kickstarter and Indiegogo have successfully funded numerous IoT solutions. Established companies are investing a lot in IoT. Soon, we will see many of these things in our home and city. Some of them are already available in the market. For example, smart bulbs that change their intensity depending on light outside to save energy. They can also be controlled via a smartphone app. The Amazon product dash can scan a product barcode or listen to any product name that you say, and this product is added to your Amazon online cart through your Wi-Fi connection. This saves time and effort when you want to buy multiple items. A wireless pacemaker helps control your heartbeat as well as store and provide heartbeat data logs wirelessly to decide medications. This was not possible previously without cutting skin. Our world will change a lot when we will have connected smart watch, health band, electrical plug, room heater, oven, toys, door lock, helmet, street lights, parking lots, trash can, coffee machine, and so on. So, it is important to know what all we can do to implement IoT using BeagleBone.

We can see that technological growth happened in different ages. A major milestone was achieved when the PC was invented. Soon, many homes, institutes, and enterprises got access to computers. They got introduced to the digital world. People started using it for financial accounting, data backup, entertainment, publishing, and so on. The next age came along with the Internet. Homes with Internet connections got connected. This communication solved lots of problems. People started exchanging information, creating social networks, hosting websites, banking online, playing multiplayer games, cloud backup, among others. Still, connectivity was limited to a PC. It was often shared. There was no Internet connectivity option available for individuals all the time. The next era came along with smartphones. Anyone can remain online all the time using a personal smartphone. The average time that individuals remain online has increased drastically. Social networks became even bigger after this. People started relying on information updates from institutes, employers, friends, and websites. People started taking decisions based on the latest update. Information has reached at everybody's fingertips.

When everybody is connected to the Internet, the next obvious era will be connecting every thing to the Internet, that is, the era of Internet of Things. Communication between these things to other things/humans will bring many possibilities. It will solve many problems. Smart things will exchange data to provide high availability of service, better interoperability, safety measures, automation, gathering and analyzing data, self-monitoring, notifying and allowing a remote user to take decisions, and so on. IoT has diverse use cases in several industries such as automobile, healthcare, agriculture, transportation, manufacturing, home automation, and others. Humans have limitations. We can not work 24 hours everyday. We cannot remember all the data that we encounter. We do not like to do repetitive tasks. Here, these things come to rescue us. They can work 24 x 7 and can store and retrieve data on cloud storage accurately and reliably (considering a reliable network). Sensors and actuators provide things with the ability to know some information about the environment and respond accordingly. This information can be analyzed and visualized to draw important conclusions. IoT gives us the power to administer things remotely, which reduces distant visits including hazardous environment conditions.

What is Internet of Things?

According to Wikipedia, IoT is a network of physical objects or things embedded with electronics, software, sensors, and connectivity. These things interoperate in the existing Internet infrastructure. They achieve greater value and service by exchanging data with the manufacturer, operator, and/or connected devices.

The properties of things involved in IoT are as follows:

  • They are physical objects with input (sensors) and/or output (actuators). They interact with the physical world.
  • They have connectivity to the Internet or local connectivity via Ethernet, Bluetooth, GSM, Wi-Fi, or any RF transreceiver.
  • They exchange data with websites, a cloud, or other things. Often, this data is available to the end user via a smartphone, tablet, or PC.
  • They have a kind of unique ID such as IP addresses, RFID, or QR code.
  • They have a small software logic that they follow. Once set up, almost no physical human interaction is involved.
  • A set of interrelated things form a system. For example, a traffic control system gets formed by smart traffic cameras, smart road notice boards, and servers that collect data from traffic cameras to display traffic information on smart road notice boards. IoT is a system of such systems.

You can think of IoT as the human body. There are five senses—light by eyes, sound by ears, touch by skin, smell by nose, and taste by tongue. Human actuators are sound generations by various parts of the mouth, movements of various body parts by muscles, various biochemical changes by controlling glands, and so on. The human body has a respiratory system, digestive system, muscular system, skeletal system, and circulatory system. These systems exchange information with the centralized brain via nerves. A human body is a system of these systems. All these systems work together to achieve our living.

BeagleBone is the natural choice for an IoT developer. It is small in size and has a built-in Ethernet port unlike regular microcontroller boards. The USB port on BeagleBone allows you to attach Wi-Fi, Bluetooth, or any RF USB adapter to have this connectivity. It has lots of GPIO pins, analog control pins, and buses to talk with sensors and actuators. It needs less electrical power to operate than a regular PC. The Beaglebone CPU is powerful enough for lots of processing. It has full-fledged Debian Linux running on it that supports a lot of programming languages and numerous software including various server software. You can do moderate data processing, storage-retrieval using database software, and data analysis locally in BeagleBone. There is no need of extra server machines for this. Kernel, bootloader, and rootfs—all the software is open source. This means that software can be modified to individual needs. Even hardware design files are open source. Anybody can modify these to implement his/her custom IoT solutions. All these benefits make BeagleBone a perfect candidate for IoT. With all this theory considered, let's move on to writing a few IoT programs using BeagleBone. IoT products can be classified into smart wearable, smart home, smart city, smart environment, and smart enterprise based on scope.

Program for creating new node.js HTTP server

To control BeagleBone from the Internet, we need to run an HTTP server on it. BeagleBone has already node.js running as the HTTP server in order to be able to run Cloud9 on port 3000. There are built-in node.js HTTP interfaces that can be used to create a new HTTP server on the specified port number. Once created, this server listens to HTML queries on the specified port. On request, it sends an HTML file to the client. The client's browser renders this HTML file. So, we have to write JavaScript code to run a node.js HTTP server and write an HTML file to be displayed. Let's create an HTML file first.

HTML code

Open the Cloud9 IDE and the New File tab. Write the following code in it and save it as iot.html:

<!DOCTYPE html>
<html>
<body>
<h1>Beaglebone IoT</h1>
<h2><a href="/led.html">LED</a></h2>
<h2><a href="/servo.html">Servo</a></h2>
</body>
</html>

This is simple HTML code. This file can be viewed using a web browser. It has a big header text—BeagleBone IoT. It has two links pointing to the led.html and servo.html files, which do not exist yet.

JavaScript code

Let's create a node.js HTTP server. Write this program in Cloud9 and save it as baseHttpServer.js. Run this program. It will run a new node.js server on port number 3001. Open a web browser from your laptop / computer / smartphone connected to the same router that your BeagleBone is connected to. Put this address in the address bar, http://<Beaglebone's ip address>:3001/iot.html. Let's suppose that BeagleBone's IP address is 192.168.7.2, then the address should be http://192.168.7.2:3001/iot.html. You should be able to see the text—BeagleBone IoT—in the browser:

var http = require("http");
var fs = require('fs');
var url = require('url');
var port = 3001;

var myServer = http.createServer(httpRequestHandler);
myServer.listen(port);
function httpRequestHandler(request, response)
{
var fullPath = '/var/lib/cloud9' +
   url.parse(request.url).pathname;
console.log('fullPath: ', fullPath); //print file path
fs.readFile(fullPath,fileReadHandler);
function fileReadHandler(err, file)
{
   if(err)
   {
     response.writeHeader(500);
     response.end('Error loading html file');
   }
   else
   {
     response.writeHeader(200);
     response.end(file);
   }
}
}

Explanation

We first included an http module and name it as http. We need it to create a new HTTP server. Similarly, we include the fs(filesystem) and url(uniform resource locator) modules. They are needed to read the HTML file and parse the URL. Then, we called the createServer() method from the http module. It returns a new instance of the http.Server class. The createServer() function takes a parameter as the name of the callback function to be called on events. Here, the httpRequestHandler() function will be called when there will be any event triggered on the port that it is listening on. Then, we called the listen() method on port 3001. In our case, if there is any event triggered on port 3001, the httpRequestHandler() function will be called:

When httpRequestHandler() gets called, it is given parameters request object and response object. The request object has information about the HTTP request made to the server. The response object has fields that manage the response by the server. We read from the request object and fill the response object in httpRequestHandler(). This should be clear from the previous image. First, we crafted a full path of the HTML file to be sent to the client's browser and printed the path for the debugging. Make sure that this path to the HTML file is /var/lib/cloud9/iot.html. Then, we read the HTML file, and after reading it, the fileReadHandler() callback function will be called with err and file as arguments. In the fileReadHandler() function, we check for error. If there is an error, we modify the response object with the HTTP return code, 500 error. Then, we called response.end(), which means end response stream. If there is no error, we give the HTTP return code as 200 ok and send our HTML file over the response stream.

Our experiment is limited to LAN. The browser from which you connect to has to be in LAN. If you want to allow connection to your BeagleBone from any system on the Internet, you can achieve it using ngrok or any tunneling software. You can also achieve this for a specific port using the port forwarding option in your router's web configuration interface. In our case, port 3001 has to be forwarded. An outside LAN connection can also be achieved by the ddns service. Note that this increases security risks.

Troubleshooting

  • It is recommended that you use the Firefox or Chrome browser. They are available on Android and iOS.
  • Run the netstat –nat | grep 3001 command in the BeagleBone shell to confirm that the 3001 port is waiting for the connection. You should get this output:
    tcp       0     0 0.0.0.0:3001           0.0.0.0:*               LISTEN
  • Use console.log() frequently in our program to debug. It can be used to confirm that control is reaching till the line. It can be used to print values of the variables that you suspect might be troubling.
  • Some errors can be revealed from the client side. Use the Developer options in the browser to debug in the client side.
  • When you run this program multiple times, it may happen that baseHttpServer.js that you ran earlier is still running. In this case, it creates a problem for you to start a new server on the same port. You will get events.js:72 //unhandled excpetion. You can find the PID of the older process instance using the ps aux | grep baseHttp command. Then you can kill it using the kill -15 <pid> command .

Program to control LED through web browser

We have created a web server on port 3001. Now, it is time to turn the external LED on and off using the HTML page remotely. Just by changing the ledPin variable in the following JavaScript program to USR0, you can turn on/off the onboard USER0 LED. This will save wiring efforts. We are going to use the JavaScript socket.io library for this. This library allows real-time, full duplex communication by sending and receiving events. Let's install it by running the following command in the BeagleBone shell:

sudo npm install –g socket.io

The npm term stands for Node Package Manager. It is the package manager for JavaScript libraries. It works independently of the Debian package manager. The source code of socket.io is available at https://github.com/socketio/socket.io.

HTML code

Let's create an HTML file first. Open the Cloud9 IDE and create a new file named led.html. Write the following code in led.html:

<!DOCTYPE html>
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
function ledOn()
{
   socket.emit('ledPin', 'on');
}
function ledOff()
{
   socket.emit('ledPin', 'off');
}
</script>
</head>
<body>
<input type="button" name="ON" id="onButton" value="ON"
   onClick="ledOn();">
<input type="button" name="OFF" id="offButton" value="OFF"
   onClick="ledOff();">
</body>
</html>

Explanation

This HTML code is divided into two parts. One part is the HTML code that creates two buttons named ON and OFF. When these buttons get clicked, they call the ledOn() and ledOff()functions accordingly. This part is in the <body> tag. The second part is the JavaScript code in the <head>tag. It uses the socket.io library to talk with the server. This is the client's browser-side scripting. The socket.iolibrary works by sending events such as connect, message, or disconnect. It allows you to emit custom events besides the regular events. Here, we are emitting an event named ledPin with data on when the ON button is clicked and data off when the OFF button is clicked. This sent event has to be handled on the server side.

JavaScript code

Now, let's write server-side code to turn the LED on or off, based on the events emitted. This code is an addition to the previous baseHttpServer.js code. Create a new file in Cloud9 and copy-paste the previous baseHttpServer.js code as it is. Then, append the following code and save it as IoTLED.js. You need to connect the LED to the P8_10 pin.

Run IoTLED.js in Cloud9 and open http://<Beaglebone's ip address>:3001/led.html in the browser on a smartphone / laptop / desktop. You will be able to see two buttons, ON and OFF, in the browser. By clicking on these buttons, you should able to turn the LED on and off. If it does not work, try the troubleshooting steps that we covered in the baseHttpServer.js program. You can replace the LED with a buzzer or relay. This will be useful in situations when you want to turn the buzzer on and off remotely. A relay can be replaced with an LED to give you the power to control AC devices in your home:

var b = require('bonescript');
var ledPin = "P8_10";
b.pinMode(ledPin,b.OUTPUT);
var sockio = require('socket.io');
var io = sockio.listen(myServer);

io.sockets.on('connection', connectionHandler);
function connectionHandler(socket)
{
console.log("Inside connectionHandler");
socket.on('ledPin', ledPinHandler);
function ledPinHandler(data)
{
   console.log("data : " + data); //print received data
   if(data == 'off')
     b.digitalWrite(ledPin,b.LOW);
   else
   b.digitalWrite(ledPin,b.HIGH);
}
}

Explanation

We took the old baseHttpServer.js code as it is. It created a new node.js HTTP server. The additional code is about using socket.io and bonescript. We included the socket.io library code and named it sockio. Then, sockio started listening on our newly created server—myServer. We mapped the connectionevent to the connectionHandler()callback function. Now, when there will be a connection event on the socket, the connectionHandler()function will be called. In the connectionHandler() function, we are waiting for the ledPinevent. If this event is emitted by the client side, it will execute the ledPinHandler()callback function. This function checks whether the data emitted with the ledPinevent is coming from the ON button or the OFF button in the led.html file. Based on the data, it calls bonescript's digitalWrite() to turn the LED on or off.

The whole communication can be seen in the preceding image. The Node.js server creates a new HTTP server and listens on port 3001. The remote web browser creates a connection with the node.js server using socket.io. It emits an event and data to the server. Based on the data, our server calls the bonescript function to control the electronic components. We avoided polling for the data in the server side. The event-driven nature of JavaScript works efficiently here. Only the required data is transmitted and received. In this exercise, there is a one-way communication from the browser to server to electronic component. However, we can extend this to send the data from the electronic sensor to server and then from server to remote browser.

IoT devices are connected all the time. So security becomes very important. A security bug can allow an attacker to take control of things remotely from anywhere in the world.

Summary

In this article, you learned about the usefulness of Internet of Things and its meaning. We created a program to implement a new node.js HTTP server and a program to control an LED through a web browser.

Resources for Article:


Further resources on this subject:


You've been reading an excerpt of:

Programming the BeagleBone

Explore Title