Back to Embedded Systems Hardware Engineering Series

Capstone 5: Industrial Monitoring System

April 17, 2026 Wasil Zafar 42 min read

Design a ruggedized industrial sensor platform with 4–20mA analog inputs, Modbus RTU/TCP communication, and safety certifications for hazardous environments.

Table of Contents

  1. System Requirements
  2. Hardware Architecture
  3. Analog Input Design
  4. Modbus Implementation
  5. Channel Planner
  6. Conclusion

System Requirements

ParameterSpecificationStandard
Analog Inputs8× 4-20mA / 0-10V (selectable)IEC 60381
ADC Resolution24-bit sigma-deltaADS1248
CommunicationModbus RTU (RS-485) + Modbus TCPIEC 61158
HART Support4 channels, HART modem per pairIEC 62591
Isolation2.5 kV channel-to-channelIEC 61010
Operating Temp-40°C to +85°CIndustrial grade
ProtectionIP67 enclosure, ATEX Zone 2IEC 60079
Power24VDC ±20% (DIN rail)IEC 61131-2

Hardware Architecture

Industrial Monitoring System Block Diagram
flowchart TD
    A["24VDC
DIN Rail Power"] --> B["DC-DC Isolated
5V + 3.3V"] B --> C["STM32F4
Main Controller"] C -->|SPI| D["ADS1248
24-bit ADC × 2"] D --> E["Analog Front-End
8× 4-20mA / 0-10V"] C -->|UART| F["RS-485
Modbus RTU"] C -->|SPI| G["W5500
Modbus TCP"] C -->|SPI| H["HART Modem
AD5700"] C --> I["EEPROM
Calibration Data"] C --> J["Watchdog
+ Reset IC"] style C fill:#3B9797,color:#fff style D fill:#16476A,color:#fff

Analog Input Design

# 4-20mA analog input front-end design calculator
# Converts loop current to ADC input voltage

import numpy as np

# Design parameters
i_min_ma = 4.0       # mA (live zero)
i_max_ma = 20.0      # mA (full scale)
r_sense = 249.0      # Ohm precision sense resistor (0.1%)
v_ref = 2.5          # ADC reference voltage
adc_bits = 24        # ADS1248 resolution

# Voltage across sense resistor
v_min = i_min_ma * 1e-3 * r_sense
v_max = i_max_ma * 1e-3 * r_sense

# ADC codes
lsb = v_ref / (2**adc_bits)
code_min = int(v_min / lsb)
code_max = int(v_max / lsb)

print("4-20mA Analog Input Design")
print("=" * 50)
print(f"Sense resistor:     {r_sense} Ω (0.1%)")
print(f"Voltage at  4mA:    {v_min:.3f} V")
print(f"Voltage at 20mA:    {v_max:.3f} V")
print(f"ADC reference:      {v_ref} V")
print(f"ADC resolution:     {adc_bits} bits ({2**adc_bits:,} codes)")
print(f"LSB size:           {lsb*1e6:.3f} µV")
print(f"Code at  4mA:       {code_min:,}")
print(f"Code at 20mA:       {code_max:,}")
print(f"Usable dynamic range: {code_max - code_min:,} codes")
print(f"Resolution per µA:  {(code_max-code_min)/16000:.1f} codes/µA")

# Wire break detection: current < 3.5mA
wire_break_v = 3.5e-3 * r_sense
print(f"\nWire break threshold: {wire_break_v:.4f} V ({3.5} mA)")
print(f"Over-range detect:   {22e-3 * r_sense:.4f} V ({22.0} mA)")
Galvanic Isolation: Each analog channel pair uses an ISO7741 digital isolator (2.5 kV) between the ADC and the MCU SPI bus. Isolated DC-DC converters (SN6501 + transformer) provide separate power domains per channel group, preventing ground loops in multi-sensor installations.

Modbus RTU Implementation

/* Modbus RTU slave — register map for 8-channel monitor
   STM32F4 UART + RS-485 transceiver (MAX3485) */

#include <stdint.h>

/* Modbus holding registers (40001-40032) */
typedef struct {
    uint16_t channel_raw[8];     /* 40001-40008: Raw ADC counts */
    uint16_t channel_scaled[8];  /* 40009-40016: Scaled value × 100 */
    uint16_t channel_status[8];  /* 40017-40024: Status flags */
    uint16_t alarm_flags;        /* 40025: Alarm bitmap */
    uint16_t device_status;      /* 40026: Device health */
    uint16_t sample_rate;        /* 40027: Samples/sec */
    uint16_t uptime_hours;       /* 40028: Hours since boot */
    uint16_t fw_version;         /* 40029: Firmware version */
    uint16_t serial_hi;          /* 40030: Serial number (high) */
    uint16_t serial_lo;          /* 40031: Serial number (low) */
    uint16_t modbus_addr;        /* 40032: Modbus slave address */
} modbus_regs_t;

/* Channel status bits */
#define CH_STATUS_OK          0x0000
#define CH_STATUS_WIRE_BREAK  0x0001  /* Current < 3.5 mA */
#define CH_STATUS_OVER_RANGE  0x0002  /* Current > 22 mA */
#define CH_STATUS_UNDER_RANGE 0x0004  /* Current < 3.8 mA (warning) */
#define CH_STATUS_CAL_ERROR   0x0008  /* Calibration invalid */
#define CH_STATUS_DISABLED    0x8000  /* Channel disabled */

/* Scale raw ADC to engineering units:
 * val = (raw - zero_offset) * span / (full_scale - zero_offset) + eng_min
 * Stored as integer × 100 (e.g., 25.50°C = 2550)
 */

Channel Configuration Planner

Industrial Channel Planner

Plan your monitoring channels and signal types. Download as Word, Excel, or PDF.

Draft auto-saved

Conclusion

Industrial monitoring requires precision analog design (24-bit ADC with galvanic isolation), robust communication protocols (Modbus RTU/TCP, HART), and compliance with safety standards (ATEX, IEC 61010). This capstone bridges consumer embedded systems knowledge with professional process control engineering.

Next Capstone

In Capstone 6: AI-Assisted Debugging Tool, we’ll build an intelligent hardware debug probe that uses ML to classify signal anomalies and suggest root causes.