Reverse engineer heatpump Genvex Combi 185

Okay, so I guess I can try this document that @moojuiceuk posted. It is not specific to the the Combi 185 / Optima 311, but worth trying.

Page 5 refers to “switch MODBUS on”, where I have “41 Modbus mode ‘0 mode’” on my Optima-display. The manual refers to menu point 30 (which is 41 in my case) as modbus mode. Values: 0 = modbus off (USB ON) ; 1 = 9600 baud (USB OFF) ; 2 = 19200 baud (USB OFF) ; Factory set points: 0. I guess I have to change it to 1 = 9600 baud (USB OFF).

On my Optima-display I also have ‘42 Modbus address 1 adr’. But I don’t know if this is important. I can change it to another number.

Page 4 refers to some MODBUS specs as well and page 6 refers to registers. So I guess that is an important page, but I don’t know how I can use it to try out in Modbus Master Simulator.

It won’t hurt to try, but essentially you’re shooting in the dark unless the two devices
(yours and the one in the doc moojuice pointed you to) share common register addresses as well as
other modes of operation like the one you mentioned on page 5 of said doc.

I’m not sure what to do. Suppose the two devices share common register addresses, … And suppose I want to read Register No 4x0000 [01) Temperature (°c)] ; R/W ; Size = 1 ; Units = UNIT16. As a function this should be (p. 4): Code = 03 ; Read Holding Registers ; Read the contents of read/write location (4X).

How do I translate this in the Modbus Master Simulator? Namely Device ID, Address, Length, … Does the 4x0000 means ‘Adress = 0’ and does UNIT16 means a length of 16 (bits?)? Is ‘Device ID’ something that I should find in the documentation?

Yes. Change it to 9600.

That’s the device address. No need to change it.

Your device does indeed use even parity.

The first two characters (4x) indicate the register type. In this case, a Holding register.
0000 is the address of the Temperature register.
UINT16 indicates an Unsigned 16-bit INTeger. Set the simulator display options to Integer.
Length is the number of registers you want to read. Set it to 1.

The red message time error indicates a comm problem. i.e your computer isn’t talking to your device.
Are you sure your RS-485 device is indeed on COM3?

Here’s a shot of my simulator settings:
image
(my WattNode doesn’t use parity)


Here’s the simulator querying my WattNode:


Register 1214 is a UINT16 voltage value multiplied by 10. (124.3 VAC)

While troubleshooting, you need to disconnect, then reconnect, every time you make a change.

An update of what I have done. I’ve send an e-mail to Genvex instead of to the distributor in Belgium. To my surprise I quickly had an answer with the modbus-settings I need. I made an overview: see attachment.

(after each step I did a disconnect-connect):

  1. Double checked COM3 (device manager). Was ok.
  2. Installed a 150 ohm resistor. Genvex itself said “I don’t think you are going to need the resistor”, but I wanted to be sure…
  3. Switched A and B.
  4. Searched for an updated driver instead of the default one that Windows found.
  5. Used another Windows-computer.

Then I used a Linux computer (Lubuntu 20.04):

  1. Installed libmodbus5, installed the mbpoll-deb I found, checked dmesg to see that ttyUSB0 is used.
  2. Checked the mbpoll-manual.

Tried some things:

$ sudo mbpoll -b 9600 -p even -m rtu -a 1 -r 3 -c 10 /dev/ttyUSB0 
mbpoll 1.0-0 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright © 2015-2019 Pascal JEAN, https://github.com/epsilonrt/mbpoll
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'mbpoll -w' for details.

Protocol configuration: Modbus RTU
Slave configuration...: address = [1]
                        start reference = 3, count = 10
Communication.........: /dev/ttyUSB0,       9600-8E1 
                        t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

-- Polling slave 1... Ctrl-C to stop)
Read output (holding) register failed: Connection timed out
-- Polling slave 1... Ctrl-C to stop)
(etc)
-- Polling slave 1... Ctrl-C to stop)
^C--- /dev/ttyUSB0 poll statistics ---
10 frames transmitted, 0 received, 9 errors, 100.0% frame loss

everything was closed.
Have a nice day !

Some different settings (I omitted some of the output):

