Get access to the new Intel® IoT Developer Kit, a complete hardware and software solution that allows developers to create exciting new solutions with the Intel® Galileo and Intel® Edison boards. Visit the Intel® Developer Zone for IoT.
Purpose and Overview
Data from the Terasic DE10-Nano's built-in 3-axis accelerometer is measured on ALL 3 axes to show when the board is in motion. The raw output of the accelerometer is converted to g-force values by a sensor library and then sent to graphing software for data visualization and interpretation.
In this tutorial you will:
- Interface with the board's built-in digital accelerometer using an I2C interface.
- Use Intel® I/O and sensor libraries (MRAA and UPM) to get data from the accelerometer.
- Monitor and observe acceleration data for small vibration and movement along the x, y, z axes.
- Translate the acceleration data into +/- g-force values to demonstrate the motion of the Terasic DE10-Nano board.
- Show the accelerometer data using different open-source technologies:
- Express* (web server)
- Plotly* (graphing library)
- Websocket* (data stream).
Note: Both Express.js and Plotly.js are non-restrictive MIT* licensed technologies.
Materials
Hardware
Software
To connect to the board via serial/SSH you will need a client like Putty or TeraTerm.
Libraries
MRAA is an I/O library (abstraction layer) that creates a common interface across plaforms to access various I/O. Here MRAA is used to access the I2C interface connected to the accelerometer.
UPM is a sensor library that provides software drivers for a wide variety of commonly used sensors including the Terasic DE10-nano's on-board accelerometer. These software drivers interact with the underlying hardware platform through calls to MRAA APIs. In this tutorial, the UPM library is used to read data from the board's built-in 3-axis digital accelerometer, the ADXL345 from Analog Devices*.
Note: MRAA and UPM come pre-installed on the default Terasic DE10-Nano microSD card image.
Programming Language
Node.js*
Accelerometer Theory
Speeding Up, Slowing Down, Changing Direction
How does your smart phone know which way is up? And how does it know to change its orientation from portrait to landscape when you rotate your device by 90 degrees clockwise? These motion smart features come courtesy of an accelerometer. An accelerometer is a sensor that measures acceleration (relative to its own frame of reference). You may remember from physics what when velocity—speed with direction—is changing, acceleration is happening. Acceleration includes speeding up, slowing down or changing direction and by measuring acceleration (g-force) along the x, y, and z axes an accelerometer knows up from down.
There are two ways to use an accelerometer:
- Acceleration
- Tilt
Here we use a 3-axis accelerometer to measure acceleration along all 3 axes (x, y, and z).
Note: Recall that the acceleration due to gravity at the Earth's surface is one g.
Communicating with the Accelerometer
Here, we interface with the board's built-in digital accelerometer using an I2C interface. The I2C bus is physically wired up to the ARM* processor on the SoC.
Tutorial Steps
Follow along with the steps below to get data from the Terasic DE10-Nano's built-in accelerometer and plot that data in graphing software.
-
Prepare the Terasic DE10-Nano development board to host the accelerometer application
-
Clone the GitHub* repository
-
Install Express*, Websocket* and Plotly*
-
Unbind the ADXL345* Driver
-
Setup an Express.js Web server
-
Generate a real-time plot using Plotly*
-
Observe the types of forces acting on the board
Step 1: Prepare your Terasic DE10-Nano
Checkpoint: Have you gone through the initial assembly and setup of the Terasic DE10-Nano board?
At this point, we assume you've already gone through the initial assembly and setup for the Terasic DE10-Nano kit. The microSD card that came with the Terasic DE10-Nano kit should be inserted into the board's microSD card slot and your board should be powered on. Please go through the assembly and setup process first!
For instructions on board assembly and setup, check out the Terasic DE10-Nano Setup from the Terasic DE10-Nano Get Started Guide.
Connect to the Board
For this tutorial you'll use a serial connection to the board to perform the initial setup.
Note: We assume you know how to set up a serial terminal on a system. For a reference on how to set up a serial terminal, check out the page here.
Here, you'll connect the board to the internet, get a static IP and then switch over to an SSH connection.
-
Run an Ethernet cable from the Terasic DE10-Nano board to a router.
There are two different network interfaces on the Terasic DE10-Nano board: 1) Ethernet RJ45 as eth0
2) Ethernet over USB (RNDIS) as usb0
In this exercise we use the eth0
interface.
Note: Newer versions of the Terasic DE10-Nano image will contain drivers for most USB Wi-Fi dongles. Unfortunately this exercise does not cover setting up a wireless connection.
-
Get a static IP
Start your preferred terminal application (PuTTY or Tera Term) to establish a serial connection to the Terasic DE10-nano board. Once connected, you should set a password for the root account, by running the passwd
command.
Most modern routers are able to assign a static IP even with DHCP assignment turned on, based on the MAC address of the Ethernet interface. Consult your router's manual for information on how to do this.
If your router doesn't support assigning a static IP for a DHCP client, you can run the following commands to force a static IP on the eth0
interface with connman:
connmanctl config ethernet_000000000000_cable --ipv4 manual <device_ip> <subnet_mask> <gateway_ip>
connmanctl config ethernet_000000000000_cable --nameservers <gateway_ip>
Variable | Description | Example |
---|
<device_ip> | the IP address you want to assign to the Terasic DE10-Nano | 192.168.1.10 |
<subnet_mask> | bit mask to determine what subnet the IP address belongs to | 255.255.255.0 |
<gateway_ip> | gateway/router IP address | 192.168.1.1 |
Please disconnect the USB cable once you complete this step and have the IP address of the board. Using both interfaces at the same time may cause them to interfere.
-
Switch to a Remote SSH connection
Now that you have a static IP, we can switch over to an SSH connection. When you disconnect the USB cable the terminal application will close the previous connection. Start a new terminal instance and use the IP address of the board instead.
Using an SSH connection will be faster, more secure and allows for file transfer to and from the board. This will prove useful if you want to change the plot settings (e.g. remove one of the axes, add data point markers, change the curve smoothness, etc.). This will also allow you to change the project files on the board after running the sample application.
Dynamic Host Configuration Protocol (DHCP)
By default, the Ethernet interface on the board is set to Dynamic Host Configuration Protocol (DHCP) mode, thus it will automatically ask for an IP address from the router that the board was plugged into. The process of connecting to the Terasic DE10-Nano and hosting the graphing webpage is made a lot easier by setting a static IP. This basically means you won't have to edit the client configuration every time you are assigned a new IP address by the router.
Return to DHCP mode (optional)
If you need to revert the changes made to the eth0
interface and return to using DHCP mode, type the command: connmanctl config ethernet_000000000000_cable --ipv4 dhcp
Step 2: Clone the GitHub Repository
Cloning the Github repository which includes the source code for this sample is a straightforward process. The Git client is part of the Terasic DE10-Nano image. To clone the repository type the following command in your SSH session:
git clone https:
This will create a new folder named terasic-de10-nano-kit in the current directory. The source code files for the accelerometer tutorial can be found under terasic-de10-nano-kit/code-samples/accelerometer/de10-adxl345.
Step 3: Install Express, Websocket and Plotly
Enter the application directory by typing:
cd terasic-de10-nano-kit/code-samples/accelerometer/de10-adxl345
When using the sample code from this repository, Express, Websocket and Plotly will get installed by running:
npm install
Step 4: Unbind the ADXL345* Driver
By default Linux* is bound (i.e., "owns") this accelerometer device. Here, we'll need to "unbind" the device from Linux (you know, take that control away from Linux) in order to use it for our program.
By default the adxl34x driver will bind with device 0-0053, you can see that in the directory listing below:
root@de10-nano:~# ls /sys/bus/i2c/drivers/adxl34x
0-0053 bind uevent unbind
The adx34x kernel driver polls the accelerometer continuously and it will interfere with the MRAA library. Furthermore, it enables the auto-sleep feature on the ADXL345, which in turns adds significant delay when reading the values with the UPM driver.
First, reconfigure the device:
root@de10-nano:~# echo 0 > /sys/bus/i2c/drivers/adxl34x/0-0053/autosleep
root@de10-nano:~# echo 15 > /sys/bus/i2c/drivers/adxl34x/0-0053/rate
To unbind the driver you echo the device name to the unbind psuedo file in the sysfs like this:
root@de10-nano:~# echo 0-0053 > /sys/bus/i2c/drivers/adxl34x/unbind
Notice that the device is no longer present in this directory:
root@de10-nano:~# ls /sys/bus/i2c/drivers/adxl34x
bind uevent unbind
To bind the device you echo the device name to the bind pseudo file in sysfs like this:
root@de10-nano:~# echo 0-0053 > /sys/bus/i2c/drivers/adxl34x/bind
[ 871.268013] input: ADXL34x accelerometer as /devices/platform/soc/ffc04000.i2c/i2c-0/0-0053/input/input5
Notice that the device is back:
root@de10-nano:~# ls /sys/bus/i2c/drivers/adxl34x
0-0053 bind uevent unbind
Note: Rebinding the driver is required in case you want to run other accelerometer samples. (Hint: There maybe an accelerometer Easter egg hiding on the microSD card image... Go hunt for it!). Driver changes are not persistent after a reboot.
Step 5: Setup an Express.js Webserver
This webserver uses WebSocket to push live data captured from the accelerometer to the client's browser.
Set the Node.js module lookup path
Before we start the server, let's make sure Node.js knows where to find MRAA and UPM. To do this, we'll set the NODE_PATH
environment variable:
export NODE_PATH=/usr/lib/node_modules
If you want to make this change permanent and have the NODE_PATH
variable exported every time the board boots, use the following command:
echo "export NODE_PATH=/usr/lib/node_modules" > ~/.profile
Start the Web server
Server side code is in the app.js file. This file was generated using an Express.js template and then extended to handle a WebSocket connection. More information on both concepts can be found under references. The server will also send accelerometer data periodically using the UPM ADXL345 library, as explained in the next section.
Client side code can be found in the public/js/index.js file. On the client side, you will need to set the IP address of the Terasic DE10-Nano board:
var connection = new WebSocket('ws://192.168.1.10:3001');
You can use the built-in vi
editor to make the change. Other text editors are available from the official Angstrom repository (e.g. vim, nano). You are now ready to start the server.
Starting Express* is as simple as typing the following command:
npm start
Step 6: Generate a Real-time Plot Using Plotly*
The Plotly* graphing library is used to visualize the data in the form of a real-time plot. The page is accessible from almost any browser/device combo.
To view the graph, use any device connected to the same network as the Terasic DE10-Nano board, open a browser, and go to:
http:
There are a few key components to this application that allow reading data from the accelerometer and pushing it to the client.
On the server side, you'll need to load the UPM library for the ADXL345 and read the g-force values. This is reflected by the following code:
var upm = require('jsupm_adxl345');
And
var adxl = new upm.Adxl345(0);
var gatherData = setInterval(function() {
adxl.update();
var force = adxl.getAcceleration();
force.setitem(2, (force.getitem(2) + 0.08));
connection.send('{"x": ' + force.getitem(0).toFixed(2) + ', "y": ' + force.getitem(1).toFixed(2) + ', "z": ' + force.getitem(2).toFixed(2) + '}');
}, 100);
For the client side, first synchronize the number of messages sent by the server per second:
var messagesPerSecond = 10;
Then, we deserialize the JSON acceleration data received from the server and update the plot:
connection.onmessage = function (message) {
try {
var adxlData = JSON.parse(message.data);
var ts = messagesReceived/messagesPerSecond;
var newData = {
x: [[ts], [ts], [ts]],
y: [[adxlData.x], [adxlData.y], [adxlData.z]]
}
Plotly.extendTraces('myDiv', newData, [0, 1, 2], 60 * messagesPerSecond);
messagesReceived++;
} catch (e) {
console.log('This doesn\'t look like valid JSON: ', message.data);
return;
}
};
The rest of the client side code defines the style of the graph according to the Plotly API.
Keep in mind that the current setup will refresh the data approximately 10 times a second. Feel free to try different values to show more or less data.
Step 7: Observe the Types of Forces Acting on the Board
Static Forces
Force of Gravity
You can observe the force of gravity acting on the board when board is resting on its rubber feet.
The green line (z-axis) should show a constant force of 1g (or 9.8 m/s^2). And, in fact, the force of gravity is always shown on the graph!
Dynamic Forces
Movement
Observe motion along the x (blue), y (orange) and z (green) axes by moving the board:
- Up and down and side to side
- At a 45 degree angle
- Figure eight
Vibration
Observe what happens when you:
- Lightly tap the board
- Drum on on the table
- Place the board on or near something with a constant vibration (e.g., fan motor)
Further Steps and Optimizations
On a PC or laptop, Plotly makes use of hardware acceleration (via webGL) for rendering the charts. Therefore you can work with large datasets, redraw often, and still be able to show responsive graphs. Unfortunately, this feature is unavailable on mobile browsers (e.g. tablets, smartphones). This means the plotting rate is directly impacted and limited to only a few updates per second (1 to 4) for these devices. The good news is that the amount of data you can send over WebSocket is not affected.
A natural optimization would be to collect the data points in buffers on the client side, while continuing to send them at a high rate from the Terasic DE10-Nano. You can then update the graph with several values at once and still keep the graph responsive even on mobile devices.
Conclusion
This exercise shows how easy it is to integrate the MRAA and UPM libraries with other technologies towards building a full IoT application. Many other sensors and actuator libraries, including several rated for industrial use are also available. For a full list of supported sensors please visit the UPM API pages here.
References
Some nice Plotly examples on how to extend graphs with new data:
Additional Resources