Introduction

This is the chapter web page to support the content in Chapter 11 of the book: Exploring BeagleBone – Tools and Techniques for Building with Embedded Linux. The summary introduction to the chapter is as follows:

This chapter describes how the Beagle boards can be used as a core building block of the Internet of Things (IoT). In this chapter you are introduced to the concepts of network programming, the IoT, and the connection of sensors to the internet. Several different communications architectures are described: The first architecture configures the Beagle board to be a web server that uses various server-side scripting techniques to display sensor data. Next, custom C/C++ code is described that can push sensor data to the internet and to platform as a service (PaaS) offerings, such as ThingSpeak and the Adafruit IO service using MQTT. Finally, a client/server pair for high-speed Transmission Control Protocol (TCP) socket communication is described. The latter part of the chapter introduces some techniques for managing distributed Beagle board sensors, and physical networking topics: setting the Beagle board to have a static IP address; and using Power over Ethernet (PoE) with the Beagle board. By the end of this chapter you should be able to build your own connected embedded IoT devices.

Learning Outcomes

After completing this chapter, you should be able to:

  • Install and configure a web server on a Beagle board and use it to display static HTML content.
  • Enhance the web server to send dynamic web content that uses CGI scripts and PHP scripts to interface to Beagle board sensors.
  • Write the code for a C/C++ client application that can communicate using either HTTP or HTTPS.
  • Build a full local MQTT architecture using Mosquitto and Paho.
  • Interface to platform as a service (PaaS) offerings, such as ThingSpeak and Adafruit IO, using HTTP and MQTT.
  • Use the Linux cron scheduler to structure workflow on the Beagle board.
  • Send e-mail messages directly from a Beagle board and utilize them as a trigger for web services such as IFTTT.
  • Build a C++ client/server application that can communicate at a high speed and a low overhead between any two TCP devices.
  • Manage remote Beagle board devices, using monitoring software and watchdog code, to ensure that deployed services are robust.
  • Configure a Beagle board to use static IP addresses, and wire it to utilize Power over Ethernet (PoE).

Additional Materials (for First Edition)

CGI using C++ on the BeagleBone (Ggicc)

In this chapter I describe how you can build web-based CGI applications that can interface with electronics hardware that is attached to the BeagleBone using Bash scripts that call C/C++ programs. The solution works well for very straightforward applications, but this linked discussion investigates more advanced solutions for applications where there are more complex interactions — for example, the use of web forms to pass data between your web browser and the application that is executing on the BeagleBone. In the linked blog discussion I begin by explaining how you can use a C/C++ program, rather than a CGI script, to display a web page. I then investigate the use of the GNU Cgicc library for more structured and complex interactions. All of the source code for this example is in the Exploring BeagleBone GitHub repository in the chp10/cgicc directory.

Products Described in the Chapter

[amazon asin=B00GYQXDQW,B003MTTJOY,B003E6493G,B00H28H8DU,B006WWN016,B00BDW6D7I&template=ebbchapters]

A number of different Wi-Fi adapters are described in the chapter, such as those in the figure below. The widget on the left-hand side links to some of these adapters on Amazon, where you can find other products, even health related like the compression socks women that are good for women that practice sports.  However, not all of these adapters are confirmed to be working. The adapters that were evaluated in the book that are working well are:

  • The TP-LINK 300Mbps Wireless N Mini that uses the RTL8192CU chipset. Two alternatives are presented in this list: the Rosewill Wireless Adapter and the generic 300Mbps Realtek adapter, which both use the same chipset. The two alternatives have not been tested
  • The Edimax EW-7811Un that uses the RTL8188CUS chipset. It is listed along with two alternatives: the Wi-Pi Raspberry Pi adapter, and the Plugable USB 2.0 adapter, which both use the same chipset. The two alternatives have not been tested, but the Wi-Pi is known to work well.
  • The Asus USB-N10 adapter that uses the RTL8188SU chipset.

Digital Media Resources

Here the digital resources referred to in the chapter web page are provided. There are high-resolution versions of some of the important figures and links to videos, resources and websites that are described in the chapter.

Source Code

All of the source code that is described in this book is available in a public GitHub repository: Derek Molloy Exploring BeagleBone repository.

You can clone this repository on a Linux desktop computer or your BeagleBone using the command:

git clone https://github.com/derekmolloy/exploringBB.git

The code for this chapter can be accessed in the chp10 folder of the cloned repository. The formatted code for the client/server example is provided here for your convenience.

SocketClient.h

Listing 10-4: SocketClient.h
/*
 * SocketClient.h  Created on: 2 Jul 2014
 * Copyright (c) 2014 Derek Molloy (www.derekmolloy.ie)
 * Made available for the book "Exploring BeagleBone" 
 * See: www.exploringbeaglebone.com
 * Licensed under the EUPL V.1.1
 *
 * This Software is provided to You under the terms of the European 
 * Union Public License (the "EUPL") version 1.1 as published by the 
 * European Union. Any use of this Software, other than as authorized 
 * under this License is strictly prohibited (to the extent such use 
 * is covered by a right of the copyright holder of this Software).
 * 
 * This Software is provided under the License on an "AS IS" basis and 
 * without warranties of any kind concerning the Software, including 
 * without limitation merchantability, fitness for a particular purpose, 
 * absence of defects or errors, accuracy, and non-infringement of 
 * intellectual property rights other than copyright. This disclaimer 
 * of warranty is an essential part of the License and a condition for 
 * the grant of any rights to this Software.
 * 
 * For more details, see http://www.derekmolloy.ie/
 */

