---
title: "ESP32-MQTT-Weight-Modul"
url: "https://maker.wiznet.io/Grace_Koo/projects/esp32-mqtt-weight-modul/"
markdown_url: "https://maker.wiznet.io/Grace_Koo/projects/esp32-mqtt-weight-modul/md"
type: "UCC: User Created Content"
author: "MojitoShader"
author_url: "https://github.com/MojitoShader/ESP32-MQTT-Weight-Modul"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "MojitoShader"
original_url: "https://github.com/MojitoShader/ESP32-MQTT-Weight-Modul"
published: "2026-03-06"
language: "en"
likes: 0
views: 541
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# ESP32-MQTT-Weight-Modul

> https://github.com/MojitoShader/ESP32-MQTT-Weight-Modul

Original author: MojitoShader (source: https://github.com/MojitoShader/ESP32-MQTT-Weight-Modul)

## Article

## Wired Ethernet-Based Industrial Weight Measurement Module with W5500 — A Cocktail Bar Automation Case Study

### Introduction: Why Weight Measurement Is Challenging in Automation Systems

In precision-critical environments like automated beverage dispensing systems, wireless communication turns out to be a less reliable choice than it might seem. Wi-Fi carries inherent weaknesses for real-time measurement loops — 2.4 GHz band congestion, intermittent packet loss, and reconnection delays can all disrupt closed-loop control. This project addresses that problem directly. Designed as a **distributed weight measurement node** for a cocktail bar automation robot, it leverages the WIZnet W5500 Ethernet controller to achieve reliable, real-time data communication over wired LAN.

---

### The Role of the WIZnet W5500: Why Wired, and Why W5500?

In this project, the W5500 connects to the ESP32-S3 via SPI (MOSI/MISO/SCK/CS) and handles the Ethernet MAC/PHY layer. In the ESP32 Arduino environment, TCP/IP processing is handled by the lwIP stack running on the ESP32 itself, while the W5500 is dedicated to the wired physical layer (MAC + PHY) beneath it — a clean separation of responsibilities. The key advantage over Wi-Fi is that using a wired physical layer with lower software driver dependency significantly improves connection stability and latency predictability.

**Key reasons W5500 was chosen:**

- **Deterministic Latency:** The dispensing control loop requires 100 ms precision. Wired Ethernet produces far lower jitter than a software Wi-Fi stack.

- **Multi-Node Scaling with Static IP:** Each module is assigned a fixed IP (e.g., `10.0.0.20` for module 1, `10.0.0.21` for module 2), making multiple weight sensor nodes predictable and easy to manage.

- **MAC Address Generation from ESP32 eFuse:** A unique hardware identifier is automatically generated per module, allowing multiple nodes to coexist on the same network without MAC conflicts.

- **Link Status Monitoring:** Cable connect/disconnect events are detected via `Ethernet.linkStatus()` polling, with automatic MQTT session recovery on reconnection.

The initialization sequence proceeds as follows: W5500 hardware reset via GPIO 9 RST pin → SPI initialization (~1 MHz) → Ethernet configuration → MQTT broker connection. If a link is not detected within 30 seconds, the system continues to the next step and attempts self-recovery.

---

### How It Works: Sensor → Filtering → MQTT Publish

The core of the system is a **10 Hz internal sensor loop** combined with an **adaptive MQTT publish strategy**.

#### Sensor Layer

- **HX711 Load Cell Amplifier** (GPIO 35/36): Reads weight at 10 Hz with approximately 1 g resolution. Calibration offset and scale factor are stored in the ESP32's NVS (Non-Volatile Storage) and persist across power cycles.

- **HC-SR04 Ultrasonic Sensor** (GPIO 37/38): Measures distance in millimeters to detect the presence of a cup or glass. A stability filter requires **3 consecutive consistent readings** before the `glass_present` state is toggled — preventing false transitions from a single noisy reading.

#### Adaptive Publish Strategy

The system minimizes network load while delivering high-frequency data precisely when needed.

- **No glass (idle):** Publish at 1 Hz — suppresses unnecessary traffic during standby

- **Glass detected (dispensing):** Publish at 10 Hz — precise weight tracking at 100 ms intervals

In maintenance mode (`sys/mode = MAINTENANCE`), the rate is capped at 1 Hz regardless of glass state. When an emergency stop is received (`sys/estop = ASSERTED`), telemetry publishing halts immediately.

#### MQTT Communication Structure

Structured messages flow between the main controller and each weight module through an MQTT broker (default `10.0.0.10:1883`).

```plaintext
[Main Controller]
    │
    ├── PUBLISH → cell/bar1/mod/scale_1/cmd
    │      { "req_id": "...", "cmd": "TARE", "timeout_ms": 5000 }
    │
    └── SUBSCRIBE ← cell/bar1/mod/scale_1/status   (retained, QoS 1)
                  ← cell/bar1/mod/scale_1/telemetry (10 Hz, QoS 0)
```

Every command carries a unique `req_id` (UUID). The module immediately acknowledges with `state=BUSY`, then publishes `state=IDLE` upon completion. If execution fails or a timeout occurs, `state=ERROR` is published along with an error message. If the MQTT connection drops, the LWT (Last Will Testament) mechanism automatically propagates `state=OFFLINE` through the broker.

Reconnection is handled with exponential backoff (1s → 2s → 4s → 8s → max 30s). On reconnection, up to 100 buffered telemetry samples are flushed in order, each with accurate timestamps.

#### Serial Interface (Secondary)

Commands such as `SET_HX711_OFFSET`, `TARE`, `CALIBRATE_REFERENCE`, and `SAVE_CONFIG` can be entered directly via USB/UART (115200 baud). The serial interface operates independently of MQTT, making it useful for field diagnostics and initial calibration.

#### Development Environment

The project is built on PlatformIO + Arduino Framework, with dependencies on `PubSubClient 2.8.0`, `ArduinoJson 6.21.3`, and a custom Ethernet driver (`ETH-ESP3-W5500`) forked by the author to support the ESP32-S3 + W5500 combination. The build target is `esp32-s3-devkitc-1` (240 MHz, 8 MB Flash).

---

### Scalability: Why This Architecture Generalizes

This project was designed for a cocktail dispensing robot, but the underlying system architecture is not tied to that specific application.

**Scenarios where the same architecture applies:**

- **Food & Beverage Manufacturing Lines:** Weight measurement nodes connected to a main PLC/controller via MQTT for precision filling processes

- **Logistics & Warehouse Automation:** Multiple weight sensor nodes deployed on the same LAN, with a controller aggregating all data using MQTT wildcards (`cell/+/mod/+/telemetry`)

- **Chemical & Pharmaceutical Dispensing:** High-frequency weight tracking for sub-dispensing processes where wired Ethernet stability is especially critical

- **Smart Factory MES Integration:** The node slots directly into an MQTT → middleware → ERP/MES pipeline as an edge data source

Adding a new node requires nothing more than assigning a different IP address and `role_id` string. The component set — W5500 module, HX711, HC-SR04 — is simple and cost-transparent, keeping the barrier low for scaling from prototype to repeated production deployments, including ODM/OEM contexts.

---

### Tech Stack Summary

| Item | Details |
| --- | --- |
| **MCU** | ESP32-S3 (Espressif, 240 MHz, dual-core) |
| **Ethernet Controller** | WIZnet W5500 (MAC/PHY via SPI) |
| **Weight Sensor Interface** | HX711 Load Cell Amplifier (24-bit ADC, ~1 g resolution) |
| **Distance Sensor** | HC-SR04 Ultrasonic Sensor (mm resolution, cup detection) |
| **Communication Protocol** | MQTT (PubSubClient 2.8.0), QoS 0/1, LWT support |
| **Payload Format** | JSON (ArduinoJson 6.21.3) |
| **Publish Rate** | Adaptive: 1 Hz (idle) / 10 Hz (dispensing) |
| **Configuration Storage** | ESP32 NVS (persists across power cycles) |
| **Secondary Interface** | USB/UART Serial (115200 baud, calibration & diagnostics) |
| **Development Environment** | PlatformIO + Arduino Framework (ESP32-S3 DevKitC-1) |
| **Network Configuration** | Static IP, 10/100 Mbps wired Ethernet (RJ45) |

---

> **Project Repository:** [github.com/MojitoShader/ESP32-MQTT-Weight-Modul](https://github.com/MojitoShader/ESP32-MQTT-Weight-Modul)

---

Source: https://maker.wiznet.io/Grace_Koo/projects/esp32-mqtt-weight-modul/
