First venture into MODBUS, how to send a password?

It seems you picked a fairly complicated system as your first foray into Modbus. It sounds like you have 3 Modbus devices in your system: the heat pump itself, the display, and the WiFi gateway. One of these devices must be the master and the other two are the slaves.

I recommend first determining which device is the master. I believe you've already removed the WiFi gateway and still see communications, so you just need to find out whether the master device is the display or the heat pump. The easiest way to do this is to monitor communications (using LED's or software on your PC) and powering off or removing one of the devices from the network. If there is still communications traffic, the device powered on and connected to the network is the master.

Now the problem:
Home Assistant is very likely a Modbus Master. You can only have one Modbus master on the bus. If you want to connect Home Assistant to a Modbus device, the typical way of doing this is to connect directly to the Modbus device (which must be a Modbus slave) without any other master on the bus (i.e. Home Assistant can be the only Modbus master on the RS-485 bus).

If the display is the master, then you could simply disconnect the display and connect Home Assistant to the heat pump. However, you would have to be alright with not having the display anymore and the WiFi gateway would not work unless you can configure Home Assistant to duplicate the messages that the display sent to the WiFi gateway.

Alternatively, you can connect a gateway to the system that supports "sniffing" the existing Modbus network. This gateway can listen to the communications between the display, heat pump, and WiFi gateway, extract the register values exchanged, and make them available to a separate RS-485 Modbus network. Now keep in mind, though, since the display is the master, you are limited to only being able to "sniff" the registers that the display is requesting.

ICC's Mirius gateway can be used for sniffing a Modbus RTU network and exposing the data to another Modbus RTU master:
http://www.iccdesigns.com/protocol-gateways/66-mirius.html
 
1. >I'm also a bit unsure how to read the data (e.g. 1013). Is it a holding register, input register or ?

The leading numeral in parentheses indicates whether the register is a holding register or an input register.
Leading numeral (4) is a Holding register, like (4)1013 or (4)01013
Leading numeral (3) is an Input register, like (3)1013, or (3)01013.

Some masters want the leading numeral defined, others do not, I can't recall whether Simply Modbus does or does not. Modscan assumes the (4) and wants the indexed decimal value.

The listed values are likely Holding registers because the column citing R/W, read or write is possible for Holding registers, whereas Input registers are Read Only.

One other note, there is a one-offset phenomenon, due to whether the register list starts at zero or starts at one.

Normally, decimal values are one-based, (4)0001, (4)0002, (4)0003, etc.
Normal hex values start at zero: 0000, 0001, 0002, 0003, etc. (and hex values do not use the leading numeral)

That table shows the decimal and hex values as identical, if hex 3F8 is zero based, then the equivalent value for Modscan (which uses one based decimal register addresses) would be (4)1017, not the (4)1016 shown on the table. You should be able to tell by whether the data values match up with the register address or whether they're offset by one.

2. The Simply Modbus Slave

Simply Modbus is the Master, issuing polls to the heat pump, which is the slave.
 
You might try connecting Simply Modbus to the 2nd RS-485 and see what the effect is. No telling how sophisticated the unit is, but it just might map Modbus to a separate memory for both RS-485 ports. Who knows?
 
Succss! (Or at least on my way to success)
I finally managed to get some data out!

By using a modbus slave software, I can get data out from device 1, which as I see it, is the Master.
I learned that by reading register H37, I can read what the unit id is (1).
If I read e.g. 1030 which is the current setpoint, I get 281 which is equivalent to 28.1 degrees celsius.

So I can now communicate with some of the registers on the the heater.

But as you also mentioned @jschulze, Home Assistant acts as a Master, so does the heater (Probably, not the display). I cannot have two masters, so I need to figure out how to solve that puzzle.

Also reading registers > 2000 gives an error in reading the register and an error on the heater. Don't quite understand that part yet.

But I'm on my way, at least

@David_2 It could be worth a try. Just a bit afraid of breaking something :oops:
 
By using a modbus slave software, I can get data out from device 1, which as I see it, is the Master.
I learned that by reading register H37, I can read what the unit id is (1).
If I read e.g. 1030 which is the current setpoint, I get 281 which is equivalent to 28.1 degrees celsius.

But as you also mentioned @jschulze, Home Assistant acts as a Master, so does the heater (Probably, not the display). I cannot have two masters, so I need to figure out how to solve that puzzle.
I think you might have this backwards. Reading a register is an action that only a master can perform. Also, only a slave has a slave address (unit id). Are you perhaps using Simply Modbus Master?

