Marcio Cunha

How to read industrial sensors with ESP32 via Modbus TCP

Learn to develop embedded firmware on ESP32 to read PLCs and industrial sensors via Modbus TCP, integrating data straight into SCADA systems.

Marcio Cunha•5 min
Also available in:PortuguêsEspañol
Summary
  • The Modbus TCP protocol encapsulates industrial commands inside standard Ethernet packets, allowing direct Wi-Fi queries without complex serial adapters.
  • The ESP32 acts as a Modbus client to request temperature, pressure, and machine status registers straight from industrial PLCs and meters.
  • Managing unstable Wi-Fi connections requires robust auto-reconnection routines and exception handling to prevent operational lockups in the field.
  • Correct byte-to-float conversion ensures raw network reads accurately reflect the physical reality of the industrial production process.
  • Supervisory systems natively ingest these telemetry streams when local sensor data is structured into lightweight JSON network payloads.

Why use the ESP32 in industrial automation over Wi-Fi

Traditional industrial automation has always relied on expensive shielded cables, heavy signal converters, and rigid physical infrastructures to interconnect machinery. In practice, this means that altering a sensor's position or adding a new data collection point historically demanded hours of cable pulling and costly production line shutdowns. Today, powerful and low-cost microcontrollers change this landscape radically. The ESP32, a compact chip with integrated Wi-Fi and Bluetooth, enables engineers to build reliable wireless bridges that collect data directly from PLCs, the robust computers controlling factories, and forward it to supervisory software managing production in real time.

When planning industrial networks, protocol selection is the single most critical factor for project success. Modbus TCP emerges as the ideal choice because it takes the legacy, battle-tested 1979 Modbus protocol and encapsulates it within standard IP networking packets. Instead of requiring dedicated serial lines with point-to-point connections, the ESP32 talks effortlessly to any PLC or smart meter sharing the factory's Wi-Fi network. Before diving into code, it is worth noting that building robust industrial wireless setups demands careful infrastructure planning, much like managing server bottlenecks as explored in our guide on how to configure QoS and fq_codel to prevent network bottlenecks under heavy electromagnetic interference.

Understanding Modbus TCP architecture in practice

Modbus operates under a strict request-response logic governed by a client-server relationship, where the client asks questions and the server stores information inside register tables. In our embedded firmware scenario, the ESP32 acts as the Modbus TCP client, opening network connections to query switch states, temperatures, and motor speeds directly from an industrial PLC or field instruments like those discussed in how to calibrate industrial sensors via Modbus in the field. Each useful data point sits inside specific numeric addresses, divided between digital inputs, outputs, and 16-bit holding registers.

To program the ESP32 for this task, we utilize the Arduino IDE environment alongside libraries dedicated to the Modbus TCP protocol. The main advantage of this approach is that developers do not need to reinvent the wheel by building a network stack from scratch; the library handles command encapsulation over standard TCP ports, typically port 502. In practice, the firmware sends a structured request detailing the target equipment's IP address, the function code, such as reading holding registers, and the exact count of memory positions we wish to poll within a single read cycle.

Developing the connection and reading firmware

Developing embedded code requires rigorous attention to wireless connection stability, given that industrial environments are filled with physical barriers and electrical noise sources. The first logical block of our firmware must connect the ESP32 to the local Wi-Fi network and enter a continuous monitoring loop. If the signal drops, the microcontroller must attempt reconnection in isolation without freezing the rest of the application or leaving network sockets in inconsistent states. For developers looking to expand automation by integrating remote monitoring with secure access, it is worth checking how to create a secure corporate tunnel using RustDesk to manage remote devices on the shop floor network.

Below is a functional C++ code example using the Arduino IDE to configure the ESP32 as a Modbus TCP client and execute periodic register polls from a PLC:

#include <WiFi.h>#include <ModbusIP_ESP8266.h>// Local Wi-Fi network credentialsconst char* ssid = "FactoryNetwork";const char* password = "SecurePassword123";// PLC IP address on the industrial networkIPAddress remotePLC(192, 168, 1, 50);ModbusIP mb;void setup() {  Serial.begin(115200);  WiFi.begin(ssid, password);  while (WiFi.status() != WL_CONNECTED) {    delay(500);    Serial.print(".");  }  Serial.println("\nConnected to Wi-Fi!");  // Initialize Modbus TCP client  mb.client();}// Main sensor polling loop every 2 secondsvoid setupLoop() {  // Keep Modbus connection alive  if (!mb.isConnected(remotePLC)) {    mb.connect(remotePLC);  } else {    // Read 2 holding registers starting from address 0 on the PLC    mb.readHreg(remotePLC, 0, [](Modbus::ResultCode event, uint16_t count, void* data) {      if (event == Modbus::EX_SUCCESS) {        uint16_t* regs = reinterpret_cast<uint16_t*>(data);        Serial.printf("Sensor Reading 1: %d\n", regs[0]);        Serial.printf("Sensor Reading 2: %d\n", regs[1]);      } else {        Serial.printf("Modbus read error: %d\n", event);      }      return true;    });  }  delay(2000);}void loop() {  mb.task();  setupLoop();}

Data handling, conversion, and SCADA integration

Reading raw registers from a PLC is only half the battle in an embedded firmware project. Industrial instruments typically return 16-bit integer numbers that must be translated into real physical quantities, such as degrees Celsius or kilopascals, by applying scale factors and mathematical conversions. Furthermore, many high-precision sensors split a single floating-point reading across two consecutive Modbus registers, requiring bit-manipulation operations to recombine the high and low halves correctly before displaying the final value on the serial monitor.

Once data is cleaned and converted, the ESP32 must deliver it to supervisory software or a cloud dashboard in real time. The most common strategy involves formatting these readings into lightweight JSON messages and publishing them via MQTT, a lightweight messaging protocol tailored for resource-constrained devices. This way, the factory control panel updates its charts instantly without clogging the Wi-Fi network with unnecessary traffic, ensuring a smooth, secure, and highly transparent industrial operation.

Final considerations on field robustness and maintenance

Implementing industrial sensor reading with ESP32 and Modbus TCP over Wi-Fi requires a delicate balance between affordable hardware and sound embedded software engineering practices. While wireless networks offer fantastic flexibility to avoid complex cable runs, designers must never ignore the volatility of the factory floor, where heavy motors generate electromagnetic surges and thick walls block signals. Ensuring robust error-handling routines for network drops, automatic reboots, and rigorous validation of incoming Modbus packets is what separates a bench prototype from a production-ready factory floor solution.

As industrial IoT adoption grows, accessible microcontroller-based solutions continue proving their worth by democratizing access to production data once locked inside expensive proprietary systems. With well-structured code, stable power supplies, and a clear SCADA integration strategy, the ESP32 solidifies its place as an essential tool for engineers and system integrators aiming to modernize manufacturing plants with agility, low cost, and superb operational reliability.