ESP32 Flowmeter - RS485 Modbus
As described in the first article of this series, my first goal was to read out a TUF-2000M Ultrasonic Flow Meter via an ESP32. For this purpose I found an example for an ESP8266 on the internet: Reading a TUF-2000M Ultrasonic Flow Meter with an Arduino or ESP8266 and https://forum.arduino.cc/t/comunicacion-rs485/698786/2. I described the setup of the TUF-2000M in the following article: Field Report: Ultrasonic Flow Meter TUF-2000M. To be able to read the TUF-2000M via RS485, it must first be connected to the ESP32 via the RS485 converter:
Connect hardware
RS485 and ESP32
RS485 to TTL 5V converter with MAX13487 chip for Raspberry Pi Arduino and other MCU:
The supplied cable can be connected to the ESP32 as follows:
Connect TUF-2000M
After we have everything connected, we can take care of the software:
Arduino
Alternatively to the Arduino IDE, for HomeAssistant also ESP-Home can be used.
In preparation, the sketch requires the packages in Arduion: ModbusMaster and EspSoftwareSerial:
Modbus Master
Software Serial
Error 226
At the first attempt I used the two PINs RX and TX for the communication to the RS485 board out of ignorance, which ended in an error 226. The display mirrored the output of the serial monitor to the TUF-2000M: Menu 49, see: Serial Port Traffic
...
RX_PIN RX
TX-PIN TX
...
After connecting the RS485 board to PINS 16 and 17 of the ESP32, I was able to read out the flowmeter:
...
RX_PIN 17
RX_PIN 16
...
WLAN, MQTT and Flow
Combined with ESP32 WiFi and ESP32 MQTT - Send Data, I was able to write the current value to the MQTT broker and thus into HomeAssistant with the following sketch:
#include <WiFi.h>
#include <PubSubClient.h>
#include <SoftwareSerial.h>
#include <ModbusMaster.h>
#define RX_PIN 17 // connect to converter's RX wire
#define TX_PIN 16 // connect to converter's TX wire
#define MODBUS_DEVICE_ID 1
SoftwareSerial swSerial(RX_PIN, TX_PIN);
ModbusMaster sensor;
const char* ssid = "home";
const char* password = "???";
const char* mqttServer = "192.168.1.5";
const int mqttPort = 1883;
const char* mqttUser = "mqtt";
const char* mqttPassword = "???";
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(9600);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(5000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
swSerial.begin(9600);
sensor.begin(MODBUS_DEVICE_ID, swSerial);
client.setServer(mqttServer, mqttPort);
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect("ESP32Client", mqttUser, mqttPassword )) {
Serial.println("connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(10000);
}
}
}
void loop() {
client.loop();
readFlow();
delay(3000);
if (!client.connected()) {
delay(60000);
if (!client.connected()) {
ESP.restart();
}
}
}
void readFlow() {
uint8_t result;
uint16_t buf[2];
float flow;
result = sensor.readHoldingRegisters(1, 2);
if (result == sensor.ku8MBSuccess)
{
buf[1] = sensor.getResponseBuffer(0);
buf[0] = sensor.getResponseBuffer(1);
memcpy(&flow, &buf, sizeof(float));
client.publish("flowmeter/flow", String(flow).c_str());
}
}
For integration into Home-Assistant, see: Home Assistant MQTT
ESPHome version
In the meantime I use ESP-Home for the readout. The ESPHome version looks like this for me:
esphome:
name: heating
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "??"
ota:
password: "??"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Heating Fallback Hotspot"
password: "??"
captive_portal:
uart:
id: uart_1
tx_pin: 16
rx_pin: 17
baud_rate: 9600
stop_bits: 1
parity: none
modbus:
id: modbus_1
uart_id: uart_1
send_wait_time: 1000ms
modbus_controller:
- id: tuf2000m
address: 0x1
modbus_id: modbus_1
setup_priority: -10
update_interval: 3s
# Individual sensors
sensor:
- platform: modbus_controller
modbus_controller_id: tuf2000m
name: "flowmeter"
id: flow
register_type: holding
address: 0x1
register_count: 2
response_size: 2
accuracy_decimals: 3
value_type: FP32
unit_of_measurement: "m³/h"
- platform: modbus_controller
modbus_controller_id: tuf2000m
name: "flowmeter_travelTimeRate"
id: flow_travelTimeRate
register_type: holding
address: 0x61
register_count: 2
accuracy_decimals: 2
response_size: 2
value_type: FP32
- platform: modbus_controller
modbus_controller_id: tuf2000m
name: "flowmeter_fluidSoundSpeed"
id: flow_fluidSoundSpeed
register_type: holding
address: 0x7
register_count: 2
accuracy_decimals: 2
response_size: 2
value_type: FP32
Details about ESPHome, see: www.libe.net/en-esp-home

{{percentage}} % positive

THANK YOU for your review!
Top articles in this section
Complementary to the article: DS18B20 Temperature Sensors ESP32, MQTT and WiFi - HowTo, I have meanwhile replaced the Arduino project with ESP-Home. Simple projects can be implemented much easier in ESPHome. As an example, in ESPHome these 2 lines are enough to address the temperature sensors:
In preparation for uploading sketches to a microcontroller, I installed the ESP32 board infromations and a USB to UART Bridge driver, see: Preparations for Programming an ESP32.
To be able to receive data from an ESP32, I have prepared an MQTT broker as a Docker container. The container can be integrated into Home-Assistant and thus forward the data from the ESP32 to Home-Assistant via MQTT. On the part of ESP32, I tested sending with the following sketch and later integrated the relevant parts into another sketch.