Retrofitting legacy machines for IoT is usually the fastest way to get real production data, because the machines that make most of your parts are often decades old and will not be replaced any time soon. In this guide you will learn which non-invasive signals to tap, how to pick between sensors and controller interfaces, and how to build a working current-clamp monitor that publishes machine state over MQTT without changing any PLC logic.
Why Retrofit Instead of Replace
A twenty-year-old lathe, press or injection moulding machine can still hold tolerance perfectly well. What it lacks is a network port, or it has one that speaks a protocol nobody on the IT side recognises. Replacing it to get data is rarely justified. Retrofitting it costs a fraction and can be done in a maintenance window.
The guiding principle of a good retrofit is non-invasive first. Every change to PLC logic needs validation, a backup plan and often the original integrator, who may no longer exist. Every sensor you clamp on from the outside needs none of that. Start with signals you can read without touching the control system, and only move to controller integration when the value is proven.
What to Measure on a Legacy Machine
Most of the value in a first retrofit comes from a handful of signals that answer the question "is the machine making parts, and if not, why not?"
| Signal | How to capture it | What it tells you | Invasiveness |
|---|---|---|---|
| Spindle or motor current | Split-core current transformer (current clamp) on one phase | Off, idle, running, overload | None, clamps around an existing cable |
| Stack light status | Light sensors or dry contacts on the tower light | Running, waiting, alarm as the operator sees it | Very low |
| Part count | Proximity sensor on an ejector or a contact on the cycle-complete signal | Throughput and cycle time | Low |
| Vibration | Magnetic-mount accelerometer, wired or wireless | Bearing wear, imbalance, tool condition | None |
| Temperature | Clamp-on or adhesive probe | Overheating motors, hydraulic oil, coolant | None |
| Controller data | Modbus, Ethernet/IP, S7 or serial read through a gateway | Program, alarms, setpoints, counters | Medium, read-only access to the PLC |
The current clamp deserves special attention. With one sensor per machine you can derive state, utilisation and even rough energy consumption. It does not need a PLC, a network port on the machine, or the machine builder's cooperation.
Choosing Between Sensors and Controller Interfaces
There are two broad retrofit paths, and they combine well.
Add-on sensors are independent of the machine's controller. They work on machines with relay logic, obsolete PLCs or locked-down controllers. They give you physical truth, such as whether the spindle actually turned, but no context such as the program number or alarm text.
Controller interfaces read data the machine already has. Many older PLCs expose Modbus RTU over a serial port, and many from the last two decades support Modbus TCP, Ethernet/IP or S7 communication. A gateway reads registers or tags in read-only mode and publishes them. Our guides on Modbus TCP to MQTT and PLC to cloud connectivity walk through that path.
A practical sequence is to clamp first, prove the value with utilisation data, and then add controller reads on the machines where alarm codes and counters justify the extra effort.
The Retrofit Architecture
Whatever you measure, the architecture stays the same:
- Sensors on the machine produce analog, digital or fieldbus signals.
- An edge device reads them. This can be a microcontroller such as an ESP32 for a single machine, or an IIoT edge gateway for a whole line.
- The edge device publishes MQTT to a broker, using a topic hierarchy such as
site/area/line/machine/measurement. - Consumers subscribe: dashboards, OEE calculations, historians, maintenance systems.
The broker is what keeps this scalable. Adding the fiftieth machine is the same as adding the first, and a new consumer never needs to know how the data was collected. If MQTT itself is new, start with what an MQTT broker is.
Hands-On: A Current-Clamp Machine Monitor with ESP32
This example uses an ESP32 and a voltage-output split-core current transformer such as the SCT-013-030, which outputs 1 V RMS at 30 A. The clamp is wired to GPIO34 through a mid-point bias circuit (two equal resistors from 3.3 V to GND with a capacitor to ground, the clamp between the mid-point and the ADC pin), so the AC signal swings around roughly 1.65 V.
Safety first: the clamp goes around a single insulated conductor inside the machine's cabinet. That work must be done by a qualified electrician with the machine isolated. Never clamp around a multi-core cable carrying all phases, since the fields cancel and you will read close to zero.
#include <WiFi.h>
#include <PubSubClient.h>
const char* WIFI_SSID = "plant-iot";
const char* WIFI_PASS = "your-wifi-password";
const char* MQTT_HOST = "broker.connectmq.com";
const int MQTT_PORT = 1883;
// Use a unique prefix on the public broker; it is readable by everyone
const char* BASE = "connectmq/demo/k7q2x9/factory1/turning/lathe07";
const int CT_PIN = 34;
const float AMPS_PER_VOLT = 30.0; // SCT-013-030: 1 V RMS = 30 A
const float IDLE_AMPS = 1.0; // below this the machine is off
const float RUN_AMPS = 4.0; // above this the spindle is cutting
WiFiClient net;
PubSubClient mqtt(net);
String lastState = "";
unsigned long lastReport = 0;
float readAmpsRms() {
const int N = 2000;
static float samples[N];
float sum = 0;
for (int i = 0; i < N; i++) {
samples[i] = analogReadMilliVolts(CT_PIN) / 1000.0;
sum += samples[i];
delayMicroseconds(100); // ~200 ms window, 10 mains cycles at 50 Hz
}
float mean = sum / N;
float sq = 0;
for (int i = 0; i < N; i++) {
float v = samples[i] - mean;
sq += v * v;
}
return sqrt(sq / N) * AMPS_PER_VOLT;
}
void connectMqtt() {
String clientId = "lathe07-" + String((uint32_t)ESP.getEfuseMac(), HEX);
String stateTopic = String(BASE) + "/state";
while (!mqtt.connected()) {
// Last will marks the monitor offline if power or Wi-Fi is lost
if (mqtt.connect(clientId.c_str(), stateTopic.c_str(), 1, true, "UNKNOWN")) {
lastState = "";
} else {
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
analogSetPinAttenuation(CT_PIN, ADC_11db);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
mqtt.setServer(MQTT_HOST, MQTT_PORT);
connectMqtt();
}
void loop() {
if (!mqtt.connected()) connectMqtt();
mqtt.loop();
float amps = readAmpsRms();
String state = amps < IDLE_AMPS ? "OFF" : (amps < RUN_AMPS ? "IDLE" : "RUNNING");
// Publish state on change, retained so dashboards see it immediately
if (state != lastState) {
mqtt.publish((String(BASE) + "/state").c_str(), state.c_str(), true);
lastState = state;
}
// Publish current every 10 seconds for trending
if (millis() - lastReport > 10000) {
char buf[64];
snprintf(buf, sizeof(buf), "{\"amps\":%.2f}", amps);
mqtt.publish((String(BASE) + "/current").c_str(), buf);
lastReport = millis();
}
}
Change k7q2x9 to your own random string, flash the board, and subscribe from a laptop:
mosquitto_sub -h broker.connectmq.com -p 1883 -i lathe-watch-$RANDOM \
-t 'connectmq/demo/k7q2x9/#' -v
Calibrate the thresholds by watching the current while the machine is switched off, idling with the spindle stopped, and cutting. Every machine has its own idle draw from pumps, fans and hydraulics, so IDLE_AMPS and RUN_AMPS must be set per machine. For production, switch to WiFiClientSecure on port 8883 and use the username, password and client ID from your ConnectMQ portal.
Common Retrofit Pitfalls
- Wrong thresholds. A machine whose hydraulic pump runs continuously will look "running" all shift if the run threshold is too low. Calibrate against observed behaviour.
- Electrical noise. VFDs and contactors inject noise. Keep sensor wiring short, use shielded cable, and average readings over several mains cycles as the example does.
- Wi-Fi in steel cabinets. A board inside a closed cabinet may lose its connection. Use an external antenna or mount the electronics outside the cabinet.
- No offline state. Without a last will, a monitor that loses power shows the last state forever. The example publishes
UNKNOWNas a retained will message to avoid that. - Unstructured topics. Pick the hierarchy before the second machine. Renaming fifty devices later is painful.
Scaling from One Machine to the Whole Shop Floor
Once a few machines are reporting, the questions shift from wiring to operations: how many connections, who can read which data, how to alert on stoppages. A managed MQTT broker removes the server work so you can focus on sensors. With ConnectMQ you can watch every retrofitted machine in the live topic explorer, group them by ISA-95 level in the devices view, and set threshold alert rules, for example when spindle current exceeds an overload limit. The free Serverless plan handles up to 25 connections, enough for a pilot cell. For the full journey from retrofit to plant-wide data, read our Industrial IoT with MQTT guide and the IIoT proof of concept plan.
Get Started with ConnectMQ
Create a free Serverless broker at app.connectmq.com, no credit card required. Swap the public broker for your own ConnectMQ endpoint with TLS, and your retrofitted machines become live, structured data that any dashboard or analytics tool can subscribe to.
Frequently Asked Questions
Can I retrofit legacy machines for IoT without modifying the PLC?
Yes. Current clamps, stack light sensors, vibration sensors and part-count sensors are all installed outside the control logic. They give you machine state and utilisation without any PLC changes.
What is the cheapest way to monitor machine state?
A single split-core current clamp on the main motor or spindle feed, read by a small microcontroller, is usually the lowest-cost option. The current level distinguishes off, idle and running.
Is it safe to install a current clamp on a running machine?
Clamp installation inside an electrical cabinet must be done by a qualified electrician following lockout procedures. The clamp itself does not break the circuit, but the cabinet contains live parts.
When should I read data directly from the PLC instead?
When you need context such as alarm codes, program numbers or exact part counters. Use a gateway with read-only access, and start after add-on sensors have proven the value of the data.