$ sudo mbpoll -m rtu -b 9600 -p even -d 8 -a 3 -r 3 -c 1 -t 4:int  /dev/ttyUSB0 
Protocol configuration: Modbus RTU
Slave configuration...: address = [3]
                        start reference = 3, count = 1
Communication.........: /dev/ttyUSB0,       9600-8E1 
                        t/o 1.00 s, poll rate 1000 ms
Data type.............: 32-bit integer (little endian), output (holding) register table

-- Polling slave 3... Ctrl-C to stop)
Read output (holding) register failed: Response not from requested slave
-- Polling slave 3... Ctrl-C to stop)
Read output (holding) register failed: Response not from requested slave
-- Polling slave 3... Ctrl-C to stop)
Read output (holding) register failed: Response not from requested slave
-- Polling slave 3... Ctrl-C to stop)
Read output (holding) register failed: Response not from requested slave
-- Polling slave 3... Ctrl-C to stop)
Read output (holding) register failed: Response not from requested slave
^C--- /dev/ttyUSB0 poll statistics ---
5 frames transmitted, 0 received, 5 errors, 100.0% frame loss

Sometimes a combination of ‘timed out’ and ‘not from requested slave’:

$ sudo mbpoll -m rtu -b 9600 -p even -d 8 -a 1 -r 3 -c 1 -t 4:int  /dev/ttyUSB0 
Protocol configuration: Modbus RTU
Slave configuration...: address = [1]
                        start reference = 3, count = 1
Communication.........: /dev/ttyUSB0,       9600-8E1 
                        t/o 1.00 s, poll rate 1000 ms
Data type.............: 32-bit integer (little endian), output (holding) register table

-- Polling slave 1... Ctrl-C to stop)
Read output (holding) register failed: Response not from requested slave
-- Polling slave 1... Ctrl-C to stop)
Read output (holding) register failed: Connection timed out
-- Polling slave 1... Ctrl-C to stop)
Read output (holding) register failed: Connection timed out
-- Polling slave 1... Ctrl-C to stop)
Read output (holding) register failed: Response not from requested slave
-- Polling slave 1... Ctrl-C to stop)
Read output (holding) register failed: Response not from requested slave
-- Polling slave 1... Ctrl-C to stop)
Read output (holding) register failed: Response not from requested slave
^C--- /dev/ttyUSB0 poll statistics ---
6 frames transmitted, 0 received, 6 errors, 100.0% frame loss

After rereading everything I saw that the option should have been ‘-t 4’ instead of ‘-t 4:int’:

$ sudo mbpoll -m rtu -b 9600 -p even -d 8 -a 3 -r 3 -c 1 -t 4 /dev/ttyUSB0 
Protocol configuration: Modbus RTU
Slave configuration...: address = [3]
                        start reference = 3, count = 1
Communication.........: /dev/ttyUSB0,       9600-8E1 
                        t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

-- Polling slave 3... Ctrl-C to stop)
Read output (holding) register failed: Connection timed out
-- Polling slave 3... Ctrl-C to stop)
(etc)
Read output (holding) register failed: Connection timed out
^C--- /dev/ttyUSB0 poll statistics ---
6 frames transmitted, 0 received, 6 errors, 100.0% frame loss

So, at the moment, no luck :-(. Maybe I have a faulty USB-RS485-stick?

I rechecked everything, but to no reveal. I’ve removed the resistor of 150 ohm again. I checked the settings on the Optima-display: 41 Modbus mode ‘1 mode’ (the manual says this means 9600 baud) and 42 Modbus address ‘1 adr’. I guess the ‘1 adr’ is the address of the slave device and so this is the ‘-a 1’ option with mbpoll. In previous attempts I apparently suddenly changed it to ‘-a 3’ :frowning:.

I saw that my pdf has only page exported. I’ve updated the attachment with all the pages and register explanation. Optima311_modbus.pdf (106.6 KB)

Suppose I want to read 4x0001 '02) Domestic hot water temperature (°C)' R/W 1 UINT16. The 4x means option ‘-t 4’ without ‘:int’ or I wouldn’t read UINT16. So I guess the following command should do the job.

$ sudo mbpoll -m rtu -b 9600 -p even -d 8 -a 1 -r 1 -c 1 -t 4 /dev/ttyUSB0
Protocol configuration: Modbus RTU
Slave configuration...: address = [1]
                        start reference = 1, count = 1
Communication.........: /dev/ttyUSB0,       9600-8E1 
                        t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

-- Polling slave 1... Ctrl-C to stop)
Read output (holding) register failed: Connection timed out
-- Polling slave 1... Ctrl-C to stop)
Read output (holding) register failed: Connection timed out
-- Polling slave 1... Ctrl-C to stop)
^C--- /dev/ttyUSB0 poll statistics ---
3 frames transmitted, 0 received, 2 errors, 100.0% frame loss

