Isaver pool pump speed control MODBUS => Waveshare USB to RS485

Hello,

Im currently trying to connect my Isaver pool pump speed controller through MODBUS with Home Assistant.
We received the information of the RS485 protocol and i bought a Waveshare USB to RS485 to connect with the RPI.

USB controller: Waveshare RS485
Speed regulator info: Isaver 1100 +
Speed regulator manual: Manual (page 8)
Information MODBUS protocol: Modbus RS485 protocol

This is the first time i have to program something with these protocols and i was wondering if you guys would want to help me get started how to write the code?

Thx alot for helping :sweat_smile:

I am exactly in the same situation, looking for any help on how to control the ISaver+ from RS485. I’ll share the info here if I find it elsewhere.

Hello, thx for the reply.

At the moment i am testing this code,but doesn’t work:

modbus:
    name: "iSaver"
    type: serial
    baudrate: 9600
    bytesize: 8
    method: rtu
    parity: N
    port: /dev/ttyUSB0
    stopbits: 1
    retry_on_empty: true
    retries: 20
    close_comm_on_error: false
    delay: 5
    timeout: 5
    sensors:
    - name: iSaver_error
      slave: 3
      address: 2001
    - name: iSaver_status
      slave: 3
      address: 2002
    - name: iSaver_speed
      slave: 3
      address: 2003
    - name: iSaver_power
      slave: 3
      address: 2004
      unit_of_measurement: Watt

The respond is: 2023-06-26 10:07:34.742 ERROR (SyncWorker_3) [homeassistant.components.modbus.modbus] Pymodbus: iSaver: Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 4 bytes (0 received)

Any progress? I´m also trying using ESPHome component with out any luck.

After testing every possible combination ive contacted the importer in Belgium.

They have deactivated the MODBUS feature :scream:

NO! This was not god information.
Any reason why?

So given the last few posts this thread went dead.
I can give some major good news on these units after many weeks of frustration and research.

I recently bought an iSaver+ unit (the iSaver, Madimack and other brands are all the same unit). All these units are manufactured by Aquagem in China.

When I queried my supplier in the UK they also told me that the RS485 Modbus protocall was disabled on these units. This turns out to be completely false.

Aquagem have actually been fantastic. There is a support member there called Allen who has been giving me excellent information and helping me work out getting a modbus response from the unit. The manufacturer has confirmed the RS485 CANNOT be disabled on these units. If you have one of these ignore what the supplier tells you, the RS485 is always enabled.

So despite my supplier telling me there is no RS485 and it was disabled i am now receiving RS485 data from my unit (using a rough set up with a ESP32, RS845 Max module and esphome)

I will post more details once I’ve got this all set up properly and creating all the sensors and controls properly.

oh, and by the way after weeks of frustration it turns out the rs485 modules are very very flaky which caused a lot of my problems. Reading on other forums a 70% failure rate for these boards is very common and right in line with my recent experience.

1 Like

oh and the modbus protocol was changed slightly by the manufacturer. Here is the updated version

Thanks ! I’m also trying to figure this out !!

Hi, would you mind to post your last/final ESPhome config? [Nerver mind found your post Post ]
I’m currently thinking of either using the digital pins to be triggered by a custom relay board or using rs485.
But I have no real clue where to start etc… any help is more than appreciated.

Kind Regards,
Dieter

@DeWaFre Did you or any other manage to create anything? Did you to get it to work? I’m stuck… :roll_eyes: I got the same gateway, the Waveshare RS485. Manage to connect to the gateway with Node-Red but can’t get hold of any data reading the registrar address. Also the Modbus seem strange, kind of their own… reading from the protocol description.
If you have any hints or anything to share, please do. I’ll share if I manage to get any further but now I’ve hit the wall. Completely.

Also, any other that got the device/unit ID to 170??? (slave address 0xAA ) Strange

Cheers.

EDIT 2024-10-16 The iSaver don’t seem to be working with any Modbus/RS486 Gateway. Not the same as a RS486 USB stick or similar. Based on the knowledge I have on RS486 this type of unit don’t seem to follow the standard protokoll. Nothing behaves the way I’ve learned. I have been trying a Waveshare Gateway on the Model 1100 (1 Phase 6A 1.1kW) European market. Another guy and contributor on this forum that also tried the gateway can tell the same story. Haven’t seen anyone else yet posting any different stories regarding gateways. However there is a solution that has been tried out and can be found further down in this thread. Using a ESP32 card with an 485 TTL board.

BRAND & MODEL: Same unit seem to be rebranded to names like (example) INVERSilence, Madimack, Rapid X20, AtecPool, Trendpool, Vario, AquaForte, Vitalia, Aquagripp, Aquagem. They all looks like they are the same product. There also seem to be a few different hardware versions as they have renewed them.

Hello,

After contact with the importer Isaver about this problem, they let me know that they disabled this function :face_with_raised_eyebrow:

Thats not correct. Look at this: Modbus - iSaver+ Pool Pump Inverter - Custom Commands Issue - Response mising bytes

I am in contact with the manufacturer. Problem is that the protocol is no standard and esphome does it not support by default I think.

@NightWatcher Hi, did the manufacturer get back to you?