#ifndef SOCKETCLIENT_H_
#define SOCKETCLIENT_H_

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string>

namespace exploringBB {

class SocketClient {

private:
    int 	    socketfd;
    struct 	    sockaddr_in   serverAddress;
    struct 	    hostent       *server;
    std::string serverName;
    int         portNumber;
    bool        isConnected;

public:
	SocketClient(std::string serverName, int portNumber);
	virtual int connectToServer();
	virtual int disconnectFromServer();
	virtual int send(std::string message);
	virtual std::string receive(int size);
	bool isClientConnected() { return this->isConnected; }
	virtual ~SocketClient();
};

} /* namespace exploringBB */

#endif /* SOCKETCLIENT_H_ */

SocketClient.cpp

Listing 10-4: SocketClient.cpp
/*
 * SocketClient.cpp  Created on: 2 Jul 2014
 * Copyright (c) 2014 Derek Molloy (www.derekmolloy.ie)
 * Made available for the book "Exploring BeagleBone" 
 * See: www.exploringbeaglebone.com
 * Licensed under the EUPL V.1.1
 *
 * This Software is provided to You under the terms of the European 
 * Union Public License (the "EUPL") version 1.1 as published by the 
 * European Union. Any use of this Software, other than as authorized 
 * under this License is strictly prohibited (to the extent such use 
 * is covered by a right of the copyright holder of this Software).
 * 
 * This Software is provided under the License on an "AS IS" basis and 
 * without warranties of any kind concerning the Software, including 
 * without limitation merchantability, fitness for a particular purpose, 
 * absence of defects or errors, accuracy, and non-infringement of 
 * intellectual property rights other than copyright. This disclaimer 
 * of warranty is an essential part of the License and a condition for 
 * the grant of any rights to this Software.
 * 
 * For more details, see http://www.derekmolloy.ie/
 */

#include "SocketClient.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
using namespace std;

namespace exploringBB {

SocketClient::SocketClient(std::string serverName, int portNumber) {
	this->socketfd = -1;
	this->server = NULL;
	this->serverName = serverName;
	this->portNumber = portNumber;
	this->isConnected = false;
}

int SocketClient::connectToServer(){

    socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if (socketfd < 0){
    	perror("Socket Client: error opening socket.\n");
    	return 1;
    }
    server = gethostbyname(serverName.data());
    if (server == NULL) {
        perror("Socket Client: error - no such host.\n");
        return 1;
    }
    bzero((char *) &serverAddress, sizeof(serverAddress));
    serverAddress.sin_family = AF_INET;
    bcopy((char *)server->h_addr,(char *)&serverAddress.sin_addr.s_addr, server->h_length);
    serverAddress.sin_port = htons(portNumber);

    if (connect(socketfd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0){
    	perror("Socket Client: error connecting to the server.\n");
    	return 1;
    }
    this->isConnected = true;
    return 0;
}

int SocketClient::send(std::string message){
	const char *writeBuffer = message.data();
	int length = message.length();
    int n = write(this->socketfd, writeBuffer, length);
    if (n < 0){
       perror("Socket Client: error writing to socket");
       return 1;
    }
    return 0;
}

string SocketClient::receive(int size=1024){
    char readBuffer[size];
    int n = read(this->socketfd, readBuffer, sizeof(readBuffer));
    if (n < 0){
       perror("Socket Client: error reading from socket");
    }
    return string(readBuffer);
}

int SocketClient::disconnectFromServer(){
	this->isConnected = false;
	close(this->socketfd);
	return 0;
}

SocketClient::~SocketClient() {
	if (this->isConnected == true){
		disconnectFromServer();
	}
}

} /* namespace exploringBB */

SocketServer.h

Listing 10-11: SocketServer.h
/*
 * SocketServer.h  Created on: 13 Jul 2014
 * Copyright (c) 2014 Derek Molloy (www.derekmolloy.ie)
 * Made available for the book "Exploring BeagleBone" 
 * See: www.exploringbeaglebone.com
 * Licensed under the EUPL V.1.1
 *
 * This Software is provided to You under the terms of the European 
 * Union Public License (the "EUPL") version 1.1 as published by the 
 * European Union. Any use of this Software, other than as authorized 
 * under this License is strictly prohibited (to the extent such use 
 * is covered by a right of the copyright holder of this Software).
 * 
 * This Software is provided under the License on an "AS IS" basis and 
 * without warranties of any kind concerning the Software, including 
 * without limitation merchantability, fitness for a particular purpose, 
 * absence of defects or errors, accuracy, and non-infringement of 
 * intellectual property rights other than copyright. This disclaimer 
 * of warranty is an essential part of the License and a condition for 
 * the grant of any rights to this Software.
 * 
 * For more details, see http://www.derekmolloy.ie/
 */

#ifndef SOCKETSERVER_H_
#define SOCKETSERVER_H_

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string>

namespace exploringBB {

class SocketServer {
private:
	int 		portNumber;
    int 	    socketfd, clientSocketfd;
    struct 	    sockaddr_in   serverAddress;
    struct 	    sockaddr_in   clientAddress;
    bool		clientConnected;

public:
	SocketServer(int portNumber);
	virtual int listen();
	virtual int send(std::string message);
	virtual std::string receive(int size);
	virtual ~SocketServer();
};

} /* namespace exploringBB */

#endif /* SOCKETSERVER_H_ */

SocketServer.cpp

Listing 10-11: SocketServer.cpp
/*
 * SocketServer.cpp  Created on: 13 Jul 2014
 * Copyright (c) 2014 Derek Molloy (www.derekmolloy.ie)
 * Made available for the book "Exploring BeagleBone" 
 * See: www.exploringbeaglebone.com
 * Licensed under the EUPL V.1.1
 *
 * This Software is provided to You under the terms of the European 
 * Union Public License (the "EUPL") version 1.1 as published by the 
 * European Union. Any use of this Software, other than as authorized 
 * under this License is strictly prohibited (to the extent such use 
 * is covered by a right of the copyright holder of this Software).
 * 
 * This Software is provided under the License on an "AS IS" basis and 
 * without warranties of any kind concerning the Software, including 
 * without limitation merchantability, fitness for a particular purpose, 
 * absence of defects or errors, accuracy, and non-infringement of 
 * intellectual property rights other than copyright. This disclaimer 
 * of warranty is an essential part of the License and a condition for 
 * the grant of any rights to this Software.
 * 
 * For more details, see http://www.derekmolloy.ie/
 */

#include "SocketServer.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
using namespace std;

namespace exploringBB {

SocketServer::SocketServer(int portNumber) {
	this->socketfd = -1;
	this->clientSocketfd = -1;
	this->portNumber = portNumber;
	this->clientConnected = false;
}

int SocketServer::listen(){
    this->socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if (this->socketfd < 0){
    	perror("Socket Server: error opening socket.\n");
    	return 1;
    }
    bzero((char *) &serverAddress, sizeof(serverAddress));
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_addr.s_addr = INADDR_ANY;
    serverAddress.sin_port = htons(this->portNumber);
    if (bind(socketfd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0){
    	perror("Socket Server: error on binding the socket.\n");
    	return 1;
    }
    ::listen(this->socketfd, 5);
    socklen_t clientLength = sizeof(this->clientAddress);
    this->clientSocketfd = accept(this->socketfd,
    		(struct sockaddr *) &this->clientAddress,
    		&clientLength);
    if (this->clientSocketfd < 0){
    	perror("Socket Server: Failed to bind the client socket properly.\n");
    	return 1;
    }
    return 0;
}

int SocketServer::send(std::string message){
	const char *writeBuffer = message.data();
	int length = message.length();
    int n = write(this->clientSocketfd, writeBuffer, length);
    if (n < 0){
       perror("Socket Server: error writing to server socket.");
       return 1;
    }
    return 0;
}

string SocketServer::receive(int size=1024){
    char readBuffer[size];
    int n = read(this->clientSocketfd, readBuffer, sizeof(readBuffer));
    if (n < 0){
       perror("Socket Server: error reading from server socket.");
    }
    return string(readBuffer);
}

SocketServer::~SocketServer() {
	close(this->socketfd);
	close(this->clientSocketfd);
}

} /* namespace exploringBB */

Some High-Resolution Figures from this Chapter

Here are high-resolution images of some of the more complex figures in this chapter, which may help you in wiring the circuits. Please note that you can close this pop-up window by pressing the Escape key.

External Resources

Important Documents

External Web Sites

AM335x ARM A8 Technical Reference Manual

The AM335x Technical Reference Manual (TRM)

BeagleBone Black System Reference Manual

The BeagleBone Black System Reference Manual (SRM)

Errata

Second Edition

  • None so far

First Edition

  • Page 391. There should be a line echo “” after the line echo “Content-type: text/html” in the script that displayed in the center of the page. The code in the GitHub repository is correct.
  • Page 396. The title of code Listing 10-2 should be /exploringBB/chp10/WebBrowser/WebBrowser.c not WebClient/WebClient.c. The correct title is used in the description and elsewhere.

Recommended Books on the Content in this Chapter

[amazon asin=0996025510&template=Iframe Image] [amazon asin=1449393578&template=Iframe Image] [amazon asin=0789722410&template=Iframe Image] [amazon asin=0131411551&template=Iframe Image] [amazon asin=0071626751&template=Iframe Image] [amazon asin=1593272200&template=Iframe Image]

Feel free to contact us on Social Media, we were recently able to Buy automatic instagram likes for all our content, this way the posts will grow on popularity.