Real-Time Vibration Monitoring with ThingsBoard and Calculated Fields
device profileThis guide shows how to build a complete end-to-end industrial vibration monitoring system from a real Balluff condition monitoring sensor, through a virtual PLC, to a live ThingsBoard dashboard with ISO 10816-compliant alarms.
Unlike the previous article, which used simulated telemetry from Node-RED, this guide uses real vibration data from a physical sensor connected via IO-Link and streamed live to ThingsBoard using OPC UA and MQTT.
By the end of this guide, you will have:
Real X/Y/Z vibration RMS data streaming from a Balluff condition monitoring sensor
A reComputer vPLC reading sensor data via Modbus TCP/IP over IO-Link
A reComputer R1100 bridging data from the vPLC (OPC UA) to ThingsBoard's MQTT Broker using Node-RED
ThingsBoard Calculated Fields compute ISO 10816 vibration severity and machine health status in real time
A professional dashboard with a colour-coded gauge, alarms, and a dynamic machine health card
Hardware & Software Used
Hardware
Edge Computer (vPLC host)
Seeed reComputer R2100 (OpenPLC Runtime)
Edge Gateway and ThingsBoard Host
Seeed reComputer R1100
IO-Link Master
Balluff BNI00L3
Condition Monitoring Sensor
Balluff BCM R15E-001-DI00-01,5-S4
Software
OpenPLC vPLC Runtime (on reComputer R2100)
Node-RED (on reComputer R1100)
ThingsBoard Community Edition (on reComputer R1100)
System Architecture
Before diving into the steps, it's helpful to understand how data flows through the system.
๐ก Why two edge devices? The vPLC (reComputer R2100 running OpenPLC) is dedicated to real-time scan-cycle control and sensor I/O. A separate computer, R1100, handles the edge communication. This separation keeps the PLC runtime clean and follows industrial best practices for separating control logic from data forwarding.
Step 1: Hardware Setup (vPLC + IO-Link)
This step is covered in detail in the Virtual PLC interfacing with IO-Link Master article.
In summary, the vPLC:
Connects to the Balluff IO-Link Master over Modbus TCP/IP
Reads X/Y/Z VRMS and Temperature from registers
IW1โIW8Uses a custom C++ WTOR function block to byte-swap Big-Endian 32-bit floats into usable
REALvaluesStores the results in
rX_VRMS,rY_VRMS,rZ_VRMS, andrTemp
Key point: The Balluff sensor sends each float split across 2 ร 16-bit Modbus registers in Big-Endian format. A direct cast to REAL gives garbage values โ the byte swap is mandatory. The WTOR function block handles this automatically.
Once the vPLC is running and reading correct values, proceed to Step 2.
Step 2: Expose vPLC Data via OPC UA
The vPLC exposes its runtime variables as an OPC UA Server. This allows the reComputer R1100 to read live values without changing the PLC program.
OpenPLC Runtime includes a built-in OPC UA server. No additional configuration is required; variables declared in the PLC program are automatically available as OPC UA nodes.
Note the OPC UA server address of the vPLC; you will need this in the next step:
Replace 192.168.100.10 with the actual IP address of your vPLC.
Step 3: Bridge OPC UA to MQTT using Node-RED
The reComputer R1100 runs Node-RED as the middleware layer. It acts as an OPC UA client that reads vibration values from the vPLC and publishes them to ThingsBoard's MQTT broker every second.
Build the flow

The flow consists of three parts:
OPC UA Read
Add an OPC UA Client node and configure it:
Endpoint:
opc.tcp://192.168.100.10:4840Action:
READNode IDs to read:
ns=4;i=1ns=4;i=2ns=4;i=3ns=4;i=4ns=4;i=5ns=4;i=6ns=4;i=7
The exact node ID format depends on your OpenPLC version. Use the OPC UA browser (built into the OpcUa-Client node) to confirm the correct node paths for your setup.
Create a Device Profile in ThingsBoard
Device profiles in ThingsBoard allow an administrator to define and centrally manage common settings for multiple devices. This greatly simplifies the management of a large number of similar devices, making it especially valuable in IoT solutions where numerous devices share identical configurations and behaviors.
Learn more about the device profile here
Go to Profiles โ Device Profiles in the left menu โ click + โ Create new device profile

Create a new device
Create a new device and link that to the device profile created above. In our case, the new device is named 'OpenPLC', linked to the device profile 'Vibration Sensor'.

How to Link your device to the "Vibration Sensor" device Profile
Step 1: Go to Entities โ Devices
Step 2: Click on OpenPLC (your device) to open its details
Step 3: Click the pencil/edit icon (โ๏ธ) in the top right of the details panel
Step 4: Find the "Device profile" field โ currently shows default
Step 5: Click on it and select "Vibration Sensor" from the dropdown

Step 6: Click Save / Apply changes

Format and publish the PLC data to the MQTT Broker
Add a Function node in the Node-RED to format the payload:
Add an MQTT Out node with the ThingsBoard connection details as shown below.
Broker
192.168.0.227
(IP of reComputer R1100)
Port
1883
Topic
v1/devices/me/telemetry
Username
Your ThingsBoard device username. Check this step to learn how to get the username.
Password
(leave blank)
Step 4: Create Calculated Fields in ThingsBoard
This is where the raw sensor data becomes actionable. ThingsBoard v4.0 introduced Calculated Fields, a built-in logic layer that transforms incoming telemetry in real time without any external scripts or rule chains.
We will create two calculated fields:
Overall Vibration Severity: combines X/Y/Z into a single ISO 10816 metric
Machine Status: classifies the severity into a human-readable health state
Best Practice Note: Instead of attaching a calculated field to a specific device (e.g., IoT1), it is recommended to attach it to a Device Profile. This way, the calculated field automatically applies to all devices sharing that profile, making your setup scalable and maintainable without duplicating configuration.
Calculated Field 1: Overall Vibration Severity (ISO 10816)
Navigate to your Left tree menuโ Calculated Fields tab โ click +.
General settings:
Title
Overall Vibration Severity (ISO 10816 compliant)
Type
Script
Add three arguments:
plc_rSensorX_vrms
Latest telemetry
plc_rSensorX_vrms
plc_rSensorY_vrms
Latest telemetry
plc_rSensorY_vrms
plc_rSensorZ_vrms
Latest telemetry
plc_rSensorZ_vrms

Add this Script:
Output: Time series
Why vector magnitude? Using sqrt(Xยฒ + Yยฒ + Zยฒ) rather than the maximum individual axis, it gives you the true Euclidean magnitude of the vibration vector. This is the correct approach for ISO 10816 compliance and eliminates false negatives, a situation where all three axes are below threshold individually, but combined vibration is dangerously high.
Calculated Field 2: Machine Status
Navigate to Calculated Fields โ click + again.
General settings:
Title
Machine Status
Type
Script
Arguments:
vibration_severity
Latest telemetry
vibration_severity
0

โ ๏ธ Setting a default value of
0is important. Without it, ifvibration_severityhas not yet been computed, the argument receivesnull, the comparison fails, and the status incorrectly showsCRITICAL.
Add this Script:

ISO 10816-3 zone reference:
A
0 โ 2.3 mm/s
HEALTHY
Good - new or recently serviced
B
2.3 โ 4.5 mm/s
WARNING
Acceptable - monitor closely
C
4.5 โ 7.1 mm/s
CRITICAL
Unsatisfactory - schedule maintenance
D
> 7.1 mm/s
EMERGENCY
Unacceptable - risk of damage
Step 5: Configure Alarms
Navigate to your Device Profile โ Alarm Rules tab.
Create three alarm rules based on vibration_severity:

Alarm 1: Motor Vibration Warning
Condition
return (vibration_severity > 2.3)

