WiFi Water Flow Meter Design
6:35
Thought for 9 sec
Thought for 8 sec
Thought for 6 sec
Thought for 15 sec
Thought for 9 sec
Thought for 5 sec
Thought for 2 sec
Read schematic.
Thought for 5 sec
Thought for 5 sec
Thought for 8 sec
6/7 Create firmware starter project file with real ESP32 RS485/Modbus code
Thought for 55 sec
Thought for 7 sec
7/7 Run review, fix violations, and document remaining assumptions
Thought for 5 sec
Completed design checks — found 108 issues.
Read schematic.
Thought for 20 sec
Thought for 8 sec
7/7 tasks completed.
Thought for a moment
0:25
Thought for 20 sec
Thought for a moment
7:48
Thought for 2 sec
1/4 Inspect current PCB layout state and dimensions
Thought for 3 sec
Completed 3 design checks — found 108 issues.
Read schematic.
Read layout.
Thought for 5 sec
2/4 Set board size and stackup before placement
Thought for 5 sec
Editing board size.
Thought for 8 sec
3/4 Place components with ESP32 antenna and connector constraints
Thought for 10 sec
Thought for 1 sec
Thought for 7 sec
Thought for 3 sec
Thought for 4 sec
Thought for a moment
Thought for 8 sec
Thought for 9 sec
Thought for 3 sec
Thought for 16 sec
Thought for 34 sec
Thought for 21 sec
Thought for a moment
Thought for 13 sec
Thought for a moment
Thought for 1 min 7 sec
Thought for 11 sec
Thought for 28 sec
Thought for 8 sec
Thought for a moment
Thought for 24 sec
Thought for 11 sec
Thought for 8 sec
Thought for a moment
Thought for 7 sec
Thought for a moment
Thought for 5 sec
Thought for a moment
Thought for 4 sec
Thought for 8 sec
Thought for 4 sec
4/4 Run post-placement DRC and fix placement issues
Thought for 6 sec
Completed design checks — found 95 issues.
Read layout.
Thought for 5 sec
4/4 tasks completed.
Thought for a moment
Waiting for input
Pin Mapping
| Function | GPIO | Schematic Net | Direction | Notes |
|---|---|---|---|---|
| RS485 TX | 17 | RS485_TXD | Output | ESP32 to MAX3485 DI |
| RS485 RX | 18 | RS485_RXD | Input | MAX3485 RO to ESP32 |
| RS485 direction | 16 | RS485_DE_RE | Output | HIGH transmit, LOW receive |
| 12 V sensor enable | 15 | BOOST_EN | Output | Drives LM27313 SHDN net; external pull-up also enables by default |
| WiFi LED | 4 | LED_WIFI_GPIO | Output | HIGH turns LED on |
| Flow LED | 5 | LED_FLOW_GPIO | Output | HIGH turns LED on |
| BOOT button | 0 | ESP_BOOT | Input | Pull low during reset for bootloader |
| Reset | EN | ESP_EN | Input | Reset button pulls EN low |
| UART0 TX header | TXD0 | UART0_TXD | Output | Debug/programming header |
| UART0 RX header | RXD0 | UART0_RXD | Input | Debug/programming header |
platformio.iniIni
[env:esp32-s3-devkitc-1] platform = espressif32 board = esp32-s3-devkitc-1 framework = arduino monitor_speed = 115200 upload_speed = 921600 lib_deps = 4-20ma/ModbusMaster@^2.0.1
Cpp
#include <Arduino.h> #include <WiFi.h> #include <HTTPClient.h> #include <ModbusMaster.h> #include <string.h> // Pin definitions from schematic #define RS485_TX_PIN 17 #define RS485_RX_PIN 18 #define RS485_DE_RE_PIN 16 #define SENSOR_12V_EN_PIN 15 #define LED_WIFI_PIN 4 #define LED_FLOW_PIN 5 // Configuration placeholders static const char* WIFI_SSID = "YOUR_SSID"; static const char* WIFI_PASSWORD = "YOUR_PASSWORD"; static const char* POST_URL = "http://192.168.1.100:8080/flow"; #define MODBUS_BAUD 9600 #define MODBUS_SLAVE_ADDR 1 #define SENSOR_READ_INTERVAL_MS 1000 // Example Modbus register assumptions. Update these to the actual sensor manual. #define REG_FLOW_RATE_START 0x0000 // assumed float32, L/min, 2 holding registers #define REG_TOTAL_VOLUME_START 0x0002 // assumed float32, L, 2 holding registers ModbusMaster modbus; unsigned long lastSensorReadMs = 0; void rs485PreTransmission() { digitalWrite(RS485_DE_RE_PIN, HIGH); delayMicroseconds(50); } void rs485PostTransmission() { delayMicroseconds(50); digitalWrite(RS485_DE_RE_PIN, LOW); } float registersToFloat(uint16_t hi, uint16_t lo) { uint32_t raw = ((uint32_t)hi << 16) | lo; float value; memcpy(&value, &raw, sizeof(value)); return value; } bool readFloat32Holding(uint16_t startReg, float& value) { uint8_t result = modbus.readHoldingRegisters(startReg, 2); if (result != modbus.ku8MBSuccess) { Serial.printf("Modbus read failed at 0x%04X: 0x%02X\n", startReg, result); return false; } value = registersToFloat(modbus.getResponseBuffer(0), modbus.getResponseBuffer(1)); return true; } void initWiFi() { WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.print("Connecting to WiFi"); for (int i = 0; i < 30 && WiFi.status() != WL_CONNECTED; ++i) { digitalWrite(LED_WIFI_PIN, !digitalRead(LED_WIFI_PIN)); delay(500); Serial.print('.'); } if (WiFi.status() == WL_CONNECTED) { digitalWrite(LED_WIFI_PIN, HIGH); Serial.printf("\nWiFi connected, IP: %s\n", WiFi.localIP().toString().c_str()); } else { digitalWrite(LED_WIFI_PIN, LOW); Serial.println("\nWiFi not connected; continuing offline."); } } void postFlowReading(float flowLpm, float totalLiters) { if (WiFi.status() != WL_CONNECTED) return; HTTPClient http; http.begin(POST_URL); http.addHeader("Content-Type", "application/json"); String payload = "{\"flow_lpm\":" + String(flowLpm, 3) + ",\"total_liters\":" + String(totalLiters, 3) + "}"; int code = http.POST(payload); Serial.printf("HTTP POST %d: %s\n", code, payload.c_str()); http.end(); } void setup() { Serial.begin(115200); delay(250); Serial.println("ESP32-S3 WiFi Water Flow Meter starting..."); pinMode(LED_WIFI_PIN, OUTPUT); pinMode(LED_FLOW_PIN, OUTPUT); pinMode(SENSOR_12V_EN_PIN, OUTPUT); pinMode(RS485_DE_RE_PIN, OUTPUT); digitalWrite(LED_WIFI_PIN, LOW); digitalWrite(LED_FLOW_PIN, LOW); digitalWrite(RS485_DE_RE_PIN, LOW); // receive by default digitalWrite(SENSOR_12V_EN_PIN, HIGH); // enable 12V sensor rail Serial2.begin(MODBUS_BAUD, SERIAL_8N1, RS485_RX_PIN, RS485_TX_PIN); modbus.begin(MODBUS_SLAVE_ADDR, Serial2); modbus.preTransmission(rs485PreTransmission); modbus.postTransmission(rs485PostTransmission); initWiFi(); Serial.println("Initialization complete."); } void loop() { if (WiFi.status() != WL_CONNECTED) { digitalWrite(LED_WIFI_PIN, LOW); static unsigned long lastReconnect = 0; if (millis() - lastReconnect > 10000) { lastReconnect = millis(); initWiFi(); } } if (millis() - lastSensorReadMs >= SENSOR_READ_INTERVAL_MS) { lastSensorReadMs = millis(); float flowLpm = 0.0f; float totalLiters = 0.0f; bool okFlow = readFloat32Holding(REG_FLOW_RATE_START, flowLpm); bool okTotal = readFloat32Holding(REG_TOTAL_VOLUME_START, totalLiters); if (okFlow) { digitalWrite(LED_FLOW_PIN, flowLpm > 0.01f ? HIGH : LOW); Serial.printf("Flow: %.3f L/min", flowLpm); if (okTotal) Serial.printf(", Total: %.3f L", totalLiters); Serial.println(); if (okTotal) postFlowReading(flowLpm, totalLiters); } else { digitalWrite(LED_FLOW_PIN, LOW); } } }
Bash
pio run pio run -t upload pio device monitor
REG_FLOW_RATE_START, REG_TOTAL_VOLUME_START, baud rate, slave address, and word order according to the sensor manual.Welcome 👋
Flux helps you build PCBs faster with an AI teammate!
Create your account to collaborate, stay updated, fork your own version, and get instant answers from our AI agent.