But unfortunately it doesn’t do the job :frowning:

What do you get when you run the comand ls -l /dev/ttyU* ?

Thank you for the quick response! I was not sure if I needed sudo, so I did both:

~$ sudo ls -l /dev/ttyU*
crw-rw---- 1 root dialout 188, 0 jan 30 21:18 /dev/ttyUSB0
~$ ls -l /dev/ttyU*
crw-rw---- 1 root dialout 188, 0 jan 30 21:18 /dev/ttyUSB0

That looks as it should, so no issue there. Your ttyUSB0 device has the permissions it needs.

Try
mbpoll -m rtu -b 9600 -P even -d 8 -a 1 -r 1 -c 1 -t 4 /dev/ttyUSB0

Note the p is an upper case p.
A lower case p denotes a port number. Applicable to modbus TCP, but not modbus RTU.

I get timeout errors when a lower case p is used:

pi@emonpi:~ $ mbpoll -m rtu -b 9600 -p none -d 8 -a 1 -r 1019 -c 8 -t 4:float /dev/ttyUSB0 -1
mbpoll 1.4-12 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright © 2015-2019 Pascal JEAN, https://github.com/epsilonrt/mbpoll
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'mbpoll -w' for details.

Protocol configuration: Modbus RTU
Slave configuration...: address = [1]
                        start reference = 1019, count = 8
Communication.........: /dev/ttyUSB0,       9600-8E1
                        t/o 1.00 s, poll rate 1000 ms
Data type.............: 32-bit float (little endian), output (holding) register table

-- Polling slave 1...
Read output (holding) register failed: Connection timed out

but it works as it should with an upper case p.

pi@emonpi:~ $ mbpoll -m rtu -b 9600 -P none -d 8 -a 1 -r 1019 -c 8 -t 4:float /dev/ttyUSB0 -1
mbpoll 1.4-12 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright © 2015-2019 Pascal JEAN, https://github.com/epsilonrt/mbpoll
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'mbpoll -w' for details.

Protocol configuration: Modbus RTU
Slave configuration...: address = [1]
                        start reference = 1019, count = 8
Communication.........: /dev/ttyUSB0,       9600-8N1
                        t/o 1.00 s, poll rate 1000 ms
Data type.............: 32-bit float (little endian), output (holding) register table

-- Polling slave 1...
[1019]:         127.858
[1021]:         127.02
[1023]:         127.285
[1025]:         254.878
[1027]:         254.878
[1029]:         0
[1031]:         0
[1033]:         60.0369

Luckily you have an eye for detail, but unfortunately it didn’t work out. I tried it twice: the second time with A and B wires reversed.

$ sudo mbpoll -m rtu -b 9600 -P even -d 8 -a 1 -r 1 -c 1 -t 4 /dev/ttyUSB0
Protocol configuration: Modbus RTU
Slave configuration...: address = [1]
                        start reference = 1, count = 1
Communication.........: /dev/ttyUSB0,       9600-8E1 
                        t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

-- Polling slave 1... Ctrl-C to stop)
Read output (holding) register failed: Connection timed out
(etc) 
^C--- /dev/ttyUSB0 poll statistics ---
4 frames transmitted, 0 received, 3 errors, 100.0% frame loss

I’ll first try to ask Genvex if they see a problem. If they don’t, I guess I will order another USB2RS485-stick from a different brand.

Looking more and more like a bad adapter stick. Bummer.

You’re trying to read address zero, correct?

Have you tried:

sudo mbpoll -m rtu -b 9600 -P even -d 8 -a 1 -r 0 -c 1 -t 4 /dev/ttyUSB0

After thinking about it, an incorrect address value should yield an illegal address error
vice a timeout error.

I was trying to read address one, namely the 4x0001 '02) Domestic hot water temperature (°C)' R/W 1 UINT16 from the documentation. If I try to read address zero I get:

$ sudo mbpoll -m rtu -b 9600 -P even -d 8 -a 1 -r 0 -c 1 -t 4 /dev/ttyUSB0
mbpoll: start reference out of range (0) ! Try -h for help.

I’ve got an e-mail back from Genvex. The employee has experience with modbus and a Honeywell CTS controller, but never from a Genvex-unit… He had a look at their ‘Genvex Gateway (for mobile control)’. This one also uses modbus, but with a bridge between C2 and C4. Unfortunately he doesn’t know why this bridge is needed.

I made a screenshot from their ‘Quick Guide Genvex Connect’ (see link, page 3). I’ve added the blue circles:

  • Top comes from the Optima ‘Modbus_Communication_OPT311’ manual. With the strange usage of C2 and C4, bridged with a 150 ohm resistor. Strange, because it looks like it should be bridged between C2 and C3, with C4 not being used.
  • Bottom left is what I think they mean with their ‘Gateway ES1040’. Just a wire between C2 and C4 (??). Probably I don’t need C1 connected to the GND of my USBRS485 adapter. Would this be worth trying?

I’ve tried it with C1–GND ; C2–B ; C3–A and C2–150 ohm resistor–C4. To no reveal :-(. Then switched A and B, but I got the same result: connection timed out :-(.

Another setup: C1–GND ; C2–B ; C3–A, C2–150 ohm resistor–C4, C3-C4 (so just a wire between C3 and C4). This is just like the manual says, but :-(.

@Bill.Thomson, I tried a different approach. I got a Dixell xr170d from someone (eg. like this one). We don’t really know how to handle it, but we know it understands RS485. In that way I could test my RS485-USBadapter. I figured out how to set the address to 1 in the device and I wired A and B (I didn’t connect ground or used a resistor).

I tried the settings from this manual, namely 9600 bps, 8 bit data length, no parity. I couldn’t seem to find the register mapping, so I just tried something.

sudo mbpoll -m rtu -b 9600 -P none -d 8 -a 1 -r 1 -c 1 -t 4 /dev/ttyUSB0
Protocol configuration: Modbus RTU
Slave configuration...: address = [1]
                        start reference = 1, count = 1
Communication.........: /dev/ttyUSB0,       9600-8N1 
                        t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

-- Polling slave 1... Ctrl-C to stop)
[1]:    4116
-- Polling slave 1... Ctrl-C to stop)
[1]:    4116
-- Polling slave 1... Ctrl-C to stop)
[1]:    4116
-- Polling slave 1... Ctrl-C to stop)
[1]:    4116
^C--- /dev/ttyUSB0 poll statistics ---
4 frames transmitted, 4 received, 0 errors, 0.0% frame loss

Although I don’t know how to interpret the 4116 value, I guess my RS485-USB adapter just works? A polling of ‘-r 2’ gives me 20992. If that is the correct conclusion, I guess I will have to send an e-mail to Genvex to ask what is wrong with my/their setup?

The output you’re getting looks good. i.e. the format is correct. thumbsup

Looks like that’s your next step.

I did my next step, but it’s not my last one as their answer was “I guess I’m the one in our house that knows most about modbus, but not enough to help you with this.”.

Sigh… If even they don’t know it :expressionless: . I’ve tried to contact somebody else. We’ll see…

Update: today I received an e-mail that my ‘Optima 311Combi UK’ display with Genvex-nr 022083 supports modbus in the menu, but the modbus hardware is missing in my display (same for 022103). There should be a black box soldered to the 3 points, which I don’t have (see picture). Only from art. 022113 on the hardware is present :-(.

All new displays have modbus, but then I would need to go for ‘Optima 251 Design’ which costs 413,82 EUR (TVA incl.) :confused: :face_with_raised_eyebrow::roll_eyes::pensive::confused:. sigh