I failed to get any data into my RS485 bridge at my first test. Have to investigate further.

Wonder if I got the wiring wrong.

  • The plus and minus connections isn’t that difficult to figure out. However the ground from the iSaver isn’t obvious. Or is it? There is one on the board next to the plus and minus. That would be the one… However not on the same bridge but that could be a simple construction choice. Didn’t get any data.
    There is another digital ground that got my attention, however its on the second row of the connectors. So I will try that.*

Curious on what you others can find out.

He did, but without any solution. At the moment, i have other things to do. Maybe i find my 5 minutes in the winter time to try it again.

Which plus and minus are you searching? The rs485 pinout is documented in the manual. You only need this 2 lines.

@NightWatcher Thanks for letting me know. So did they confirm the RS485 was activated or not? Has been confirmed once so hope it is the case.

I found the plus and minus, wasn’t a problem. Easy to identify. I failed to communicate with the unit and started to investigate why. Did some research and found some notes about the GND. Nothing that I had an issue with before. The note said that in some cases the GND is needed with RS485. The information on this in the documentation is very limited. Thought it was worth a try.

Well, there is never enough time to calibrate.

They confirm, that the rs485 is activated. And for me it is. Only the problem is the crc I think.

1 Like

I’ve managed to get this working for the Australian rebrand of the iSaver inverter:
Madimack INVERTER PLUS.

I ended up using UART directly since there are only 2 registers worth accessing: writing the RPM (3001) and reading the current RPM (2001). AFAIK the ESPHome modbus implementation is incompatible with this non-standard modbus protocol. Even when ignoring the invalid CRC being returned, the function code of 0xC3 echoed back by the inverter is interpreted as an error because of this check here: esphome/esphome/components/modbus/modbus.cpp at f2249848585e98e532ae3d71d1df0a9f483a5a5c · esphome/esphome · GitHub.

Here’s the YAML i’ve come up with. It’s far from perfect - it will block the ESP for 150ms each time it reads / writes and the code is hardcoded and duplicated, but it works well enough in this limited case. I wouldn’t run anything else on the same ESP though. It will also ensure any RPM set below 1200 turns the pump off.

# Set up UART for the TTL485 controller
uart:
  tx_pin: GPIO17
  rx_pin: GPIO16
  baud_rate: 1200
  stop_bits: 1
  data_bits: 8
  parity: NONE
  id: modbus_uart
  debug:
    after:
      delimiter: "\n"

output:
  - platform: gpio
    pin: GPIO15
    id: modbus_write_enable

number:
  - platform: template
    name: "Pump RPM"
    id: pump_rpm
    min_value: 0
    max_value: 2900
    step: 1
    update_interval: 10s
    set_action:
      then:
        - lambda: |
            id(modbus_write_enable).turn_on();
            uint16_t rpm = (uint16_t)x;
            if (rpm < 1200) {
              rpm = 1;
            }
            uint8_t rpm0 = (rpm >> 8) & 0xFF;
            uint8_t rpm1 = rpm & 0xFF;
            uint8_t data[6] = {0xAA, 0xD0, 0x0B, 0xB9, rpm0, rpm1};
            uint16_t crc = 0xFFFF;
            for (int i = 0; i < 6; i++) {
              crc ^= data[i];
              for (int j = 0; j < 8; j++) {
                if (crc & 0x0001) {
                  crc >>= 1;
                  crc ^= 0xA001;
                } else {
                  crc >>= 1;
                }
              }
            }
            uint8_t crc0 = crc & 0xFF;
            uint8_t crc1 = (crc >> 8) & 0xFF;
            uint8_t packet[8] = {0xAA, 0xD0, 0x0B, 0xB9, rpm0, rpm1, crc0, crc1};
            auto uart = id(modbus_uart);
            uart->write_array(packet, 8);
            uart->flush();
            id(modbus_write_enable).turn_off();

    lambda: |
      id(modbus_write_enable).turn_on();
      uint8_t data[6] = {0xAA, 0xC3, 0x07, 0xD1, 0x00, 0x00};
      uint16_t crc = 0xFFFF;
      for (int i = 0; i < 6; i++) {
        crc ^= data[i];
        for (int j = 0; j < 8; j++) {
          if (crc & 0x0001) {
            crc >>= 1;
            crc ^= 0xA001;
          } else {
            crc >>= 1;
          }
        }
      }
      uint8_t crc0 = crc & 0xFF;
      uint8_t crc1 = (crc >> 8) & 0xFF;
      uint8_t packet[8] = {0xAA, 0xC3, 0x07, 0xD1, 0x00, 0x00, crc0, crc1};
      auto uart = id(modbus_uart);
      while(uart->available() > 0) {
        uint8_t t;
        uart->read_array(&t, 1);
      }
      uart->write_array(packet, 8);
      uart->flush();
      id(modbus_write_enable).turn_off();
      uint32_t start_time = millis();
      while (uart->available() < 8 && (millis() - start_time) < 200) {
        delay(1);
      }
      if (uart->available() >= 7) {
        uint8_t response[7];
        uart->read_array(response, 7);
        return (float)((uint16_t)response[5] << 8 | (uint16_t)response[6]);
      } else {
        return NAN;
      }
2 Likes