Node‑RED is a low‑code, flow‑based visual programming tool (built on Node.js) that lets you wire together hardware, APIs, databases and services to build event‑driven integrations and dashboards easily. It serves as a powerful tool for building Industrial Internet of Things (IIoT) applications, enabling easy integration of hardware, APIs, and cloud services. Node-Red supports key industrial protocols like MQTT, Modbus, and OPC UA for easy data exchange with PLCs, sensors, and machine control systems.
Node‑RED is open‑source under the Apache 2.0 licence and free to use even commercially. The Apache License 2.0 is a permissive open‑source software licence that lets you freely use, modify, distribute the code (even commercially) while requiring attribution, license text inclusion, and granting patent rights
Hands-on Industrial Automation & Control Engineering with Node-RED
A complete guide from simulation to SCADA dashboard
🎯 Target Audience
Engineering students, technicians, process engineers, and IT/OT professionals seeking practical skills in modern industrial automation using open-source tools.
✅ What You’ll Build
By the end of this tutorial, you’ll have:
- A simulated PLC controlling a temperature system
- Node-RED reading/writing via Modbus TCP
- An industrial dashboard with gauges, charts, and alarms
- MQTT integration for IIoT data flow
- A complete monitoring and control system
📋 Prerequisites
- Basic understanding of automation concepts
- Windows/macOS/Linux computer
- Internet connection for downloads
🛠️ Part 1: Environment Setup
1.1 Install Node.js
- Download Node.js LTS from nodejs.org
- Verify installation:
bash
node -v # Should show v18.x or higher npm -v # Should show 9.x or higher
1.2 Install Node-RED
bash
npm install -g --unsafe-perm node-red
Note: On Linux/macOS, you might need sudo
1.3 Start Node-RED
bash
node-red
Access the editor at: http://localhost:1880
🔧 Part 2: Your First Automation Flow
Simulating a Digital Sensor → Actuator Control
2.1 Build the Flow
- In Node-RED editor, drag these nodes from the palette:
- Inject node (timestamp)
- Function node (logic)
- Debug node (output)
- Connect them: Inject → Function → Debug
- Double-click the Function node and paste:
javascript
// Simulate random sensor value (0 or 1)
let sensorValue = Math.random() > 0.5 ? 1 : 0;
// Control logic: If sensor detects something, turn actuator ON
let actuatorState = sensorValue === 1 ? "ACTUATOR ON" : "ACTUATOR OFF";
// Add timestamp
msg.payload = {
timestamp: new Date().toISOString(),
sensor: sensorValue,
actuator: actuatorState
};
return msg;
- Click Deploy (top right)
- Click the inject node’s button – see output in Debug panel
This mimics basic PLC ladder logic!
🏭 Part 3: Industrial Protocols – Modbus TCP
3.1 Install Modbus Nodes
- In Node-RED: Menu → Manage Palette
- Go to Install tab, search for:
node-red-contrib-modbus - Click Install
3.2 Simulate a PLC with OpenPLC
- Install OpenPLC Editor from openplcproject.com
- Create simple ladder logic:
- Input: %IX0.0 (simulated temperature high)
- Output: %QX0.0 (cooling fan)
- Run in simulation mode
3.3 Node-RED Modbus Configuration
text
[Flow Configuration] 1. Modbus Read node → Read Holding Registers 2. Server: localhost:502 (OpenPLC default) 3. Address: 40001 (temperature register) 4. Interval: 2000ms
3.4 Test Modbus Connection
javascript
// Add function node after Modbus Read
msg.payload = {
temperature: msg.payload[0],
unit: "°C",
timestamp: new Date()
};
return msg;
📊 Part 4: Build an Industrial Dashboard
4.1 Install Dashboard
bash
npm install node-red-dashboard
Restart Node-RED
4.2 Create HMI Elements
Temperature Gauge
text
Group: Process Monitoring Tab: Control Room Size: 1x1 Min: 0, Max: 100 Units: °C Range colors: 0-50: green 50-80: yellow 80-100: red
Motor Status LED
text
Label: Main Pump Colors: On=green, Off=grey
Alarm History Table
Use ui_template node with:
html
<div style="max-height: 200px; overflow-y: auto;">
<div ng-repeat="alarm in alarms | orderBy:'timestamp':true"
style="padding: 5px; margin: 2px;
background-color: {{alarm.severity === 'HIGH' ? '#ffcccc' : '#fff3cd'}}">
{{alarm.timestamp}} - {{alarm.message}}
</div>
</div>
🚨 Part 5: Alarm System Implementation
5.1 Alarm Logic Flow
text
[Temperature Sensor] → [Function: Check Limits] → [Alarm Trigger]
↓
[High Temp Alarm] → [Dashboard] → [Log File]
↓
[Email Alert] (optional)
5.2 Alarm Configuration Node
javascript
// Check temperature limits
let temp = msg.payload;
let alarm = null;
if (temp > 85) {
alarm = {
severity: "HIGH",
message: `CRITICAL: Temperature ${temp}°C exceeds limit`,
timestamp: new Date().toISOString(),
acknowledged: false
};
} else if (temp > 70) {
alarm = {
severity: "MEDIUM",
message: `Warning: Temperature ${temp}°C approaching limit`,
timestamp: new Date().toISOString(),
acknowledged: false
};
}
if (alarm) {
// Send to dashboard
node.send([{payload: alarm}, null]);
// Send to log file
let logMsg = {...msg};
logMsg.payload = JSON.stringify(alarm);
node.send([null, logMsg]);
}
🔄 Part 6: MQTT Integration for IIoT
6.1 Install Mosquitto MQTT Broker
bash
# Ubuntu/Debian sudo apt install mosquitto mosquitto-clients # Windows # Download from https://mosquitto.org/download/
6.2 MQTT Flow in Node-RED
text
[Modbus Data] → [MQTT Publish node] Topic: factory/line1/temperature QoS: 1 (at least once) Retain: true
6.3 Subscribe to Commands
text
[MQTT Subscribe node] → [Command Processor] Topic: factory/line1/commands/+
6.4 Test with MQTT Client
bash
# Subscribe to temperature mosquitto_sub -h localhost -t "factory/line1/temperature" # Send command mosquitto_pub -h localhost -t "factory/line1/commands/fan" -m "ON"
🧪 Part 7: Complete Lab Project
Temperature Control System with SCADA
7.1 System Architecture
text
[OpenPLC Simulator]
↓ (Modbus TCP)
[Node-RED Edge]
├── [Dashboard HMI]
├── [Alarm Manager]
├── [Data Logger]
└── [MQTT Bridge → Cloud]
7.2 Complete Flow JSON
Download from: [GitHub Gist Link – See Appendix]
7.3 Step-by-Step Implementation
- PLC Simulation Setup
- OpenPLC: Create temperature control program
- Set Modbus mapping:text40001: Temperature (0-100°C) 40002: Setpoint (70°C) 40003: Fan Status (0/1)
- Node-RED Main Flow
json
[{"id":"modbus-read","type":"modbus-read","z":"main","name":"Read Temperature","topic":"","showStatusActivities":true,"showErrors":true,"unitid":"1","dataType":"HoldingRegister","adr":"0","quantity":"1","rate":"2000","rateUnit":"ms","delayOnStart":false,"startDelayTime":"","server":"server1","useIOFile":false,"ioFile":"","useIOForPayload":false,"x":200,"y":100,"wires":[["alarm-check","temp-gauge"]]}]
- Dashboard Layout
- Tab 1: Process Overview
- Tab 2: Alarms & Events
- Tab 3: Historical Trends
- Data Persistence
javascript
// Add to file node for logging
const fs = require('fs');
const path = './logs/temperature.csv';
// Create CSV if doesn't exist
if (!fs.existsSync(path)) {
fs.writeFileSync(path, 'timestamp,temperature,setpoint,fan_status\n');
}
// Append data
const data = `${msg.timestamp},${msg.temp},${msg.setpoint},${msg.fan}\n`;
fs.appendFileSync(path, data, 'utf8');
⚙️ Part 8: Industrial Best Practices
8.1 Reliability Patterns
- Watchdog Timer: Implement heartbeat monitoring
javascript
// Watchdog function - reset every 30 seconds
let lastHeartbeat = Date.now();
setInterval(() => {
if (Date.now() - lastHeartbeat > 60000) {
// Restart flow or send alert
node.error("Watchdog timeout - system unresponsive");
}
}, 30000);
- Data Validation: Always validate industrial data
javascript
function validateIndustrialData(data) {
// Check range
if (data.temperature < -50 || data.temperature > 200) {
return {valid: false, reason: "Temperature out of physical range"};
}
// Check rate of change (prevent spikes)
if (Math.abs(data.temperature - previousTemp) > 10) {
return {valid: false, reason: "Rate of change too high"};
}
return {valid: true};
}
8.2 Basic Cybersecurity
- Change default passwords
- Use Node-RED projects for version control
- Enable HTTPS in settings.js:
javascript
module.exports = {
https: {
key: require("fs").readFileSync('privkey.pem'),
cert: require("fs").readFileSync('cert.pem')
}
}
8.3 Documentation Standards
- Use consistent tag naming:
PLANT.AREA.DEVICE.SENSOR - Add comments to complex function nodes
- Maintain flow documentation in README
📈 Real-World Applications
Application 1: Energy Monitoring
text
Flow: [Power Meter] → [Modbus] → [Energy Calculator] → [Dashboard]
→ [Peak Alert]
→ [CSV Export]
Application 2: OEE Tracking
javascript
// Overall Equipment Effectiveness
function calculateOEE(availableTime, runtime, goodParts, totalParts) {
const availability = runtime / availableTime;
const performance = (idealCycleTime * totalParts) / runtime;
const quality = goodParts / totalParts;
return {
oee: (availability * performance * quality) * 100,
availability: availability * 100,
performance: performance * 100,
quality: quality * 100
};
}
🚀 Next Steps & Advanced Topics
Level Up Your Skills:
- Containerization: Run Node-RED in DockerdockerfileFROM nodered/node-red:latest COPY flows.json /data/flows.json
- OPC UA Integration:
node-red-contrib-opcua - Time-Series Database: Connect to InfluxDBjavascript// Write to InfluxDB const point = new InfluxDB.Point(‘temperature’) .tag(‘machine’, ‘press-1’) .floatField(‘value’, msg.temp);
- Cloud Integration: AWS IoT / Azure IoT Hub
- Advanced Visualization: Grafana with Node-RED
⚠️ Safety & Limitations
Critical Notes:
- Node-RED is NOT a safety system
- Never use for safety-critical functions (E-stop, safety interlocks)
- Always use certified safety PLCs for personnel protection
- Performance limits
- Typical scan time: 100ms-1s
- Not suitable for high-speed control (<50ms)
- Best used for:
- Monitoring and visualization
- Data acquisition
- Non-critical control loops
- Protocol translation
- Alarm notification
📚 Learning Resources
Free Resources:
- Node-RED Official: nodered.org/docs
- OpenPLC Documentation: openplcproject.com/docs
- Industrial IoT GitHub: github.com/industrial-iot
Recommended Books:
- “Industrial Automation from Scratch” by P. Obakpolo
- “Node-RED Guide” by A. Sharpe
🎓 Final Project Challenge
Build a complete system that:
- Simulates 3 temperature sensors
- Controls 2 cooling fans based on average temperature
- Implements high/low alarms with acknowledgment
- Logs data to CSV daily
- Displays on a professional dashboard
- Sends MQTT data to a cloud service (optional)
Success criteria: System runs for 24 hours without crashes, maintains data integrity, and provides clear operator interface.
📝 Appendix: Quick Reference Commands
Node-RED Useful Commands
bash
# Start with settings file node-red -s settings.js # List installed nodes npm list --depth=0 # Backup flows cp ~/.node-red/flows.json ./backup/
Modbus Testing Tools
bash
# Install modbus-cli npm install -g modbus-cli # Read register modbus read -a 1 -t holding -c 1 localhost 40001
🆘 Troubleshooting Common Issues
| Problem | Solution |
|---|---|
| Modbus connection failed | Check firewall, verify PLC IP |
| Dashboard not loading | Clear browser cache, restart Node-RED |
| High CPU usage | Check for infinite loops, reduce polling rate |
| Memory leaks | Monitor with node-red-admin log |
📄 License & Attribution
This tutorial is open-source under MIT License. Always verify designs with certified engineers before industrial deployment.
Ready to automate? Deploy your first industrial flow today!
🔧 Ready-to-Use Resources:
- Complete flow JSON: Download from GitHub Gist
- Dashboard template: Node-RED Library
- PLC simulation program: OpenPLC Share
Note: Replace # with actual links in published version