Water level sensor QDY30A modbus RS485 with ESP32 S2 mini

I have bought water level sensor QDY30A from Ali QDY30A - the modbus RS485 version. I am trying to read its values using Wemos ESP32 S2 mini with Esphome and Max485, but no luck. Looks like the modbus connection is completely dead. Sensor docs are not so good, only wiring on that Ali page (and those colors are not correct as I have green instead of black). Some datasheet I found here (PDF). Modbus data sequence written in logs seems to be ok.

What I have also tried with no result:

  • connect DE and RE pins on MAX485 and put them to GND (signalizing always “read”)
  • switch RX and TX on ESP32
  • switch blue and yellow from sensor (A to B) as some docs shows them switched

Any hints what is wrong?

My wiring:

My yaml

substitutions:
  devicename: water-tank
  friendly_name: Water tank sensor
  device_description:  Water tank sensor (Carat 4m3)

esphome:
  name: ${devicename}
  friendly_name: ${friendly_name}
  comment: ${device_description}

esp32:
  board: lolin_s2_mini #Pinout: https://www.wemos.cc/en/latest/s2/s2_mini.html
  variant: esp32s2
  framework:
    type: arduino

wifi:
  networks:
  - ssid: !secret wifi_ssid
    password: !secret wifi_password
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ${friendly_name} Hotspot
    password: !secret wifi_ap_password

ota:
  password: !secret ota_password

# Enable logging
logger: 
  level: VERBOSE
  baud_rate: 0

captive_portal:

# restart 
button:
  - platform: restart
    name: Restart

sensor:
# Reports how long the device has been powered (in minutes)
  - platform: uptime
    name: Uptime
    filters:
      - lambda: return x / 60.0;
    unit_of_measurement: minutes

# water level sensor
# https://esphome.io/components/sensor/modbus_controller.html
  - platform: modbus_controller
    modbus_controller_id: qd
    name: "Water level"
    id: modbus_water_level
    register_type: holding
    address: 0x0004
    unit_of_measurement: "cm"
    value_type: S_WORD

# Reports the WiFi signal strength
  - platform: wifi_signal
    name: Wifi Signal
    update_interval: 60s

text_sensor:
  - platform: version
    name: ESPHome Version
  - platform: wifi_info
    ip_address: # exposes the IP Address when connected
      internal: true
      id: wifi_ip_addr
      name: "IP Address"

uart:
  id: mod_bus
  tx_pin: GPIO39
  rx_pin: GPIO37
  baud_rate: 9600
  data_bits: 8
  stop_bits: 1
  parity: NONE
  debug: 

modbus:
  id: modbus1
  uart_id: mod_bus
  send_wait_time: 500ms

modbus_controller:
  - id: qd
    address: 0x01
    modbus_id: modbus1
    setup_priority: -10
    update_interval: 5s

status_led:
  pin:
    number: GPIO15

Logs:

INFO Successfully connected to water-tank @ 172.16.1.243 in 0.347s
INFO Successful handshake with water-tank @ 172.16.1.243 in 8.833s
[19:28:14][I][app:102]: ESPHome version 2024.2.1 compiled on Mar  3 2024, 17:39:55
[19:28:14][C][status_led:019]: Status LED:
[19:28:14][C][status_led:020]:   Pin: GPIO15
[19:28:16][C][wifi:577]: WiFi:
[19:28:16][C][wifi:409]:   Local MAC: 80:65:99:49:8A:98
[19:28:16][C][wifi:414]:   SSID: 'Vega'
[19:28:16][C][wifi:415]:   IP Address: 172.16.1.243
[19:28:16][C][wifi:417]:   BSSID: 2A:3B:82:4D:2D:6C
[19:28:16][C][wifi:418]:   Hostname: 'water-tank'
[19:28:16][C][wifi:420]:   Signal strength: -50 dB ▂▄▆█
[19:28:16][V][wifi:422]:   Priority: 0.0
[19:28:16][C][wifi:424]:   Channel: 9
[19:28:16][C][wifi:425]:   Subnet: 255.255.255.0
[19:28:16][C][wifi:426]:   Gateway: 172.16.1.1
[19:28:16][C][wifi:427]:   DNS1: 192.168.1.1
[19:28:16][C][wifi:428]:   DNS2: 0.0.0.0
[19:28:16][C][logger:447]: Logger:
[19:28:16][C][version.text_sensor:021]: Version Text Sensor 'ESPHome Version'
[19:28:16][C][mdns:115]: mDNS:
[19:28:16][C][mdns:116]:   Hostname: water-tank
[19:28:16][V][modbus_controller:047]: Sending next modbus command to device 1 register 0x04 count 1
[19:28:16][V][modbus:199]: Modbus write: 01.03.00.04.00.01.C5.CB (8)
[19:28:16][V][modbus_controller:509]: Command sent 3 0x4 1
[19:28:16][D][uart_debug:114]: >>> 01:03:00:04:00:01:C5:CB
[19:28:16][V][modbus_controller:047]: Sending next modbus command to device 1 register 0x04 count 1
[19:28:16][V][modbus:199]: Modbus write: 01.03.00.04.00.01.C5.CB (8)
[19:28:16][V][modbus_controller:509]: Command sent 3 0x4 1
[19:28:16][D][uart_debug:114]: >>> 01:03:00:04:00:01:C5:CB
[19:28:17][V][modbus_controller:047]: Sending next modbus command to device 1 register 0x04 count 1
[19:28:17][V][modbus:199]: Modbus write: 01.03.00.04.00.01.C5.CB (8)
[19:28:17][V][modbus_controller:509]: Command sent 3 0x4 1
[19:28:17][D][uart_debug:114]: >>> 01:03:00:04:00:01:C5:CB
[19:28:17][D][modbus_controller:043]: Modbus command to device=1 register=0x04 countdown=0 no response received - removed from send queue
[19:28:20][V][modbus_controller:181]: Updating modbus component
[19:28:20][V][modbus_controller:148]: Range : 4 Size: 1 (3) skip: 0
[19:28:20][V][modbus_controller:047]: Sending next modbus command to device 1 register 0x04 count 1
[19:28:20][V][modbus:199]: Modbus write: 01.03.00.04.00.01.C5.CB (8)
[19:28:20][V][modbus_controller:509]: Command sent 3 0x4 1
[19:28:20][D][uart_debug:114]: >>> 01:03:00:04:00:01:C5:CB
[19:28:21][V][modbus_controller:047]: Sending next modbus command to device 1 register 0x04 count 1
[19:28:21][V][modbus:199]: Modbus write: 01.03.00.04.00.01.C5.CB (8)
[19:28:21][V][modbus_controller:509]: Command sent 3 0x4 1
[19:28:21][D][uart_debug:114]: >>> 01:03:00:04:00:01:C5:CB
[19:28:21][V][modbus_controller:047]: Sending next modbus command to device 1 register 0x04 count 1
[19:28:21][V][modbus:199]: Modbus write: 01.03.00.04.00.01.C5.CB (8)
[19:28:21][V][modbus_controller:509]: Command sent 3 0x4 1
[19:28:21][D][uart_debug:114]: >>> 01:03:00:04:00:01:C5:CB
[19:28:21][V][modbus_controller:047]: Sending next modbus command to device 1 register 0x04 count 1
[19:28:21][V][modbus:199]: Modbus write: 01.03.00.04.00.01.C5.CB (8)
[19:28:21][V][modbus_controller:509]: Command sent 3 0x4 1
[19:28:21][D][uart_debug:114]: >>> 01:03:00:04:00:01:C5:CB
[19:28:22][V][modbus_controller:047]: Sending next modbus command to device 1 register 0x04 count 1
[19:28:22][V][modbus:199]: Modbus write: 01.03.00.04.00.01.C5.CB (8)
[19:28:22][V][modbus_controller:509]: Command sent 3 0x4 1
[19:28:22][D][uart_debug:114]: >>> 01:03:00:04:00:01:C5:CB
...
1 Like

Not sure, but looks You to connect DE/RE pins together and to ESP board.

See here:

  • flow_control_pin (Optional, Pin): The pin used to switch flow control. This is useful for RS485 transceivers that do not have automatic flow control switching, like the common MAX485.
1 Like

I have tried to connect them together. I did not connect them to ESP board as I am not planning to write to sensor, I am only reading. So I connected them to GND as recommended here:

If you’re only ever going to be either transmitting or receiving then you could tie both DE and RE high (permanent transmit) or both low (permanent receive).

But no data came from sensor.

I made a water level sensor a couple years back has worked flawlessly I used this sensor https://www.amazon.com/gp/product/B087N3LV1J/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1 with a D1 mini, the only strange thing is I had to use 12v and 5v power supplies.

esphome:
  name: pond-height
  friendly_name: pond-height

esp8266:
  board: d1

sensor:
  - platform: adc
    pin: A0
    name: "Pond Height"
    update_interval: 36000s
    filters:
      - multiply: 3.3

# 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: "Pond-Height Fallback Hotspot"
    password: ""

captive_portal:

Looks similar, but you have version which returns values as current, I have a modbus RS485 version.

Not a big expert in RS485, but this looks like ESP sending something.
Suggest to connect DE/RE to ESP and configure as descrobed.
Why not.

You were right with a flow control pin. I definitely need to write something to sensor - commands for reading. So I need a flow control pin for MAX485.

Finally my wiring:

I have also switched the A and B (blue and yellow) wires from sensor to MAX485. Now it is working. Sensor is sending unit “cm”, but is measuring in “mm”. Measurements are very quick and very accurate (water level in the bucket 122mm, value returned: 122). Current draw by sensor is stable 5.7mA.

My final esphome yaml for those, who will look for working setup in a future:

substitutions:
  devicename: water-tank
  friendly_name: Water tank sensor
  device_description:  Water tank sensor (Carat 4m3)

esphome:
  name: ${devicename}
  friendly_name: ${friendly_name}
  comment: ${device_description}

esp32:
  board: lolin_s2_mini #Pinout: https://www.wemos.cc/en/latest/s2/s2_mini.html
  variant: esp32s2
  framework:
    type: arduino

wifi:
  networks:
  - ssid: !secret wifi_ssid
    password: !secret wifi_password
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ${friendly_name} Hotspot
    password: !secret wifi_ap_password

ota:
  password: !secret ota_password

# Enable logging
logger: 
  level: DEBUG
  baud_rate: 0

captive_portal:

# restart 
button:
  - platform: restart
    name: Restart

sensor:
# Reports how long the device has been powered (in minutes)
  - platform: uptime
    name: Uptime
    filters:
      - lambda: return x / 60.0;
    unit_of_measurement: minutes

# water level sensor
# https://esphome.io/components/sensor/modbus_controller.html
  - platform: modbus_controller
    modbus_controller_id: qd
    name: "Water level"
    id: modbus_water_level
    register_type: holding
    address: 0x0004
    unit_of_measurement: "mm"
    value_type: S_WORD

# Reports the WiFi signal strength
  - platform: wifi_signal
    name: Wifi Signal
    update_interval: 60s

text_sensor:
  - platform: version
    name: ESPHome Version
  - platform: wifi_info
    ip_address: # exposes the IP Address when connected
      internal: true
      id: wifi_ip_addr
      name: "IP Address"

uart:
  id: mod_bus
  tx_pin: GPIO39
  rx_pin: GPIO37
  baud_rate: 9600
  data_bits: 8
  stop_bits: 1
  parity: NONE
  #debug: 

modbus:
  id: modbus1
  uart_id: mod_bus
  flow_control_pin: GPIO35

modbus_controller:
  - id: qd
    address: 0x01
    modbus_id: modbus1
    setup_priority: -10
    update_interval: 5s

status_led:
  pin:
    number: GPIO15

Thanks a lot to all!

1 Like

Hello Martin, did you try to change the modbus address of this sensor via esphome ? I want to use two sensors hence the need to change the default modbus address but all my tries failed! Any clue? Thanks

Function 6

Read pdf in first post

hi again, i tried it as following:

  • platform: modbus_controller
    modbus_controller_id: mbtank
    name: “water tan address change”
    id: tan_address_change
    custom_command: [ 0x1, 0x06, 0x00, 0x00, 0x00, 002, 0x0B, 0xE0]
    value_type: S_WORD

and got this error:
[23:26:45][D][modbus:119]: Modbus error function code: 0x86 exception: 1
[23:26:45][E][modbus_controller:091]: Modbus error function code: 0x6 exception: 1
[23:26:45][E][modbus_controller:100]: Modbus error - last command: function code=0x6 register address = 0xCCAD registers count=1 payload size=8

hi again, i tried it as following:

  • platform: modbus_controller
    modbus_controller_id: mbtank
    name: “water tan address change”
    id: tan_address_change
    custom_command: [ 0x01, 0x06, 0x00, 0x00, 0x00, 0x02, 0x0B, 0xE0]
    value_type: S_WORD

and got this error:
[23:26:45][D][modbus:119]: Modbus error function code: 0x86 exception: 1
[23:26:45][E][modbus_controller:091]: Modbus error function code: 0x6 exception: 1
[23:26:45][E][modbus_controller:100]: Modbus error - last command: function code=0x6 register address = 0xCCAD registers count=1 payload size=8
[/quote]

  • platform: modbus_controller
    modbus_controller_id: mbtank
    name: “water tan address change”
    id: tan_address_change
    custom_command: [ 0x01, 0x06, 0x00, 0x00, 0x00, 0x02]
    value_type: U_WORD

Thanks Martin ! I got mine running, but needed to swap ESP32 TX and RX wires in respect to your wiring diagram.
(also See: Modbus with EW11 + QDY30A RS485 water level measure probe - #5 by murcielago)

For your information: my experiments show that the holding register at 0x0005 (zero point) actually is writable. The value will be added to the result in register 0x0004.

BTW: Other registers are also writable and stored, but don’t change anything (unit of measurement, scaling factor)

Hi murcielago,
with your crucial tip to swap TX and RX wires, it also worked for me. Many thanks for that!
I read in another post of yours that you still want to change the millimeters to liters. Did you succeed?
Regards, Frank