Did you disconnect the display to determine if the display or the heat pump is the master on the bus?

If you are indeed using Simply Modbus Slave, you've added two slaves to your network with the same address (both at address 1). This can cause communication issues between the display and the heat pump, since two devices would attempt to respond to the same request.
 
@mrwee Did you get any further with this? I have the same heat pump and I want to use ESPHOME to read data and use it in Home Assistant.

Hopefully you have more news and maybe already a working setup.
 
@mr_sjappie
Not as far as I'd like to. What I've learned (I think):
- Heat pump & Wi-Fi module are slaves. When I removed the display, the bus went silent. When display is attached, a lot of communication is going on.
- I'm not going to use Wi-Fi module, so it's out of my equation.
- The heatpump is using MODBUS RTU.
- Home Assistant will act as MODBUS master, but only without the display attached.
- The company said it was fine with 120Ohm resistor on the far end of the bus, so I'm using that.
- I briefly tried to communicate with it, after removing the display but I'm lacking a good / easy tool to scan / search for slaves.
- I have not found the slave ID for the heat pump. A scan does not reveal anything.
- Since my heatpump shows E03 when there is no flow, I assume that I should be able to read that from register 2074 in idle mode.
- MODBUS has changed somewhat in Home Assistant, but I've not tried that path yet. Also, I don't have much experience with ESPHOME either.
- I'm testing with a Moxa RS-485 to IP converter and/or a simple RS-485 USB Adapter.
I'm attaching two manuals for heatpumps using the PC1002 controller, the .pdf file is from the company who manufactures the one I have. The .zip file contains a similar manual, but from a different company.

But please share your setup, findings and experience, hopefully we can crack this nut :)
 

Attachments