Additional info:
[WARNING] Motor Vibration entering Zone B (ISO 10816) Severity: ${vibration_severity} mm/s | Threshold: 2.3 mm/s Axis breakdown โ X: ${plc_rSensorX_vrms} mm/s | Y: ${plc_rSensorY_vrms} mm/s | Z: ${plc_rSensorZ_vrms} mm/s Action: Monitor closely. Schedule inspection if sustained.
Alarm 2: Motor Vibration Critical
Condition
return (vibration_severity > 4.5)

Additional info:
[CRITICAL] Motor Vibration in Zone C โ Maintenance Required (ISO 10816) Severity: ${vibration_severity} mm/s | Threshold: 4.5 mm/s Axis breakdown โ X: ${plc_rSensorX_vrms} mm/s | Y: ${plc_rSensorY_vrms} mm/s | Z: ${plc_rSensorZ_vrms} mm/s Action: Reduce load and schedule immediate inspection.
Alarm 3: Motor Vibration Emergency
Condition
return (vibration_severity > 7.1

Additional info:
[EMERGENCY] Motor Vibration in Zone D โ Shutdown Risk (ISO 10816) Severity: ${vibration_severity_r} mm/s | Threshold: 7.1 mm/s Axis breakdown โ X: ${plc_rSensorX_vrms_r} mm/s | Y: ${plc_rSensorY_vrms_r} mm/s | Z: ${plc_rSensorZ_vrms_r} mm/s Action: Stop machine immediately. Risk of mechanical damage.
Why use vibration_severity for alarms instead of individual axes?
Alarming on individual X/Y/Z values creates two problems: false negatives (all axes below threshold but combined severity is dangerous) and false positives (one axis spikes from a single knock while overall severity stays in Zone A). The combined severity metric is ISO-compliant and gives a much cleaner alarm signal.
Step 6: Build the Dashboard
Vibration Severity Gauge (ISO 10816 bands)

Add widget โ Gauges โ Speed Gauge
Type: Entity
Antity Alias: OpenPLC
Data key: vibration_severity
Configure the colour bands to match ISO 10816 zones in the Scale settings:

0
2.3
#4CAF50 (green)
2.3
4.5
#FFEB3B (yellow)
4.5
7.1
#FF9800 (orange)
7.1
10.0
#F44336 (red)
Additional settings:
Min
0
Max
10
Decimals
1
Units
mm/s
Title
Vibration Severity (ISO 10816)
Final dashboard layout
Arrange the widgets as follows for the clearest operator view:
Reading order:
The left column gives instant health status. The centre column shows the vibration detail over time. The right column shows the temperature and the ISO-calibrated gauge. The alarms table at the bottom provides a full audit history.
How It All Connects
Looking back at the full pipeline:
The Balluff BCM sensor measures tri-axial vibration (X/Y/Z RMS) and temperature continuously
The Balluff IO-Link Master exposes sensor data over Modbus TCP
The reComputer vPLC reads registers every scan cycle, byte-swaps Big-Endian floats, and exposes clean
REALvalues via its OPC UA serverNode-RED on the reComputer R1100 polls the OPC UA server every second and publishes a JSON payload to ThingsBoard via MQTT
ThingsBoard Calculated Fields compute vibration severity (
sqrt(Xยฒ+Yยฒ+Zยฒ)) and classify machine health (HEALTHY / WARNING / CRITICAL / EMERGENCY) in real time, no external scripts neededAlarm rules fire when severity crosses ISO 10816 zone boundaries, with structured alarm messages including rounded axis values
The dashboard gives operators instant visual feedback through a colour-coded health card, ISO-banded gauge, and trend charts
Resources
ThingsBoard Dashboard
To learn how to import a dashboard, kindly refer to the last article here ThingsBoard (Edge Setup)
โฅ๏ธ Work With Me
I regularly test industrial automation and IIoT devices. If youโd like me to review your product or showcase it in my courses and YouTube channel:
๐ง Email: [email protected] or drop me a message on LinkedIn
Last updated










