Simplicity is prerequisite for reliability.
—Edsger Dijkstra
Internet of Things (IoT) is no doubt one of the hottest buzzwords at the moment. If you read technical magazines, it is everywhere. Related to IoT is the concept of Industry 4.0. So, what exactly is IoT, and what is Industry 4.0?
In the broadest sense, Internet of Things (IoT) refers to the global network of interconnected devices or “things.” This is going to be the future of the Internet, which is currently a global network of interconnected computers, including smartphones and tablets. The things in IoT refer to the everyday physical devices that are not primarily computers but have embedded computing hardware (microcontrollers), such as TVs, fridges, cookers, kettles, lights, cars, doors, chairs, and so on. Figure 7.1 shows an illustrative IoT diagram.
To connect these everyday devices to the Internet, you need several technologies.
An IoT system can generally be divided into four building blocks according to Farnell Ltd, a global distributor for electronic products. (https://uk.farnell.com/internet-of-things
), as shown in Figure 7.2.
The Collect block is where you will find the edge devices, which are integrated with sensors and actuators. The sensors are for taking measurements; they include temperature sensors, humidity sensors, smoke sensors, flame sensors, poisonous gas sensors, distance sensors, water level sensors, motion sensors, light sensors, magnetic sensors, and more. The actuators are for doing something, such as opening and closing a valve or a door, moving a component, and so on. The Collect block is the front end of an IoT system.
The Connectivity block is where communication occurs between devices and devices and between devices and users. The communications can be done either wirelessly or through a wired connection. For wireless communication there are a range of technologies, such as Near Field Communication (NFC), Radio Frequency Identification (RFID), Bluetooth, Zigbee, Z-Wave (WPAN), WiFi, LoRa (LPWAN), Sigfox (LPWAN), and the most talked-about cellular technology, 5G. Later in the chapter, you'll see an example using WiFi.
The Control block is where you will find gateway devices that bridge the gap between the Edge block and the Cloud block. The gateway devices receive the data from IoT device sensors or other equipment in a system and send that data to the cloud. The gateway devices are a crucial part of any IoT system, as they also perform protocol translation, data processing, data storage, data filtering, and data security.
The Cloud block is where the data is stored, analyzed, and displayed. The IoT will generate an enormous amount of data, which cannot be stored and analyzed by conventional personal computers, or even local servers, which have limited storage space and computational power. The best way to store and analyze these enormous amounts of data is in the cloud, which is basically a computing service over the Internet. With the cloud, or cloud computing, you can have services such as servers, storage, databases, networking, software, analytics, intelligence, and more. Many technical giants, such as IBM, Google, Microsoft, and Amazon, provide their own cloud computing services. For example, with IBM's Watson Internet of Things (IoT) cloud, you can easily connect your IoT devices, store the data, analyze the data, and display the results on the Web, on computers, and on your mobile devices. Watson provides many sophisticated analysis software, including artificial intelligence, to get the most out of your data. The Cloud block is the brain of an IoT system.
With IoT, business and industry can improve their efficiency and productivity, improve customer engagement, enhance data collection and data analysis, and reduce waste. But with IoT, there will also be some issues, such as security, privacy, complexity, and compliance. Security is always the top priority. More details on security are available later in this chapter and in Chapter 9.
To date, IoT development is already well underway. The number of devices connected to the IoT has increased by 30 percent every year, and there were already about 8.4 billion IoT devices in 2017. By 2020, there will be estimated 30 billion IoT devices and a global market value of $7 trillion. The IoT is largely seen as the Next Big Thing, with many companies spending billions on IoT research and development.
The industrial version of IoT is called Industry 4.0, that is, the fourth industrial revolution. The first industrial revolution happened in the eighteenth century, when the steam engine revolutionized industrial production. The second industrial revolution happened in the nineteenth century, when electric power and the assembly line made mass production possible. The third industrial revolution, also called the digital revolution, happened at the twentieth century, when electronics and computers made automated production possible. The first three industrial revolutions all have significantly improved productivity.
The next industrial revolution, Industry 4.0, is on the horizon. In this revolution, suppliers, logistics, factories, and customers will be tightly integrated together. This will even more significantly improve productivity. Robotics and artificial intelligence will be widely used. All the data will be stored in the cloud, and artificial intelligence will be used to analyze the data, to predict trends, and to identify faults. Virtual production will also allow manufacturers to design, create, and test products in a virtual environment. Customers will be able to view and customize products online, and there will be increasing focus on customized and smart products. This trend is also referred to as intelligent manufacturing, with its products described as smart-made. Industry 4.0 will require a smaller and highly skilled workforce. Figure 7.3 illustrates the concept.
The devices on the IoT communicate differently than computers communicating on the Internet, which tend to use a lot of bandwidth to transmit a large amount of data, for which timing is not always important. The most commonly used Internet protocol is the Hypertext Transfer Protocol (HTTP), which is the magic behind the World Wide Web (WWW). Devices on the IoT tend to have limited power supply, limited computing power, and limited bandwidth. They typically need to transmit a small amount data intermittently, but timing is often important. There are several communication protocols specifically designed for such communications. The following are some of the most important IoT protocols.
Message Queuing Telemetry Transport (MQTT), developed by IBM in 1999, is a publish-subscribe messaging protocol. At the heart of MQTT is the MQTT broker, which accepts and publishes the messages. Figure 7.4 shows how MQTT works. In this example, a topic called temperature is first created on the MQTT broker. Then the temperature sensor, the laptop, and the mobile device all subscribe to the topic. The temperature sensor will make a measurement from time to time and publish the data to the topic on the MQTT broker. The MQTT broker will then relay the data to the laptop, which is the mobile device. Compared with HTTP protocols, MQTT requires much less computing power, less bandwidth, and less power consumption. You will explore an MQTT example later in the chapter.
MQTT offers three levels of quality of service (QoS).
For more information about MQTT, see the following resources:
Constrained Application Protocol (CoAP) is a specialized web transfer protocol for use with constrained IoT devices (with limited computing power and limited power consumption) and constrained IoT networks (with limited bandwidth). The protocol is designed for machine-to-machine (M2M) applications such as smart energy and building automation. CoAP is based on request and response messages, similar to HTTP, but instead of running on Transmission Control Protocol (TCP), it uses User Datagram Protocol (UDP). CoAP hence has much smaller headers and is much faster.
For more information about CoAP, see the following resource:
Extensible Messaging and Presence Protocol (XMPP) is an open standard communication protocol based on the Extensible Markup Language (XML). XMPP enables real-time communication between IoT devices using structured, extensible messages. It provides a wide range of applications including instant messaging, presence, and collaboration.
For more information about XMPP, see the following resource:
Simple Object Access Protocol (SOAP) is another XML-based messaging protocol, designed by Microsoft, for exchanging information among computers via the Internet. With XML messages, SOAP is highly extensible and can be used for web services.
For more information about SOAP, see the following resource:
Representational State Transfer (REST) is a lightweight architectural style for web services. REST is based on Uniform Resource Identifier (URIs) and Hypertext Transfer Protocol (HTTP), and it uses JavaScript Object Notation (JSON) for a data format. REST is fully browser compatible. We will explore a REST example later in the chapter.
For more information about REST, see the following resource:
IoT platforms are software run on the Internet (the cloud) that connects sensors and user devices using IoT protocols such as MQTT, CoAP, XMPP, and so on. IoT platforms are also used for storing data, analyzing data, and displaying data. Artificial intelligence is often implemented in the IoT platforms to provide complex analysis.
The following is a list of popular IoT platforms.
https://iot.eclipse.org/
https://cloud.oracle.com/iot
https://www.ibm.com/watson/
https://aws.amazon.com/
https://azure.microsoft.com/en-us/
https://cloud.google.com/
https://www.salesforce.com/uk/products/iot-cloud/overview/
Security is fundamentally important for the IoT. With more and more devices connected to the IoT, there is an increasing risk of attacks, hacking, intrusions, and data theft. For many businesses, IoT security is the top priority when adopting IoT technologies.
To protect IoT systems and devices, IoT manufacturers should make hardware secure from the beginning, make it tamper-proof, ensure secure upgrades, and provide firmware updates/patches. IoT software developers should focus on secure software development and secure software integration. For those deploying IoT systems, the focus should be on hardware security and authentication. Finally, IoT operators should keep systems up-to-date and prevent system security from being compromised by mitigating malware, performing auditing, protecting infrastructure, and safeguarding credentials.
Java, with its rich networking functionality and high level of security, can be used in many IoT applications. According to Oracle, Java can be used in machine-to-machine (M2M) devices, wireless modules, industrial control, smart meters/sensors, and ehealth/telehealth. For example, Java can be used on many small, embedded systems, such as the Raspberry Pi, to read sensor data, transmit the data to the cloud, and perform controls.
With Java, devices can become more integrated and more efficient in exchanging information, which provides an enhanced experience. The devices can also have the ability to upgrade themselves and manage themselves, which enhances the life cycle of the products and reduces the product support cost. Java is an easy language to learn and to use. According to Oracle, there are more than nine million Java developers in the world. Market reach can also be increased with reusable modules and platform independence. Finally, the use of Java makes the devices secure and reliable.
To compile Java programs in embedded devices, you will need a full operating system. The following are the three most popular devices—single-board computers—that run on the full Linux operating system and fully support Java. (For all of these devices, the specifications shown are based on models currently available at the time of writing and may have been upgraded by the time you read this.)
https://www.raspberrypi.org/
https://beagleboard.org/
https://www.hardkernel.com/
Here we are focused only on the Raspberry Pi, as it is the most popular embedded device. The Raspberry Pi is a credit-card-size single-board computer developed to promote the teaching of computer science in schools. The popularity of the Raspberry Pi has grown steadily since its introduction in 2005. By March 2018, 19 million Raspberry Pi devices had been sold worldwide. There have been several versions of it; the latest is Raspberry Pi 3, which has built-in WiFi and Bluetooth. Figure 7.5 shows the Raspberry Pi 3 Model B board and its key components. Figure 7.6 shows the Raspberry Pi 3 Model B 40 GPIO pinout diagram (https://pi4j.com/1.2/pins/model-3b-rev1.html
).
To run Java on the Raspberry Pi, you will first need to have the Raspberry Pi hardware. You can visit the Raspberry Pi web site to find the nearest distributor or simply get it from Amazon or eBay. All the instructions here are based on the Raspberry Pi 3 Model B board.
Along with the Raspberry Pi board, you will also need a microSD card of 8GB or more to store the operating system called Raspbian, a GNU Debian Linux operating system. You can get a pre-installed Raspbian microSD card from either of the following:
https://uk.rs-online.com/
https://thepihut.com/products/raspbian-preinstalled-sd-card
Or you can download the operating image from https://www.raspberrypi.org/downloads/
.
Figure 7.7 shows the Raspberry Pi Software Guide web site (https://www.raspberrypi.org/learning/software-guide/quickstart/
), which provides a comprehensive guide to Raspbian software download and installation, as well as setting up the Raspberry Pi board and getting it running.
To interact with the Raspberry Pi board, you will need a USB keyboard, a USB mouse, and either a TV with an HDMI port or a standard computer monitor through an HDMI-to-VGA converter.
Alternatively, you can connect the Raspberry Pi remotely using secure shell (SSH) or the Windows Remote Desktop Connection. To use SSH, you need to enable the SSH service on the Raspberry Pi first. You can enable the SSH service in one of three ways.
sudo raspi-config
. From the configuration menu, select Interfacing Options, navigate to and select SSH, choose Yes, select OK, and choose Finish. Here sudo
means execute the command as a superuser, that is, as an administrator.$ sudo systemctl enable ssh
$ sudo systemctl start ssh
My favorite approach is to connect Raspberry Pi using the Windows Remote Desktop Connection, as SSH only provides a text mode connection. To do this, you will need to install the xrdp
and tightvncserver
packages on your Raspberry Pi first, using the following commands:
$ sudo apt-get remove xrdp vnc4server tightvncserver
$ sudo apt-get install tightvncserver
$ sudo apt-get install xrdp
Next connect your Raspberry Pi to the Internet using Ethernet cable or WiFi. To use the Windows Remote Desktop Connection to connect to Raspberry Pi, you will need to know the Raspberry Pi's IP address. If you don't have a TV with HDMI port or an HDMI-to-VGA converter, you can use a free program called the Advanced IP Scanner (https://www.advanced-ip-scanner.com/
) to scan the Raspberry Pi's IP address, as shown in Figure 7.8.
After you find the IP address, you can then use Windows Remote Desktop Connection to remotely log in to the Raspberry Pi. After typing in the username and password (the default is pi and raspberry), you should see the Raspberry Pi desktop, as shown in Figure 7.8.
Once the Raspberry Pi is up and running, you will need the Java JDK software, which should be included with the standard Raspbian operating system, including BlueJ Java IDE. If it is not or you want to install a different version of Java JDK software, you can simply run the following commands in a Raspbian terminal:
$ sudo apt-get update
$ sudo apt-get install oracle-java8-jdk
These commands install Java 8 on the Raspberry Pi, because Java 9 and later versions are not easily available. To read and write Raspberry Pi general-purpose input-output (GPIO) pins, you will also need to download and install the Pi4J library (http://pi4j.com/
), as shown in Figure 7.9. There are different ways of downloading and installing the Pi4J library; I prefer to download the entire source from GitHub.
With setup completed, you can begin building your first Raspberry Pi Java application, using the GPIO pins first to control a blinking LED. Your code will be based on an example from the Pi4J library.
To start, create a dedicated folder for your Java programs. In my case, I created a folder called IoT Java
under the standard Documents
folder, as shown in Figure 7.10. From the Pi4J library download folder, find the file called pi4j-core.jar
and copy it to the IoT Java
folder. Also, find an example file called ControlGpioExample.java
and copy it to the IoT Java
folder. Then, from the Terminal window, use the cd
command to navigate to the IoT Java
folder. You can use the command nano ControlGpioExample.java
to view and modify the code.
The following is the full code, which basically uses GpioFactory.getInstance()
to create a GPIO object and provisionDigitalOutputPin()
to set the GPIO pin as digital output. In this case, it selects GPIO pin 01 as the digital output and then switches it to high, waits for 5000ms, switches it to low, waits for another 5000ms, and finally toggles it on and off. If you connect an LED to that pin, it will set the LED on and off accordingly.
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
/**
* This example code demonstrates how to perform simple state
* control of a GPIO pin on the Raspberry Pi.
*
* @author Robert Savage
*/
public class ControlGpioExample {
public static void main(String[] args) throws InterruptedException {
System.out.println("<--Pi4J--> GPIO Control Example … started.");
// create gpio controller
final GpioController gpio = GpioFactory.getInstance();
// provision gpio pin #01 as an output pin and turn on
final GpioPinDigitalOutput pin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01, "MyLED", PinState.HIGH);
// set shutdown state for this pin
pin.setShutdownOptions(true, PinState.LOW);
System.out.println("--> GPIO state should be: ON");
Thread.sleep(5000);
// turn off gpio pin #01
pin.low();
System.out.println("--> GPIO state should be: OFF");
Thread.sleep(5000);
// toggle the current state of gpio pin #01 (should turn on)
pin.toggle();
System.out.println("--> GPIO state should be: ON");
Thread.sleep(5000);
// toggle the current state of gpio pin #01 (should turn off)
pin.toggle();
System.out.println("--> GPIO state should be: OFF");
Thread.sleep(5000);
// turn on gpio pin #01 for 1 second and then off
System.out.println("--> GPIO state should be: ON for only 1 second");
pin.pulse(1000, true); // set second argument to 'true' use a blocking call
// stop all GPIO activity/threads by shutting down the GPIO controller
// (this method will forcefully shutdown all GPIO monitoring threads and scheduled tasks)
gpio.shutdown();
System.out.println("Exiting ControlGpioExample");
}
}
To compile and run the program, enter the following commands. It is important to include the pi4j-core.jar
file in the classpath when compiling and running the program. It is also important to run the program as a superuser.
$ javac -classpath ".:pi4j-core.jar" ControlGpioExample.java
$ sudo java -classpath ".:pi4j-core.jar" ControlGpioExample
If you don't want to retype all the lengthy classpath details each time you compile and run the program, you can also create a shell script that does this automatically; see Figure 7.11. In this case, I created a Bash shell script file called ControlGpioExample.sh
, which has the following content:
#!/bin/Bash
javac -classpath ".:pi4j-core.jar" ControlGpioExample.java
sudo java -classpath ".:pi4j-core.jar" ControlGpioExample
The hash exclamation mark (#!
) is referred to as the shebang, followed by the path to the shell program. Here I'm using the Bash shell, but there are many other types of shell programs. The shebang must appear on the first line of the script file, and there must also be no spaces before the #
or between the !
and the path to the shell program. To run the shell script, simply type the following:
$ bash ControlGpioExample.sh
Based on the ControlGpioExample.java
program, you can create a simple GPIO blinking LED demo program, as shown in Example 7.1. This application will use pin GPIO_01
as the digital output pin and set the pin voltage high and low every 500ms. If you connect an LED to the pin, as illustrated in Figure 7.12, the LED will flash on and off accordingly.
You can also create a simple Morse code demo program, as shown in Example 7.2. This program uses pin GPIO_01
as the digital output pin and sets the pin voltage high and low, according to the Morse code for the letter A, which is dot, dash, short space. Again, if you connect an LED to the pin, it will flash the Morse code accordingly.
Example 7.3 shows another GPIO example; it uses pin GPIO_01
as the digital output pin and toggles it high and low every 1000 milliseconds using the toggle()
class in a for
loop ten times.
The GPIO pins can also be set as digital inputs. Example 7.4 shows how to set up GPIO pin 29 as the digital input and display its state using the getState()
class in a for
loop for ten times. You can attach a push button to GPIO pin 29, as illustrated in Figure 7.13. The resistors are simply used to protect the board. When you run the program, if you push down the button, the state of GPIO pin 29 will be shown as low; otherwise, it will be shown as high.
As you saw in Chapter 3, Java can also run system programs and commands. In the Raspberry Pi, Python is the default programming language that has all the natively supported functions. So if there is something you cannot do in Java, you can also call Python programs from within your Java program.
For example, the following is a simple Python GPIO program that turns the GPIO_01
pin on and off every half a second. It uses the Python GPIO Zero library for working with GPIO pins. Let's assume this program is called led.py
, and it is in the /home/pi/
folder. Python uses # as comments.
#Example 7.4 Python GPIO example - led.py
#Modified from https://gpiozero.readthedocs.io/en/stable/
from gpiozero import LED #import the GPIO Zero library
from time import sleep
led = LED(18) #GPIO_01 is 18 in GPIO Zero
while True:
led.on()
sleep(0.5)
led.off()
sleep(0.5)
For more information about the Python GPIO Zero library and its pin numbering, please visit the following resources:
https://gpiozero.readthedocs.io/en/stable/
https://gpiozero.readthedocs.io/en/stable/recipes.html
Example 7.5 is a demonstration program that makes a system call to run led.py
within the Java program. Since led.py
runs on an infinite loop, you need to press Ctrl+C on the keyboard to stop the program.
Pulse Width Modulation (PWM) is a useful technique for many embedded systems. PWM can be used to control the brightness of an LED or to control a motor. In the Pi4J library, there is also a PWM example program, named PwmExample.java
. Based on the previous example, you can create a simple Java PWM example program, listed in Example 7.6. This program uses the CommandArgumentParser.getPin()
class to set the default parameters such as PWM pin, in this case GPIO_01
, and uses the provisionPwmOutputPin()
class to create a PWM
object. It uses pwmSetMode()
to set the PWM mode (PWM_MODE_BAL
or PWM_MODE_MS
), and it uses pwmSetRange()
to set the PWM range (the default is 1024; here I'm setting it at 1000). It also uses pwmSetClock()
to set the divisor for the PWM clock, which specifies the frequency of the PWM signal, as follows:
DIVISOR | FREQUENCY | NOTES |
2048 | 9.375 kHz | |
1024 | 18.75 kHz | |
512 | 37.5 kHz | |
256 | 75 kHz | |
128 | 150 kHz | |
64 | 300 kHz | |
32 | 600.0 kHz | |
16 | 1.2 MHz | |
8 | 2.4 MHz | |
4 | 4.8 MHz | |
2 | 9.6 MHz | Fastest available |
1 | 4.6875 kHz | Same as divisor 4096 |
Finally, it uses setPwm()
to set the PWM rate, here we set it at 500, that is 500 out of 1000, so this is 50 percent PWM duty cycle. In PWM, duty cycle is the percentage of time the PWM pin is on over an interval or period of time. So 50 percent means half of the time the PWM pin is on and half of the time is off.
The following commands show how to compile and run the program. Again, it is important to run the program as a superuser.
$ javac -classpath ".:pi4j-core.jar" PwmExample1.java
$ sudo java -classpath ".:pi4j-core.jar" PwmExample1
Example 7.6A shows another way of running PWM, using the Pi4J library's wiringPi.SoftPwm
class. It uses Gpio.wiringPiSetup()
to initialize the wiringPi
library and uses SoftPwm.softPwmCreate()
to set the PWM pin and the PWM range. In this case, it is the GPIO_01
pin, and the range is from 0 to 100. The code then uses SoftPwm.softPwmWrite()
to write a value to the PWM pin, 50 out of 100, which means 50 percent PWM duty cycle.
Based on the preceding examples, you can create a simple Raspberry Pi and Java smart lighting system using a passive infrared sensor (PIR) sensor and an LED; Figure 7.14 shows the circuit diagram. In this case, it uses the PIR sensor to detect the presence of people and switch on and off the light (LED) accordingly. Example 7.7 shows the Java code.
Example 7.8 is a variation of the previous Java PIR program, which uses Gpio.pinMode()
to set the GPIO pin as either input or output.
Inter-Integrated Circuit (I2C, pronounced “I-squared-C”) is a popular serial communication bus and protocol invented in 1982 by Philips Semiconductor (now NXP Semiconductors). I2C is a two-wire interface to connect low-speed devices such as microcontrollers, digital sensors, EEPROMs, A/D and D/A converters, and similar peripherals in embedded systems. Raspberry Pi comes with I2C support and has two default I2C pins, pin 3 for I2C SDA, and pin 5 for I2C SCL. To use I2C with the Raspberry Pi, you first need to enable it using Raspberry Pi configuration software by typing the following:
$ sudo raspi-config
The raspi-config
interface differs slightly among Raspbian versions. Figure 7.15 shows the interface of Raspbian GNU/Linux 8 (Jessie). You can use the following command to find the version of your Raspbian operating system:
$ cat /etc/os-release
You can use the following commands to upgrade your Raspbian operating system:
$ sudo apt-get update
$ sudo apt-get dist-upgrade
From the raspi-config
interface, use the down arrow to select Interfacing Options. Then choose P5 I2C, press the Enter key, select Yes to enable it, finish the raspi-config
program, and reboot the Raspberry Pi.
MAX30205 is a popular, accurate, I2C-based digital body temperature sensor. Figure 7.16 shows a simple Raspberry Pi I2C circuit with the MAX30205 body temperature sensor. Example 7.9 shows the corresponding I2C Java application code. It uses I2CFactory.getInstance()
to create an I2C object and uses i2c.getDevice()
to get the device at a particular address. It then uses write()
to write a byte to the device and read()
to read a byte from the device.
For more information about the MAX30205 body temperature sensor, visit the following resources:
https://www.maximintegrated.com/en/products/sensors/MAX30205.html
https://www.tindie.com/products/closedcube/max30205-01degc-human-body-temperature-sensor/
https://github.com/closedcube/ClosedCube_MAX30205_Arduino
Example 7.10 shows another I2C Java example, which scans all the addresses from 1 to 128 to see whether there are any I2C devices attached.
For more I2C examples, see the following resources:
https://learn.sparkfun.com/tutorials/raspberry-pi-spi-and-i2c-tutorial/all
https://github.com/Pi4J/pi4j/blob/master/pi4j-example/src/main/java/bananapro/I2CExample.java
The Raspberry Pi does not have analog-to-digital converter (ADC) pins, so it cannot read directly from analog sensors. However, because Raspberry Pi supports I2C, you can use an I2C-based ADC module, such as the ADS1115 16-bit ADC (https://www.adafruit.com/product/1085
), for connecting analog sensors.
Figure 7.17 shows an example circuit diagram of Raspberry Pi, ADS1115 16-bit ADC module board, and the LM35 analog temperature sensor. Raspberry Pi uses I2C to communicate with ADS1115, and ADS1115 reads the LM35 sensor value through channel A0.
Figure 7.18 shows an example circuit diagram of Raspberry Pi, ADS1115 16-bit ADC module, and the light-dependent resistor (LDR) analog light sensor.
In the Pi4j library, there is an ADS1115 code example, named ADS1115GpioExample.java
, that can read four channel values from the ADS1115 module. The following is the full code:
/*
* #%L
* *********************************************************************
* ORGANIZATION : Pi4J
* PROJECT : Pi4J :: Java Examples
* FILENAME : ADS1115GpioExample.java
*
* This file is part of the Pi4J project. More information about
* this project can be found here: http://www.pi4j.com/
* *********************************************************************
* %%
* Copyright (C) 2012 - 2018 Pi4J
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* #L%
*/
import java.io.IOException;
import java.text.DecimalFormat;
import com.pi4j.gpio.extension.ads.ADS1115GpioProvider;
import com.pi4j.gpio.extension.ads.ADS1115Pin;
import com.pi4j.gpio.extension.ads.ADS1x15GpioProvider.ProgrammableGainAmplifierValue;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinAnalogInput;
import com.pi4j.io.gpio.event.GpioPinAnalogValueChangeEvent;
import com.pi4j.io.gpio.event.GpioPinListenerAnalog;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CFactory.UnsupportedBusNumberException;
/**
*
* This example code demonstrates how to use the ADS1115 Pi4J GPIO interface
* for analog input pins.
*
*
* @author Robert Savage
*/
public class ADS1115GpioExample {
public static void main(String args[]) throws InterruptedException, UnsupportedBusNumberException, IOException {
System.out.println("<--Pi4J--> ADS1115 GPIO Example … started.");
// number formatters
final DecimalFormat df = new DecimalFormat("#.##");
final DecimalFormat pdf = new DecimalFormat("###.#");
// create gpio controller
final GpioController gpio = GpioFactory.getInstance();
// create custom ADS1115 GPIO provider
final ADS1115GpioProvider gpioProvider = new ADS1115GpioProvider(I2CBus.BUS_1, ADS1115GpioProvider.ADS1115_ADDRESS_0x48);
// provision gpio analog input pins from ADS1115
GpioPinAnalogInput myInputs[] = {
gpio.provisionAnalogInputPin(gpioProvider, ADS1115Pin.INPUT_A0, "MyAnalogInput-A0"),
gpio.provisionAnalogInputPin(gpioProvider, ADS1115Pin.INPUT_A1, "MyAnalogInput-A1"),
gpio.provisionAnalogInputPin(gpioProvider, ADS1115Pin.INPUT_A2, "MyAnalogInput-A2"),
gpio.provisionAnalogInputPin(gpioProvider, ADS1115Pin.INPUT_A3, "MyAnalogInput-A3"),
};
// ATTENTION !!
// It is important to set the PGA (Programmable Gain Amplifier) for all analog input pins.
// (You can optionally set each input to a different value)
// You measured input voltage should never exceed this value!
//
// In my testing, I am using a Sharp IR Distance Sensor (GP2Y0A21YK0F) whose voltage never exceeds 3.3 VDC
// (http://www.adafruit.com/products/164)
//
// PGA value PGA_4_096V is a 1:1 scaled input,
// so the output values are in direct proportion to the detected voltage on the input pins
gpioProvider.setProgrammableGainAmplifier(ProgrammableGainAmplifierValue.PGA_4_096V, ADS1115Pin.ALL);
// Define a threshold value for each pin for analog value change events to be raised.
// It is important to set this threshold high enough so that you don't overwhelm your program with change events for insignificant changes
gpioProvider.setEventThreshold(500, ADS1115Pin.ALL);
// Define the monitoring thread refresh interval (in milliseconds).
// This governs the rate at which the monitoring thread will read input values from the ADC chip
// (a value less than 50 ms is not permitted)
gpioProvider.setMonitorInterval(100);
// create analog pin value change listener
GpioPinListenerAnalog listener = new GpioPinListenerAnalog()
{
@Override
public void handleGpioPinAnalogValueChangeEvent(GpioPinAnalogValueChangeEvent event)
{
// RAW value
double value = event.getValue();
// percentage
double percent = ((value * 100) / ADS1115GpioProvider.ADS1115_RANGE_MAX_VALUE);
// approximate voltage ( *scaled based on PGA setting )
double voltage = gpioProvider.getProgrammableGainAmplifier(event.getPin()).getVoltage() * (percent/100);
// display output
System.out.println(" (" + event.getPin().getName() +") : VOLTS=" + df.format(voltage) + " | PERCENT=" + pdf.format(percent) + "% | RAW=" + value + " ");
}
};
myInputs[0].addListener(listener);
myInputs[1].addListener(listener);
myInputs[2].addListener(listener);
myInputs[3].addListener(listener);
// keep program running for 10 minutes
Thread.sleep(600000);
// stop all GPIO activity/threads by shutting down the GPIO controller
// (this method will forcefully shutdown all GPIO monitoring threads and scheduled tasks)
gpio.shutdown();
System.out.println("Exiting ADS1115GpioExample");
}
}
The Raspberry Pi can connect to a digital sensor directly. Figure 7.19 shows an example circuit diagram of the Raspberry Pi with the DHT11 digital temperature and humidity sensor. The data pin of the DHT11 sensor is connected to the Raspberry Pi pin 40 (GPIO_29
).
Example 7.11 shows a Java program that can read the temperature and humidity values from the DHT11 digital sensor and check the parity in order to validate the received data.
To compile and execute the program, enter the following commands (or put them into a Linux Shell script):
$ javac -classpath ".:pi4j-core.jar" DHT11Example1.java
$ sudo java -classpath ".:pi4j-core.jar" DHT11Example1
Figure 7.20 shows the output results of the DHT11Example1.java
program, which can read the temperature and humidity from the DHT11 digital sensor.
For more information about the Raspberry Pi and the DHT11 sensor, see the following resources:
http://www.circuitbasics.com/how-to-set-up-the-dht11-humidity-sensor-on-the-raspberry-pi/
https://tutorials-raspberrypi.com/raspberry-pi-measure-humidity-temperature-dht11-dht22/
Message Queuing Telemetry Transport (MQTT) is an IoT protocol that allows IoT devices to publish messages on a topic through a broker, which in turn forwards the messages to all subscribers. In this example, we are going to create a Java MQTT program on the Raspberry Pi. We will use iop.eclipse.org
as the MQTT broker to publish some temperature and humidity information to a topic called PX Temperature and Humidity
, and we will use a computer (or other mobile devices) to subscribe to the topic and receive the messages using the IBM WMQTT A92 program. Figure 7.21 shows a conceptual diagram of the example.
To implement this example, you will need to download two pieces of software:
https://www.eclipse.org/paho/clients/java/
https://github.com/mqtt/mqtt.github.io/wiki/ia92
For the Eclipse Paho Java Client there are different versions, and you can choose the version you prefer. Here, you will use MQTT V3, version 1.0.2, which you can download directly from this link:
For IBM's WMQTT IA92, just go to the GitHub web site and follow the instructions to download and install it. The simplest way is to download it as a zipped file and just unzip it to your computer.
Example 7.12 is a simple Java MQTT program, modified from the MqttPublishSample
Java example on the Eclipse Paho Java Client web site. The program uses iot.eclipse.org
:1883
as the broker, the topic is Temperature and Humidity
, and message content is T=30C
and RH=40%
. The QoS is level 2, which means exactly once.
Put the MQTT JAR file and the Java program in the same folder and then compile and execute the program using the following commands. Here it is important to include the MQTT JAR file in the classpath for both compilation and execution.
$ javac -classpath ".:org.eclipse.paho.client.mqttv3-1.0.2.jar" MqttExample.java
$ sudo java -classpath ".:org.eclipse.paho.client.mqttv3-1.0.2.jar" MqttExample
Figure 7.22 shows the compilation and execution of the MQTTExample.java program.
To view the MQTT messages, go into IBM's WMQTT IA92 unzipped folder called ia92
, and from the J2SE
subdirectory find the wmqttSample.jar
file and double-click it to run it. In case it does not run, you can also run it by typing java –jar wmqttSample.jar
in the Windows command window. Make sure you connect to the iot.eclipse.org
at port 1883
first, and subscribe to the PX Temperature and Humidity topic. Then you will be able to receive the message every time the Java program sends output from Raspberry Pi. Figure 7.23 shows the program and the messages it receives.
Representational State Transfer (REST) is another popular IoT communication protocol, similar to MQTT. But unlike MQTT, REST is web-based. So, you can just use a web browser to view the messages, with no extra software needed. In this example, you'll see how to create a Java REST program on the Raspberry Pi. It will send messages to a REST server, Thingspeak
, and use a web browser to view the messages on a computer.
To do this example, you will need to do two things.
http://unirest.io/java.html
.https://thingspeak.com/
.For the Unirest Java library, there are many ways of downloading and using it. Here I'm downloading the Unirest Java JAR 1.4.9 file with all dependencies as a zipped file called jar_files.zip
from the following link:
https://jar-download.com/artifacts/com.mashape.unirest/unirest-java/1.4.9/source-code
Then just unzip the jar_files.zip
file to a folder, for example, /home/pi/Downloads/unirest-1.4.9/
. It should contain the Unirest unirest-java-1.4.9.jar
file and eight other JAR files; see Figure 7.24.
For the REST server, you will use Thingspeak (https://thingspeak.com/
), which is an open IoT platform with MATLAB analytics. You will need to sign up first, if you do not have an account already. After signing up, you will be able to log in and create a channel. In this case, I create a channel called PX Sensor, whose channel ID is 599274. Figure 7.25 shows the Thingspeak web page of my account. The different tabs show different views. The Private View tab and Public View tab show how the web page looks for private and public users, respectively. The Channel Settings tab shows the channel statistics and the fields. There can be many fields for many sensor values. Here I use only one field, Field 1, named Temperature. The API Keys tab shows the security keys used for writing to and reading from the Thingspeak REST server. The Data Import/Export tab shows how to update and retrieve data from the REST server using API requests.
Example 7.13 shows a Java demonstration of how to send dumb temperature sensor data using the REST protocol to the Thinkspeak REST server web site.
Enter the following lines to compile and execute the program, making sure to include the Unirest library JAR file with all dependencies directory /home/pi/Downloads/unirest-1.4.9/
in the classpath.
$ javac -classpath ".:/home/pi/Downloads/unirest-1.4.9/*" RESTCall.java
$ sudo java -classpath ".:/home/pi/Downloads/unirest-1.4.9/*" RESTCall
Open a web browser, and log in to your Thinkspeak account, from either the Private View or the Public View tab, and you should be able to see the temperature values you are sending out from your Java REST program, as shown in Figure 7.25.
For more information on Java and the Raspberry Pi, see the following resources:
http://www.oracle.com/technetwork/articles/java/raspberrypi-1704896.html#Java%20
,
http://www.oracle.com/technetwork/articles/java/cruz-gpio-2295970.html
https://iot.eclipse.org/java/tutorial/
http://agilerule.blogspot.com/2016/06/java-raspberry-pi-pi4j-pir-motion-sensor.html
http://www.robo4j.io/2017/05/be-ready-and-prepare-raspberry-pi-for.html
In addition to the Java Standard Edition, there is also Java Micro Edition, or Java ME (https://www.oracle.com/technetwork/java/embedded/javame/index.html
). Java ME provides a robust, flexible environment for applications running on embedded and mobile devices in the IoT, such as microcontrollers, smart meters/sensors, gateways, mobile phones, TVs, and printers. Java ME Embedded is a Java runtime that leverages the core Java ME technologies and can run on many embedded devices, such as Freescale FRDM K64F, STM32429I-EVAL (Cortex-M4/RTX), STM 32F746GDISCOVERY (Cortex-M7/RTX), Intel Galileo Gen. 2, and Raspberry Pi (ARM 11/Linux).
For more information, see the following resources:
https://docs.oracle.com/javame/8.1/get-started-freescale-k64/install.htm
http://thomasweldon.com/tpw/courses/eegr6114/javambed/dspJavaMbedNetbeans.html
Besides running Java on embedded systems, you can also use Java to communicate with a range of IoT platforms.
The Eclipse Open IoT Stack for Java is a set of open source technologies that will make it easier for Java developers to build IoT solutions. The focus of the technology is to enable developers to connect and manage the devices, sensors, and actuators that are part of their IoT solution. The Open IoT Stack for Java includes support for a number of popular IoT standards, such as MQTT, CoAP, Lightweight M2M (LWM2M), and a set of services for building IoT Gateways. All the information is available at the Eclipse Open IoT Stack for Java web site (https://iot.eclipse.org/java/
). Eclipse simplifies the development of IoT solutions with Open IoT Stack for Java. There are several interesting Eclipse tutorials, such as to build a smart greenhouse (https://iot.eclipse.org/java/tutorial/
) and to build a smart home (https://www.eclipse.org/smarthome/getting-started.html
).
IBM Watson IoT is another popular IoT platform (https://internetofthings.ibmcloud.com/#/
). Figure 7.26 shows the IBM Watson IoT demonstration web site (http://discover-iot.eu-gb.mybluemix.net/#/play
), where you can connect any of your embedded systems to the IBM IoT cloud and display the sensor readings there, without registration.
There are several interesting web sites, such as the IBM Watson IoT Java client library web site (https://github.com/ibm-watson-iot/iot-java
) and the IBM Watson IoT recipes with Raspberry Pi (https://developer.ibm.com/recipes/tutorials/?s=Raspberry
), as well as the IBM Watson IoT tutorial to use a Raspberry Pi camera and Watson Visual Recognition to determine whether an object of interest is in the image (https://developer.ibm.com/recipes/tutorials/use-a-raspberry-pi-camera-and-watson-visual-recognition-to-determine-if-object-of-interest-is-in-the-image/
).
Amazon Web Services (AWS) offers reliable, scalable, and inexpensive cloud computing services. It's free to join; you pay only for what you use. You can find all the documents on Amazon AWS SDK for Java web site (https://aws.amazon.com/sdk-for-java/
). You can find the example programs available for the Amazon AWS IoT SDK for Java from its GitHub web site (https://github.com/o-can/aws-java-iot-example
).
For more information on the AWS IoT SDK for Java, see the following resources:
https://docs.aws.amazon.com/iot/latest/developerguide/iot-sdks.html#iot-java-sdk
https://aws.amazon.com/blogs/iot/introducing-aws-iot-device-sdks-for-java-and-python/
Microsoft Azure is an open, flexible, enterprise-grade cloud computing platform that provides infrastructure as a service (IaaS), platform as a service (PaaS), and software as a service (SaaS). It supports many different programming languages including Java. IaaS allows users to launch general-purpose Microsoft Windows and Linux virtual machines. PaaS allows developers to easily publish and manage web sites. SaaS allows users to connect to and use cloud-based software over the Internet, such as email, calendaring, and office tools (Microsoft Office 365). Microsoft Azure IoT services allow users—without writing code—to connect, monitor, and control IoT devices; to run analytics on real-time data streams; to store the IoT data; and to automate data access and use data across clouds.
With Microsoft Azure Java SDK, you can develop Java applications to access Microsoft Azure Cloud Services such as Storage, Media Services, Queue Services, Service Bus Queues, and SQL Database. The best place to start with Java on Azure is its Java Developer Center (https://azure.microsoft.com/en-us/develop/java/
), where you can get started with $200 credit and 12 months of popular services at no cost.
In the Microsoft Azure Java documentation hub for Java developers (https://docs.microsoft.com/en-us/java/azure/
), you can find a Get Started guide and more in-depth information. Microsoft Azure SDK for Java is open source software, so you can modify it or change it whatever way you like. You can get the full source code from its GitHub site (https://github.com/Azure/azure-sdk-for-java
).
This chapter introduced the concept of the Internet of Things (IoT), explained how the IoT works, and IoT technologies. It also introduced Java IoT applications with Raspberry Pi and Java for different IoT platforms such as Eclipse Open IoT Stack for Java, IBM Watson IoT, Amazon AWS IoT, and Microsoft Azure IoT.
Q7.1. | What is the Internet of Things (IoT)? |
Q7.2. | How does the IoT works? |
Q7.3. | What are potential IoT applications? |
Q7.4. | What is Industry 4.0? |
Q7.5. | What are IoT communication protocols? |
Q7.6. | What are IoT platforms? Give a few examples. |
Q7.7. | What is the Raspberry Pi? What are other similar embedded computers on the market? |
Q7.8. | What are Raspberry Pi's GPIO pins? |
Q7.9. | What is PWM? Which is the Raspberry Pi's default PWM pin? |
Q7.10. | What is I2C? Which are the Raspberry Pi's default I2C pins? |
Q7.11. | What is MQTT? |
Q7.12. | What is REST? Compare it with HTTP. |
Q7.13. | What is IaaS, PaaS, and SaaS? |
Q7.14. | Compare the different IoT platforms and list the features. |