A SCADA system (Supervisory Control And Data Acquisition) is the brain of any industrial facility — monitoring sensors, controlling equipment, and providing operators with real-time dashboards. Commercial SCADA software costs lakhs, but you can build a fully functional mini SCADA system using a Raspberry Pi and Node-RED for a fraction of the price. This guide walks you through the architecture, setup, and practical implementation of a SCADA system suitable for small plants, educational labs, and home automation.
Table of Contents
- What Is SCADA and How Does It Work?
- SCADA Architecture: RTU, MTU, and HMI
- Setting Up Raspberry Pi as a SCADA Server
- Building an HMI Dashboard with Node-RED
- Connecting Field Devices via Modbus
- Alarm Management and Notifications
- Historical Data Logging and Trends
- Frequently Asked Questions
- Conclusion
What Is SCADA and How Does It Work?
SCADA stands for Supervisory Control And Data Acquisition. It is a software and hardware architecture that allows operators to monitor and control industrial processes from a central location. You will find SCADA systems in:
- Water treatment plants: Monitoring flow rates, chemical dosing, and pump status
- Power generation: Tracking turbine speed, voltage, frequency, and grid parameters
- Manufacturing: Overseeing production lines, temperature zones, and quality metrics
- Oil and gas: Remote monitoring of pipeline pressure, flow, and leak detection
- Building management: HVAC control, lighting, and energy monitoring
A SCADA system does four things: collects data from sensors and controllers, displays it in real-time on graphical screens, allows operators to control equipment, and logs everything for historical analysis.
SCADA Architecture: RTU, MTU, and HMI
A SCADA system has three main components:
RTU (Remote Terminal Unit) / PLC
These are the field devices that connect directly to sensors and actuators. They read sensor values, control outputs, and communicate with the central station. In our mini SCADA, Arduino boards with RS485 modules serve as RTUs.
MTU (Master Terminal Unit) / SCADA Server
The central computer that polls RTUs for data, processes alarms, logs data, and hosts the HMI application. Our Raspberry Pi running Node-RED serves this role.
HMI (Human Machine Interface)
The graphical screens that operators interact with. They show process diagrams, real-time values, alarms, and trend graphs. Node-RED Dashboard provides our HMI layer, accessible from any web browser on the network.
Mini SCADA Architecture:
[Sensors] --> [Arduino RTU 1] --RS485--> |
[Sensors] --> [Arduino RTU 2] --RS485--> |-- RS485 Bus
[Sensors] --> [Arduino RTU 3] --RS485--> |
|
[USB-RS485 Adapter]
|
[Raspberry Pi]
- Node-RED (logic)
- InfluxDB (data)
- Grafana (trends)
|
[Web Browser HMI]
(any device on LAN)
Setting Up Raspberry Pi as a SCADA Server
Install the required software stack on your Raspberry Pi (4 or 5 recommended):
Step 1: Install Node-RED
# Install Node-RED (includes Node.js)
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
# Enable auto-start on boot
sudo systemctl enable nodered.service
sudo systemctl start nodered.service
# Access Node-RED at http://raspberry-pi-ip:1880
Step 2: Install Node-RED Dashboard and Modbus Nodes
# Open Node-RED, go to Menu > Manage Palette > Install
# Search and install:
# - node-red-dashboard (HMI widgets)
# - node-red-contrib-modbus (Modbus RTU/TCP)
# - node-red-contrib-influxdb (data logging)
Step 3: Install InfluxDB for Data Logging
# Install InfluxDB 2.x
wget -q https://repos.influxdata.com/influxdata-archive_compat.key
sudo apt install influxdb2
sudo systemctl enable influxdb
sudo systemctl start influxdb
# Access InfluxDB setup at http://raspberry-pi-ip:8086
Step 4: Install Grafana for Historical Trends
# Install Grafana
sudo apt install grafana
sudo systemctl enable grafana-server
sudo systemctl start grafana-server
# Access Grafana at http://raspberry-pi-ip:3000
Building an HMI Dashboard with Node-RED
Node-RED Dashboard provides industrial-style widgets for building operator screens:
- Gauges: Circular and linear gauges for pressure, temperature, level
- Charts: Real-time line charts and bar graphs for trend monitoring
- Switches: Toggle switches and buttons for equipment control
- Text displays: Numerical readouts with units and colour coding
- Notification: Pop-up alerts and audio alarms
- Templates: Custom HTML/CSS for process diagrams (P&ID mimic screens)
A basic Node-RED flow for reading a Modbus sensor and displaying on the dashboard:
// Node-RED Flow (JSON - import via clipboard)
// This reads Modbus registers every 2 seconds and displays on dashboard
[Modbus Read Node]
Server: /dev/ttyUSB0 (USB-RS485 adapter)
Unit ID: 1
FC: Read Holding Registers (FC3)
Address: 0
Quantity: 4
Poll Rate: 2 seconds
--> [Function Node: Parse Data]
msg.payload = {
temperature: msg.payload[0] / 10,
humidity: msg.payload[1] / 10,
pressure: msg.payload[2] / 100,
level: msg.payload[3] / 10
};
return msg;
--> [Dashboard Gauge: Temperature]
Range: 0-100, Units: "°C"
Colours: Green < 60, Yellow = 80
--> [Dashboard Chart: Temperature Trend]
X-axis: Last 1 hour
Creating a Process Mimic Screen
For a professional-looking SCADA screen, use the Template node with custom HTML/SVG to create process diagrams. You can animate valves, change pipe colours based on flow status, and show pump states with CSS animations:
{{msg.payload.level | number:1}}%
Water Tank Level
Connecting Field Devices via Modbus
Configure Arduino boards as Modbus RTU slaves that your Raspberry Pi SCADA polls for data. Each Arduino reads local sensors and exposes values through Modbus registers:
// Arduino RTU - Modbus Slave (Station 1: Water Treatment)
#include
#define RS485_DE 2
ModbusRTUSlave modbus(Serial, RS485_DE);
uint16_t inputRegisters[8]; // Read by SCADA
uint16_t holdingRegisters[4]; // Written by SCADA
bool coils[4]; // Pump controls
void setup() {
modbus.configureInputRegisters(inputRegisters, 8);
modbus.configureHoldingRegisters(holdingRegisters, 4);
modbus.configureCoils(coils, 4);
modbus.begin(1, 9600); // Slave address 1
// Sensor pins
pinMode(A0, INPUT); // pH sensor
pinMode(A1, INPUT); // Turbidity
pinMode(A2, INPUT); // Flow rate (pulse)
pinMode(A3, INPUT); // Level (4-20mA)
// Pump outputs
for (int i = 4; i <= 7; i++) pinMode(i, OUTPUT);
}
void loop() {
// Update input registers with sensor values
inputRegisters[0] = analogRead(A0); // pH (raw)
inputRegisters[1] = analogRead(A1); // Turbidity (raw)
inputRegisters[2] = getFlowRate(); // Flow in L/min x10
inputRegisters[3] = readLevel(); // Level in % x10
inputRegisters[4] = millis() / 1000; // Uptime
// Control pumps based on SCADA coil writes
for (int i = 0; i < 4; i++) {
digitalWrite(i + 4, coils[i] ? HIGH : LOW);
}
modbus.poll();
}
On the Node-RED side, add multiple Modbus Read nodes for each RTU station, each polling at appropriate intervals (critical values every 1-2 seconds, non-critical every 10-30 seconds).
Alarm Management and Notifications
Alarm management is critical in SCADA. Implement a proper alarm system in Node-RED:
// Node-RED Function: Alarm Processing
var alarms = flow.get('activeAlarms') || {};
var data = msg.payload;
// Define alarm conditions
var checks = [
{tag: 'TEMP_HIGH', value: data.temperature, limit: 80,
type: 'HIGH', message: 'Temperature exceeds 80°C'},
{tag: 'TEMP_CRIT', value: data.temperature, limit: 95,
type: 'CRITICAL', message: 'CRITICAL: Temperature above 95°C'},
{tag: 'LEVEL_LOW', value: data.level, limit: 10,
type: 'LOW', message: 'Tank level below 10%'},
{tag: 'PRESSURE_HIGH', value: data.pressure, limit: 8.5,
type: 'HIGH', message: 'Pressure exceeds 8.5 bar'}
];
var newAlarms = [];
checks.forEach(function(check) {
var active = (check.type === 'LOW')
? check.value check.limit;
if (active && !alarms[check.tag]) {
alarms[check.tag] = {
time: new Date().toISOString(),
message: check.message,
value: check.value
};
newAlarms.push(alarms[check.tag]);
} else if (!active && alarms[check.tag]) {
delete alarms[check.tag];
}
});
flow.set('activeAlarms', alarms);
if (newAlarms.length > 0) {
msg.payload = newAlarms;
return msg; // Send to notification nodes
}
return null;
Connect the alarm output to email nodes (node-red-node-email), Telegram bot nodes, or SMS gateway APIs for remote notifications.
Historical Data Logging and Trends
Log all process data to InfluxDB for historical analysis. In Node-RED, the InfluxDB output node writes timestamped data points:
// Node-RED Function: Prepare data for InfluxDB
msg.payload = [
{
measurement: "water_treatment",
tags: {station: "RTU1", location: "inlet"},
fields: {
temperature: msg.payload.temperature,
ph: msg.payload.ph,
turbidity: msg.payload.turbidity,
flow_rate: msg.payload.flowRate,
level: msg.payload.level
}
}
];
return msg;
In Grafana, create dashboards with:
- Time series panels: Show temperature, pressure, and level trends over hours/days/weeks
- Stat panels: Current values with colour-coded thresholds
- Alert rules: Grafana can also generate alerts based on data patterns
- Table panels: Alarm history log with timestamps and acknowledgements
Frequently Asked Questions
Is a Raspberry Pi SCADA suitable for real industrial use?
For small-scale applications like building management, agricultural monitoring, or educational labs — yes, with proper engineering. For safety-critical industrial processes like chemical plants or power generation, use certified SCADA software (Ignition, WinCC, FactoryTalk) on industrial-grade hardware.
How many RTU stations can a Raspberry Pi SCADA handle?
With RS485 Modbus RTU, up to 247 stations theoretically. Practically, polling 10-20 stations every 2 seconds is comfortable for a Raspberry Pi 4. For more stations or faster polling, use Modbus TCP over Ethernet.
Can Node-RED handle complex control logic?
Node-RED is excellent for supervisory logic (start/stop sequences, alarm processing, data routing) but should not be used for safety-critical real-time control. Keep critical control logic in the PLC/Arduino RTU and use Node-RED for monitoring and supervisory functions only.
What is the cost of this mini SCADA system?
A basic setup costs approximately: Raspberry Pi 4 (₹4,000-6,000) + 3 Arduino RTU stations with RS485 (₹3,000) + USB-RS485 adapter (₹300-500) + sensors and wiring (₹2,000-5,000). Total: ₹10,000-15,000 for a functional 3-station SCADA system. Compare this with commercial SCADA software licences starting at ₹2-5 lakhs.
Can I access the SCADA remotely?
Yes. Node-RED Dashboard and Grafana are web-based. Set up a VPN (WireGuard is recommended) to access your SCADA from anywhere. Never expose SCADA systems directly to the internet without proper cybersecurity measures.
Conclusion
Building a mini SCADA system with Raspberry Pi and Node-RED is an excellent way to learn industrial automation concepts without the cost of commercial software. The combination of Node-RED for logic and HMI, InfluxDB for data storage, and Grafana for historical trends creates a surprisingly capable monitoring platform.
Start with a single Arduino RTU station, build the Node-RED dashboard, and gradually expand with more stations and features. The skills you develop — Modbus communication, alarm management, data logging, and HMI design — are directly transferable to commercial SCADA platforms.
Get all the components you need at Zbotic’s online store and start building your industrial monitoring system today.
Add comment