Please try the following:

  1. Download and install the CAS Modbus Scanner (https://store.chipkin.com/products/tools/cas-modbus-scanner)
  2. Wire your USB to RS-485 converter to the heat pump only as follows:
    1. Converter's RS-485 + to Heat Pump's 485A
    2. Converter's RS-485 - to Heat Pump's 485B
    3. Converter's ground (i.e. Common/Com, Reference/Ref) to Heat Pump's GND
  3. Remove all 120 ohm termination resistors. These resistors are not necessary since the heat pump uses 9600 baud (transmission line effects, i.e. signal reflections will not cause communication issues at that low of a baud rate).
  4. Discover the heat pump using CAS Modbus Scanner (you previously stated the heat pump is at address 1, which you determined by looking at parameter H37, so the CAS Modbus Scanner should discover the heat pump at address 1 if your connections are correct)
    1. Open CAS Modbus Scanner
    2. Click the Discover button
    3. In the Connection box, select Serial, select the COM port of your USB to RS-485 converter, select 9600 for the Baud rate
    4. Set the Timeout to 1 (i.e. 1 second)
    5. Click the Start Scan button
    6. Any status other than Timeout (i.e. Good or Exception) indicates there is a device at that address
  5. After you confirm the address of your heat pump, you can use CAS Modbus Scanner to poll values
    1. In the main window, right click on the pane on the left and select Add Connection
    2. Select the following, then click the Add Serial Connection button:
      1. Serial Port: COM port of your USB to RS-485 converter
      2. Baud Rate: 9600
      3. Data Bits: 8
      4. Stop Bits: 1
      5. Parity: None
      6. Timeout: 1
    3. Right click on the new connection and select Add Device
    4. Enter the heat pump's address in the Slave ID field and click the Add Device button
    5. Right click on the new device and select Add Task
    6. Enter the following to read the set point (address 1029, note that you must add 1 to this number), then click the Add Request button
      1. Function: 03 Read Holding registers (4xxxx)
      2. Offset: 1030
      3. Length: 1
    7. Click the Poll button to read the value, the value (multiplied by 10, since it's in 0.1 units) should appear in the uint16 column
 
@jschulze Thank you for your elaborate description :)

Unfortunately I'm not 100% sure the slave address is 1, since I've been unable to probe any data.
I tried your suggestion, but don't see a clear pattern in terms of discovery response. Sometime I get a timeout on a device, sometimes not.
Also when doing the probing for 1029, I get e.g. "modbus messaage invalid length" or Invalid CRC.

I have also tried IO Ninja, and just listen on the bus. This shows me that "something is out there". E.g. I can see the serialnumber of the heat pump. If the rest of the data is correct, then something is being written to Dev 0, and read from device 1 and 2.
Neither the display nor the Wi-Fi module is attached at the moment.

13:52:00 +13:14.325 < [+] MODBUS-RTU Dev: 2 Fn: 3 Read Holding Registers (Request) Addr: 0x0bb9 N: 90
13:52:00 +13:14.559 > 0000 00 10 07 d1 00 5a b4 57 46 31 37 30 33 32 31 30 .....Z.WF1703210
> 0010 30 32 35 00 00 00 00 01 01 07 d1 00 00 00 01 00 025.............
13:52:00 +13:14.592 > 0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa 00 ................
> 0030 00 00 00 fd da 00 00 00 00 00 00 00 00 00 00 00 ................
13:52:00 +13:14.626 > 0040 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00 00 ..........0.....
> 0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
13:52:00 +13:14.659 > 0060 b5 01 1a 01 20 00 c1 00 df 01 b1 00 00 00 00 00 .... ...........
> 0070 00 00 00 00 00 5a a5 00 00 00 00 00 00 00 00 00 .....Z..........
13:52:00 +13:14.692 > 0080 00 00 3c 00 00 00 00 00 b1 00 00 00 00 00 00 00 ..<.............
> 0090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
13:52:00 +13:14.746 > 00a0 00 00 00 00 00 00 00 00 00 00 00 00 10 02 39 00 ..............9.
> 00b0 00 00 00 00 00 00 00 00 00 00 00 1d 19 .............

13:52:00 +13:14.746 < [+] MODBUS-RTU Dev: 0 Fn: 16 Write Multiple Registers (Request) Addr: 0x07d1 { 22342 12599 12339 12849 ... }
13:52:01 +13:15.341 > 0000 01 03 0b b9 00 5a 16 30 .....Z.0

13:52:01 +13:15.341 < [+] MODBUS-RTU Dev: 1 Fn: 3 Read Holding Registers (Request) Addr: 0x0bb9 N: 90
13:52:01 +13:15.573 > 0000 02 03 0b b9 00 5a 16 03 .....Z..

13:52:01 +13:15.573 < [+] MODBUS-RTU Dev: 2 Fn: 3 Read Holding Registers (Request) Addr: 0x0bb9 N: 90
13:52:01 +13:15.807 > 0000 00 10 07 d1 00 5a b4 57 46 31 37 30 33 32 31 30 .....Z.WF1703210
> 0010 30 32 35 00 00 00 00 01 01 07 d1 00 00 00 01 00 025.............
13:52:01 +13:15.840 > 0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa 00 ................
> 0030 00 00 00 fd da 00 00 00 00 00 00 00 00 00 00 00 ................
13:52:01 +13:15.874 > 0040 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00 00 ..........0.....
> 0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
13:52:02 +13:15.907 > 0060 b5 01 1a 01 20 00 c1 00 df 01 b1 00 00 00 00 00 .... ...........
> 0070 00 00 00 00 00 5a a5 00 00 00 00 00 00 00 00 00 .....Z..........
13:52:02 +13:15.940 > 0080 00 00 3c 00 00 00 00 00 b1 00 00 00 00 00 00 00 ..<.............
> 0090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
13:52:02 +13:15.994 > 00a0 00 00 00 00 00 00 00 00 00 00 00 00 10 02 39 00 ..............9.
> 00b0 00 00 00 00 00 00 00 00 00 00 00 1d 19 .............

13:52:02 +13:15.994 < [+] MODBUS-RTU Dev: 0 Fn: 16 Write Multiple Registers (Request) Addr: 0x07d1 { 22342 12599 12339 12849 ... }
13:52:02 +13:16.589 > 0000 01 03 0b b9 00 5a 16 30 .....Z.0

13:52:02 +13:16.589 < [+] MODBUS-RTU Dev: 1 Fn: 3 Read Holding Registers (Request) Addr: 0x0bb9 N: 90
13:52:02 +13:16.821 > 0000 02 03 0b b9 00 5a 16 03 .....Z..
 
@mrwee
It seems that the heat pump is actually the master. If you're seeing it transmit at all with no other devices connected other than passively monitoring the RS-485 bus, then it is definitely the master. In which case, you cannot use CAS Modbus Scanner.

Additionally, Modbus RTU address 0 is reserved for broadcast messages that are processed by all slave devices (a device cannot use address 0 for its own slave address). This is also further proof that the heat pump is the master. It is broadcasting its data using function code 16 Write Multiple Registers. Specifically, it is broadcasting register addresses 2001 - 2090 (i.e. the broadcast request starts at register address 2001 [0x07d1] and writing 90 registers).

Note that in the output you show from IO Ninja, the decoding of the message comes after the raw bytes (this can be confirmed by looking at the timestamps). It also seems like IO Ninja receives data in 16-byte blocks where the first 4 digits (the 0000, 0010, 0020, 0030, 0040, etc.) correspond to a byte offset in hexadecimal (this is not part of the Modbus packet).

Therefore, I believe if you go back to using Simply Modbus Slave, set its ID to any number besides 1 or 2, and set up a register definition for 90 registers starting at register 42002 (note that this is 1 more than the register address of 2001), function code 03, read/write, 16bit register size, and 16bit Signed Integer, you should be able to see the data for those 90 registers in Simply Modbus Slave.
 
The only reason I thought of this was because I'm currently working with an OEM that uses Modbus for communication and does the same thing. Data is broadcasted from the main device to the peripheral devices such as displays, etc. It's a pretty interesting usage of the broadcast commands and seems to be a good workaround to the multiple master limitation by reversing the roles of the devices. Of course to do this, you have to be in full control of every device.
 
I have tried it today with Modbus Slave. But I think I am doing something wrong with the settings, as I don't see value's in the data screen. I have uploaded screenshots of the Modbus Slave program. Any pointers would be appreciated.. :)
 

