Modbus: Can write to the device but cannot read: no response received

Hi,

I am trying to follow Brink Flair 325 Heat recovery unit ESPhome modbus integration (~$5). I managed to connect my Nodemcuv2 with RS485 and then with the device I want to control - HRV unit. Interestingly enough, I can control e.g. the airflow, which corresponds to this part of the config:

number:
  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup Modbus step setting"
    id: rekup_step_setting
    register_type: holding
    address: 8001
    value_type: S_WORD      
    min_value: 0
    max_value: 3
    mode: slider

i.e. when I change the step, it does change it physically on the unit as expected. Similarly, I can change the bypass mode (open/close). So I think my setup is correct (and it’s very similar to what I used before via RPi, so I know it works with the unit and that the registers and commands are correct). But I cannot actually “read” anything else:

Full config:

esphome:
  name: esphome-web-aee2ce
  platform: ESP8266
  board: nodemcuv2

# Enable logging
logger:
  level: VERBOSE

# Enable Home Assistant API
api:

ota:

web_server:
  port: 80

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome HRV control"
    password: "GvJ6AafkENq6"

captive_portal:

uart:
  id: mod_bus
  tx_pin: D3
  rx_pin: D2
  baud_rate: 19200
  stop_bits: 1
  parity: even


modbus:
  id: modbus1
  
modbus_controller:
  - id: rekup
    address: 0x14
    modbus_id: modbus1
    setup_priority: -10  
    

text_sensor:
  - platform: modbus_controller
    modbus_controller_id: rekup
    id: rekup_bypass_status_text
    register_type: read
    address: 4050
    raw_encode: NONE
    name: Rekup Bypass Status
    lambda: |-
      uint16_t int_mode = (data[item->offset] << 8) + data[item->offset+1];
      ESP_LOGD("main","Parsed operation mode int : %d", int_mode);
      std::string mode_str;
      switch (int_mode) {
        case 0:  mode_str = "INITIALIZATING"; break;
        case 1:  mode_str = "OPEN"; break;
        case 2:  mode_str = "CLOSED"; break;
        case 3:  mode_str = "OPEN"; break;
        case 4:  mode_str = "CLOSED"; break;
        default: mode_str = "Unknown"; break;
  
      }
      return mode_str;
    
sensor:
  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup To House temperature"
    id: rekup_to_house_temp
    register_type: read
    address: 4036
    unit_of_measurement: "°C"
    value_type: S_WORD  
    accuracy_decimals: 1
    filters:
      - multiply: 0.1
    
  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup To House humidity"
    id: rekup_to_house_humidity
    register_type: read
    address: 4037
    unit_of_measurement: "%"
    value_type: S_WORD  
    accuracy_decimals: 1

  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup To Outside Temperature"
    id: rekup_to_outside_temp
    register_type: read
    address: 4046
    unit_of_measurement: "°C"
    value_type: S_WORD  
    accuracy_decimals: 1
    filters:
      - multiply: 0.1

  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup To Outside humidity"
    id: rekup_to_outside_humidity
    register_type: read
    address: 4047
    unit_of_measurement: "%"
    value_type: S_WORD  
    accuracy_decimals: 1

  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup From Outside Temperature"
    id: rekup_from_outside_temp
    register_type: read
    address: 4081
    unit_of_measurement: "°C"
    value_type: S_WORD  
    accuracy_decimals: 1
    filters:
      - multiply: 0.1    

  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup Flow Actual Intake"
    id: rekup_prutok_in
    register_type: read
    address: 4032
    unit_of_measurement: "m3/h"
    value_type: S_WORD  

  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup Flow Actual Exhaust"
    id: rekup_prutok_out
    register_type: read
    address: 4042
    unit_of_measurement: "m3/h"
    value_type: S_WORD  

select:
  - platform: modbus_controller
    modbus_controller_id: rekup  
    name: "Rekup Modbus Control Mode"
    address: 8000
    value_type: S_WORD
    optimistic : TRUE
    optionsmap:
      "Device LCD": 0
      "Modbus Step": 1
      "Modbus Flow": 2


  - platform: modbus_controller
    modbus_controller_id: rekup  
    name: "Rekup Bypass Mode"
    address: 6100
    value_type: S_WORD
    optimistic : TRUE
    optionsmap:
      "Auto": 0
      "Closed": 1
      "Open": 2

switch:
- platform: modbus_controller
  modbus_controller_id: rekup
  name: "Rekup Bypass Boost switch"
  register_type: holding
  address: 6104
  bitmask: 1
  entity_category: config
  icon: "mdi:toggle-switch"

