ESP32 Flowmeter - RS485 Modbus
Wie in dem Artikel "ESP32 programmieren, Arduino - Voraussetzungen installieren" beschrieben, war mein erstes Ziel einen TUF-2000M Ultrasonic Flow Meter über einen ESP32 auszulesen. Dazu habe ich im Internet ein Beispiel zu einem ESP8266 gefunden: Reading a TUF-2000M Ultrasonic Flow Meter with an Arduino or ESP8266 und https://forum.arduino.cc/t/comunicacion-rs485/698786/2. Das Setup des TUF-2000M habe ich in folgendem Artikel beschrieben: Erfahrungsbericht: Ultraschall Durchflussmesser TUF-2000M. Um den TUF-2000M mittels RS485 auslesen zu können, muss dieser fürs Erste über den RS485 Umwandler mit dem ESP32 verbunden werden:
Hardware verbinden
RS485 und ESP32
RS485 zu TTL 5V Umwandler mit MAX13487 Chip für Raspberry Pi Arduino und andere MCU:
Das mitgelieferte Kabel kann am ESP32 wie folgt verbunden werden:
TUF-2000M verbinden
Nachdem wir alles angeschlossen haben, können wir uns um die Software kümmern:
Arduino
Alternativ zur Arduino IDE, kann für HomeAssistant auch ESP-Home verwendet werden.
Als Vorbereitung werden für den Sketch die Pakete in Arduino benötigt: ModbusMaster und EspSoftwareSerial:
Modbus-Master
Software Serial
Error 226
Beim ersten Versuch habe ich aus Unwissenheit die beiden PINs RX und TX für die Kommunikation zum RS485-Board verwendet, was in einem Fehler 226 geendet hat. Das Display hat dabei die Ausgabe des Serial-Monitors auf den TUF-2000M gespiegelt: Menü 49, siehe: Serial Port Traffic
...
RX_PIN RX
TX-PIN TX
...
Nachdem ich das RS485-Board mit den PINS 16 und 17 des ESP32 verbunden habe, war es mir möglich den Flowmeter auszulesen:
...
RX_PIN 17
RX_PIN 16
...
WLAN, MQTT und Flow
Kombiniert mit ESP32 WiFi und ESP32 MQTT - Daten senden, konnte ich mit folgendem Sketch den aktuellen Wert zum MQTT-Broker und somit in HomeAssistant schreiben:
#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());
}
}
Zur Einbindung in Home-Assistant, siehe: Home-Assistant MQTT
ESPHome-Version
Mittlerweile verwende ich für das Auslesen ESP-Home. Die ESPHome-Version ersetzt den hier vorgestellten Sketch und schaut bei mir wie folgt aus:
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
siehe: esp-home
{{percentage}} % positiv
DANKE für deine Bewertung!
Fragen / Kommentare
(sortiert nach Bewertung / Datum) [alle Kommentare(am besten bewertete zuerst)]
Hallo, vielen Dank fürs Teilen. Ich bin bei M49 auf das gleiche Problem gestoßen, aber egal wie ich die Definition oder Verkabelung von RX und TX ändere, es wird Fehler 226 angezeigt, und der Fehler in M49 ist der gleiche wie bei Ihnen. Ich verwende denselben Code. ESP32 bei Ihnen ist Kit V4,bei mir ist V1. Der einzige Unterschied besteht darin, dass meine Signalstärke „Low“ ist. Haben Sie bessere Vorschläge?