Attachments

I have tried it today with Modbus Slave. But I think I am doing something wrong with the settings, as I don't see value's in the data screen. I have uploaded screenshots of the Modbus Slave program. Any pointers would be appreciated.. :)
I think you need to change your Offset field to 40001. You seem to have a value of 1030 right now, which is not correct.
 
This is yet another case of Modbus XXX being a time sink.
There is nothing in the specification about sending passwords and the question I have is do you really want to? Modbus xxx says nothing about encrypting a password. If I just wanted to keep people from changing parameters at an HMI I would just send a number or combination.

If I controlled both the master and slave and I wanted real security I would make up a new command for sending a password. I would encrypt the password into a 64,128 or 256 bit block and send the bytes over Modbus xxx where the password could be decrypted. This would avoid someone taping into the line and seeing the password.
 
I think you need to change your Offset field to 40001. You seem to have a value of 1030 right now, which is not correct.
To expand on this, because the register listing for the heat pump uses 0-based register addressing, it probably makes more sense to set the First Register to 2001 and the Offset to 0 in Simply Modbus Slave's Slave Data window (note that this generates the same hex addresses as using First Register = 42002 and Offset = 40001). That way the register numbers shown in Simply Modbus Slave will match the addresses in the heat pump's documentation.

For details on Modbus register numbering, see this thread:
https://control.com/forums/threads/modbus-register-numbering.49844/
 
Whooohoooo Finally some data.. :) :)

Good_1.jpg

I did not test your suggestion on first register 2001.

And I needed to set the option "respond to all slave id's".
Is there a way to find out what the correct slave ID is? Other then testing number for number... ;)

Any idea on how to get this modbus data with a ESP8266 module over WiFi to MQTT or directly to home assistant? most options are master based, not slave based... :(

But I am already happy we now know how it works. So thank you for all your idea's!
 
You should not need to check the "Respond to all Slave ID's" option. This likely means that Simply Modbus Slave does not support receiving broadcast (Slave ID 0) packets. If you have the "Respond to all Slave ID's"option checked, Simply Modbus Slave will process and send a response to EVERY request packet on the network (this also includes the Slave ID 0 broadcasts, which should not be responded to by any slave). While this (probably) won't cause issues when it's the only slave on the network, it definitely will cause problems if you have other equipment connected to the heat pump (i.e. the display or WiFi adapter).

You may need to try a different Modbus Slave software. This one specifically mentions broadcast support as a feature:
https://www.modbustools.com/modbus_slave.html

You want to configure this Modbus slave with an unused slave address (not 1 or 2) so it will sit passively on the network and just process the broadcast messages.

To communicate directly with Home Assistant, one way to do it would be using a gateway device with both of its ports configured for Modbus RTU Slave, such as this:
http://www.iccdesigns.com/protocol-gateways/66-mirius.html

Or if you want to communicate Ethernet to Home Assistant, you could use this gateway instead:
http://www.iccdesigns.com/millennium-series/10-eth-1000.html

To communicate using the ESP8266, you would need to write your own application and connect an RS-485 transceiver to communicate Modbus RTU via RS-485 (or you could use a USB to RS-485 adapter if the ESP8266 device has a USB host port and supports serial converters). There are several Modbus libraries available that could be used, such as this:
https://www.arduino.cc/reference/en/libraries/modbus-esp8266/
 
Top