number:
  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup Modbus step setting"
    id: rekup_step_setting
    register_type: holding
    address: 8001
    value_type: S_WORD      
    min_value: 0
    max_value: 3
    mode: slider

  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup Modbus flow value"
    id: rekup_prutok_nastaveni
    register_type: holding
    address: 8002
    value_type: S_WORD      
    min_value: 0
    max_value: 400
    mode: slider

  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup Flow 1"
    id: rekup_flow_1
    register_type: holding
    address: 6001
    unit_of_measurement: "m3/h"
    value_type: S_WORD      
    min_value: 50
    max_value: 400
    mode: slider
    
    
  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup Flow 2"
    id: rekup_flow_2
    register_type: holding
    address: 6002
    unit_of_measurement: "m3/h"
    value_type: S_WORD      
    min_value: 50
    max_value: 400
    mode: slider
    
  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup Flow 3"
    id: rekup_flow_3
    register_type: holding
    address: 6003
    unit_of_measurement: "m3/h"
    value_type: S_WORD   
    min_value: 50
    max_value: 400
    mode: slider

  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup Fan Imbalance Intake"
    id: rekup_imbalance_intake
    register_type: holding
    address: 6035
    unit_of_measurement: "%"
    value_type: S_WORD   
    multiply: 10    
    min_value: -15
    max_value: 15
    mode: slider
      
  - platform: modbus_controller
    modbus_controller_id: rekup
    name: "Rekup Fan Imbalance Exhaust"
    id: rekup_imbalance_exhaust
    register_type: holding
    address: 6036
    unit_of_measurement: "%"
    value_type: S_WORD      
    multiply: 10 
    min_value: -15
    max_value: 15
    mode: slider    

Verbose logs

Anyone knows what to do, please? Could it be that my RS485 converter doesn’t have enough power (currently taking 3.3v from nodemcu)?

Which modbus RS485 to ttl converter do you use?
MAX485 or a MAX3485 (XY-017) ?
The first one needs 5V and a flow_ctrl pin. (but sometimes works on 3.3 V also)
The second one works on 3.3 V and doesn’t need a flow_ctrl pin.
Code (for on a wemos d1 mini pinout)

###  Settings Brink Flair (no need to change normally)
###  menu 14-Communication: TypeBus=Modbus, Slave Address=20, Baudrate=19200, Parity=Even
uart:
  id: mod_bus
  tx_pin: D7
  rx_pin: D6
  baud_rate: 19200
  data_bits: 8
  stop_bits: 1
  parity: even

modbus:
  flow_control_pin: D5
  id: modbus1
  send_wait_time: 1000ms

modbus_controller:
  - id: ${name}
    address: 0x14 
    modbus_id: modbus1
    setup_priority: -10
    #command_throttle: 250ms
    update_interval: 15s

Also try:

# Enable/Disable logging
logger:
  level: VERBOSE
  baud_rate: 0

Thanks for helping!

MAX485 or a MAX3485 (XY-017) ?

It looks like this one: MAX485 TTL to RS-485 Interface Module - ProtoSupplies , so I guess MAX485.

I added the flow_ctrl_pin and it successfully read the inflow value (not the others though)! But likely by accident, as I cannot replicate it anymore. Update: I actually got more readings:


It just might be unreliable a lot? It throws tons of those CRC checks errors. Setting the flow still does work but takes e.g. 40 seconds (probably as it’s overloaded?).

The logger with baud_rate: 0 somehow messes up with everything and I don’t see any logs (probably expected). Here are the logs when it’s verbose and not at 0: gist:6c2e85ee1c55edd98bb1aabad5155e9f · GitHub

So… I probably need to test that 5v now, am I right?

I have had also a lot of the max485 boards (40) and also a lot of Modbus CRC Check failed errors.
Sometimes a module just did’t work and sometimes an other module worked flawlesly. (about 70% of the boards failed)
Didn’t test it on 5 V because I have had a PCB that didn;t allow that easily.
Now i have designed my own PCB with the MAX3485 and i have no more issues.

You could try 5V as that is the specification of the board.
Or just buy a 3.3-5V MAX3485

About the baudrate: 0
I dont now for sure if this is the problem. Thats why i wrote: try
VERBOSE is also demanding on the CPU. DEBUG gives you also info about the crc faults?

2 Likes

Thanks. I’m using USB charger for the ESP8266, therefore I used VIN pin for as an input for MAX485, so I should be now on 5V ish. It seems that it helped a bit: after 5ish minutes it actually manage to read all the values successfully.

DEBUG gives you also info about the crc faults?

Yes. The log is just spammed by them:

18:06:26	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:26	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:26	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:26	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:26	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:26	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:27	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:27	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:27	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:27	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:27	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:27	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=1400
18:06:27	[W]	[modbus:096]	
Modbus CRC Check failed! 4CA8!=9001
18:06:27	[W]	[modbus:096]	
Modbus CRC Check failed! 9E44!=00
18:06:27	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:27	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:27	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:28	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:28	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:28	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:28	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:28	[W]	[modbus:096]	
Modbus CRC Check failed! C071!=00
18:06:28	[W]	[modbus:096]	

(surprisingly very often the same failed check)

One thing that occurs to me is that MAX485 is grounded via ESP8266 and not the unit. Could that be an issue?

1 Like

No, i didn’t had any ground to it. (tried on mitsubishi procon and on brink flair 300
Not on a working MAX485 and not an a MAX3485.
So i dont think that would matter.

Modbus works with voltage levels between A+ en B- and not with ground (as i understand from google)

1 Like

The problem was apparently a faulty MAX485 as @Fonske guessed (+ some extra settings as per the post above).

2 Likes