Feather IIoT Vibration Sensor
2019-05-09 | By Maker.io Staff
License: See Original Project Wireless Adafruit Feather
The Industrial Internet of Things (IIoT) is going to be the future of manufacturing efficiency, with machinery reporting their statuses in real time and AI processing this data to make determinations about the condition of the equipment. In this project, we will build a simple IIoT vibration sensor using an Adafruit Feather board.
BOM
Scheme-It
The Hardware
The hardware behind this vibration sensor is straightforward: it only requires an Adafruit Feather Huzzah and a Sparkfun 1568-1420-ND accelerometer. The Feather Huzzah contains an ESP8266 Wi-Fi SoC, which is the heart of the IIoT sensor system, while the accelerometer is used to record the vibration of the machinery attached to the system. Unfortunately, the Feather Huzzah lacks a VIN pin that can handle large voltages (such as a 9V battery), so power has to be provided via the onboard USB micro B connector.
The accelerometer contains a small tab breakout with a small diagram that indicates the orientation of the sensor (X, Y, and Z). However, we are using the accelerometer, and not the magnetometer, so this tab will be removed in the final design for reducing the size of the IIoT sensor. While this project can be built using many construction techniques, for this project, we will utilize a matrix board that allows the components to be soldered in place and easily wired together, producing a small, compact sensor module that can be easily mounted to a piece of machinery to monitor vibrations.
The Software
This project is only concerned with the sensor side of the IIoT, while our next project will look at the receiver side (a simple IIoT dashboard). While this IIoT device could send information via the internet and to a cloud system, it would be better to use the intranet instead of the internet. This is because the sensor will be streaming large amounts of data continuously during operation, and it makes more sense to stream this data to a local server (because it has a higher bandwidth, no data limits, etc.).
Coding the Huzzah can be done using the Arduino IDE, but a few prerequisites are required:
- The board manager needs to include the ESP8266 additional boards. Use this address in the additional boards’ URL:
- The Arduino IDE requires the MPU9250 library:
- The Adafruit Huzzah USB / UART driver:
Before the sensor is programmed and allowed to run, the Python server (code shown later) must first be executed. This server creates a TCP listener that allows TCP clients to connect and send data to and from the server. In this case, we simply listen for any connection, accept it, and dump data to the console window whenever data is received.
The Huzzah code begins by initiating the MPU9250 sensor as well as connecting to a local network (the same network that our Python server is connected to). Once connected, the Huzzah then initiates a server connection to our Python server (make sure to use the correct IP address here; otherwise, the Huzzah won’t be able to connect).
The main loop of code in the IIoT sensor simply takes readings from the MPU9250 once every 16ms, combines each axis into a single acceleration figure (which directly relates to vibration), and tokenizes this data into a packet that is sent to the server. At the same time, the raw value of the combined acceleration is sent to the serial port, so a serial plotter can be used to view the vibration data live (see below).
The tokenized data is split up using colons (:) , which makes splitting it up easier on the server side. The tokenized data includes several parameters that allow multiple sensors to connect to the server and send data.
The first parameter is the machinery type, which lets the server know how to handle the data (e.g., a drill may have different handling requirements than a lathe or band saw). The second parameter is a unique ID number, given to each IIoT sensor; this allows the server to uniquely identify the device and place the received data into the correct location. The third parameter is the raw data itself in string format. The last parameter is “END,” which is used as an end marker so the server can confirm that the entire packet arrived correctly.
Huzzah Code
#include <ESP8266WiFi.h>
#include "MPU9250.h"
// Wi-Fi details
const char* ssid = "TP-Link_B5AC";
const char* password = "93080422";
WiFiClient client;
// Create an MPU9250 Object
MPU9250 mpu;
// Variables for holding out accelerations
long accel_x, accel_y, accel_z;
long acceleration;
// Setup
void setup()
{
// Allow for printint to a serial terminal
Serial.begin(115200);
// Start an I2C connection to the MPU9250
Wire.begin();
// Setup the sensor
delay(2000);
mpu.setup();
// ******************************************************
// Wi-Fi Code
// Attempt to connect to the Wi-Fi
WiFi.begin(ssid, password);
// Wait until connected
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Connect to the server that will receive the data
client.connect("192.168.1.101", 1000);
// ******************************************************
}
void loop()
{
// Millis is used to time 16ms slots so that we send data once every
// 16ms
static uint32_t prev_ms = millis();
// Check to see if we need to send new data
if ((millis() - prev_ms) > 16)
{
// Update the sensor and get new data
mpu.update();
// Get acceleration of each axis
accel_x = mpu.getAcc(0);
accel_y = mpu.getAcc(1);
accel_z = mpu.getAcc(2);
// Sum the accelerations
// Normally we would do the cube root to get the resultant vector but not bothering
// with the cube root seems to provide more sensitive results
acceleration = (accel_x * accel_x) + (accel_y * accel_y) + (accel_z * accel_z);
// Print the acceleration to the serial port for debugging purposes
Serial.println(acceleration);
// Send the data to out TCP client as a tokenised packet
client.println("DRILL:1:" + String(acceleration) + ":END");
// Record the current timestamp (for 16ms timing)
prev_ms = millis();
}
}
Server Code (Python)
import socket
# Our network detailsTCP_IP = '192.168.1.101'TCP_PORT = 1000BUFFER_SIZE = 64
# Create a TCP socket and listen to its = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.bind((TCP_IP, TCP_PORT))s.listen(1)
# Accept an incoming connectionconn, addr = s.accept()
# Infinite loopwhile 1:
# Get the received data data = conn.recv(BUFFER_SIZE)
# Print the data if not data: break print ("received data:", data)
conn.close()
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum