ESP32 - 2 UART and 1-Wire does not working

Hi, I am using an Astra Controller: https://rocketcontroller.com/product/astra-controller-4-relays-16a-8-gpio-input-dc-power-led-br4g8al/ for my Pool Management.

I have added DS18B20 on GPIO13 and 2 Uart Devices. One PZEM and one Max485 to get Data from my inverter.

All of there deviceses are running well, if they are connected alone on the ESP.
But, if the Max485 is connected and get Data from the inverter, the 1-Wire Bus does not work anymore. I can’t control the inverter via Home Assistant either. to do so, I would first have to disconnect the 1-Wire bus. After stopping the inverter, the DS18B20 is reachable.

esphome:
  name: poolsteuerung
  friendly_name: Poolsteuerung

esp32:
  board: esp32dev
  framework:
    type: esp-idf

# Enable logging
logger:
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

ota:
  - platform: esphome
    password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid_smarthome
  password: !secret wifi_password_smarthome
  manual_ip:
    # Set this to the IP of the ESP
    static_ip: xxx.xxx.xxx.xxx
    # Set this to the IP address of the router. Often ends with .1
    gateway: xxx.xxx.xxx.xxx
    # The subnet of the network. 255.255.255.0 works for most home networks.
    subnet: 255.255.255.0
  reboot_timeout: 60s
  power_save_mode: none

#captive_portal:

# An der RS / SPI (RJ12) Buchse sind folgende GPIOs vorhanden von Links nach Rechts
# (not connected)
# GPIO18
# GPIO16
# GPIO17
# GND
# 5V

# An der I2C (RJ12) Buchse sind folgende GPIOs vorhanden von Links nach Rechts
# (not connected)
# GPIO2
# GPIO22
# GPIO21
# GND
# 5V

output:
  - platform: ledc
    pin: GPIO12
    id: rtttl_out
  - platform: gpio
    pin: GPIO18
    id: uart_isaver_write_enable

rtttl:
  output: rtttl_out
    
status_led:
  pin:
    number: GPIO4
    inverted: true

switch:
  - platform: restart
    name: "Neustarten"
  # - platform: gpio
  #   name: "Relay 1"
  #   pin: 25
  #   id: relay1
  # - platform: gpio
  #   name: "Poolpumpe"
  #   pin: 26
  #   id: relay2
  # - platform: gpio
  #   name: "Relay 3"
  #   pin: 33
  #   id: relay3
  # - platform: gpio
  #   name: "Relay 4"
  #   pin: 32
  #   id: relay4
  - platform: template
    name: "iSaver einschalten"
    id: pump_power
    optimistic: true
    turn_on_action:
      - lambda: |-
          id(pump_rpm).make_call().set_value(2100).perform();
    # Auskommentiert, da es beim Neustart immer ausgeführt wird
    # turn_off_action:
    #   - lambda: |-
    #       id(pump_rpm).make_call().set_value(0).perform();

one_wire:
  - platform: gpio
    pin: GPIO13

uart:
- id: uart_strommesser
  rx_pin: GPIO15
  tx_pin: GPIO27
  baud_rate: 9600
- id: uart_isaver
  tx_pin: GPIO17
  rx_pin: GPIO16
  baud_rate: 1200
  stop_bits: 1
  data_bits: 8
  parity: NONE
  debug:
    after:
      delimiter: "\n"

modbus:
  id: mod_bus_pzem
  uart_id: uart_strommesser

modbus_controller:
  - id: pzem
    address: 0x1
    modbus_id: mod_bus_pzem
    command_throttle: 0ms
    setup_priority: -10
    update_interval: 30s

sensor:
  - platform: wifi_signal
    name: "WiFi Signal dB"
    update_interval: 10s
  - platform: internal_temperature
    name: "Internal Temperature"
  - platform: dallas_temp
    address: 0x11e516be0164ff28
    name: "Pooltemperatur"
  - platform: pzemac
    current:
      name: "Poolpumpe Stromstärke (A)"
    energy:
      name: "Poolpumpe Energie (Wh)"
    power:
      name: "Poolpumpe Leistung (W)"
    power_factor:
      name: "Poolpumpe Power Factor"
    frequency:
      name: "Poolhütte Frequenz"
    voltage:
      name: "Poolhütte Spannung"
    update_interval: 5s
  - platform: template
    name: "Aktuelle Poolpumpen Drehzahl"
    id: pump_rpm_state
    unit_of_measurement: "RPM"
    accuracy_decimals: 0
    update_interval: never
    force_update: false
    
# Für iSaver Drehzahl Start


number:
  - platform: template
    name: "Pumpendrehzahl"
    id: pump_rpm
    min_value: 0
    max_value: 2900
    step: 1
    set_action:
      then:
        - lambda: |
            id(uart_isaver_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(uart_isaver);
            uart->write_array(packet, 8);
            uart->flush();
            id(uart_isaver_write_enable).turn_off();

interval:
  - interval: 1s
    then:
      - lambda: |-
          id(uart_isaver_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(uart_isaver);
          while(uart->available() > 0) {
            uint8_t t;
            uart->read_array(&t, 1);
          }
          uart->write_array(packet, 8);
          uart->flush();
          id(uart_isaver_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);
            id(isaver_status).publish_state("Online");
            float value = (float)((uint16_t)response[5] << 8 | (uint16_t)response[6]);
            if (value != id(pump_rpm_state).state) {
              id(pump_rpm_state).publish_state(value);
              id(pump_rpm).publish_state(value);
              id(pump_power).publish_state((value > 0));
            }
          } else {
            id(isaver_status).publish_state("No Response");
          }

text_sensor:
  - platform: template
    name: "iSaver Status"
    id: isaver_status

button:
  - platform: template
    name: "Poolpumpe ECO"
    on_press:
      - lambda: |-
          id(pump_rpm).make_call().set_value(1350).perform();

  - platform: template
    name: "Poolpumpe NORMAL"
    on_press:
      - lambda: |-
          id(pump_rpm).make_call().set_value(1700).perform();

  - platform: template
    name: "Poolpumpe MAX"
    on_press:
      - lambda: |-
          id(pump_rpm).make_call().set_value(2900).perform();

# Für iSaver Drehzahl Ende

So what you get on esphome log?

Also, be aware that Esp32 is 3.3V MCU. So pullup for temp sensor has to be on 3.3V and you need to power MAX485 board at 3.3V if you don’t use level shifter on serial line.
Also, while not related to your misbehavior, try to avoid using strapping pins (like 12 and 15)

Hi, thank you for your reply.

This is the error after next 1-Wire request, if the max485 get data:

[13:08:44][W][dallas.temp.sensor:074]: 'Pooltemperatur' - reading scratch pad failed bus reset
[13:08:44][W][component:157]: Component dallas_temp.sensor set Warning flag: bus reset failed

After shutting down the pool inverter, 1-Wire is still working well.

I also saw, that the esp sometimes reboot, during the max485 getting data.

It’s just incomprehensible to me, since each of the three devices (1-Wire, PZEM, Max485) runs flawlessly on its own. And the PZEM NEVER causes any problems.

The ESP doesn’t care whether the voltage is 5V or 3.3V. The behavior is the same for both.

Thanks for the info I will try to figure it out for more PikePass

It’s kind of hard to understand your code.
The modbus controller (id: pzem) is not used anywhere on your code, there is no sensor or other components using it. So what is the Max485 supposed to do here?

How is your temp sensor pullup?

I disagree.

Sure, the pzem is using in the sourcecode

sensor:
  - platform: pzemac
    current:
      name: "Poolpumpe Stromstärke (A)"
    energy:
      name: "Poolpumpe Energie (Wh)"
    power:
      name: "Poolpumpe Leistung (W)"
    power_factor:
      name: "Poolpumpe Power Factor"
    frequency:
      name: "Poolhütte Frequenz"
    voltage:
      name: "Poolhütte Spannung"
    update_interval: 5s

Temperature-Pullup is a 4K7 Resistor.

I hope you have a substantial replacement stock because the ESP is very definitely voltage sensitive.

1 Like

Pzemac sensor is using modbus component, not modbus_controller component.

And if you use modebus_controller to change the sensor address, you need to remove it after.

Now I have changed all to 3.3V and removed the modbus_controller part. I have changed the Resistor on the DS18B20 from 4k7 to 500Ohm. With the 4K7 resistor it didn’t work at the low voltage due to the cable length.

pzem still working well in all Situations. 1-Wire does not work, until I start the inverter

I have changed the update interval from 1-Wire to 5Seconds. Maybe all 4 times, I got the correct Temperature.

FYI: For testing, I have now removed all the parts for the Max485, but problem with the 1-Wire is still there.

500R is too low, switch it to 2.2K.
Is the long cable running together with some power cables?
Maybe your problem is not esphome related, but interferences?

1 Like

Okay, I will do it later. But this is not the Problem.

The Long cable is next to an 220V cable. It is an J-YSTY 4x2x0,6 mm² shield Cable.

But 1-Wire works great as long as the inverter is off. Max485 is active even while the inverter is off, regularly sending 0RPM.

That’s what I meant, interferences from inverter…?

The Inverter is on another power circuit. The Cable is not near of the ESP or 1-Wire cable.

It can still give interferences to that mains cable running together with sensor cable.
What is this “inverter”? PV inverter? Motor inverter?

Since you are sure that is NOT the problem (despite the resistance being so low it is likely outside the spec, but might still work sometimes) you might find this issue enlightening:

Your setup is clearly showing a problem. Do you have a logic analyzer, or even better an oscilloscope? Capture some traces, that will likely narrow down where the problem is.

This is a really good article on how to do long distance right. I have found for shorter distances you generally don’t have to do too much to get good results. When you are having problems, you have to eliminate things that could be causing the problem, until you find the one (or more) that is/are causing the problem.

Back from the Garden.

Maybe you are right.

I have changed the Cable to Cat7 and changed the Resistor to 2k2.

It feels like, that the 1-Wire is more robust and now sometimes I can manage the inverter.

The inverter is this one: https://www.heatpumps4pools.com/myfiles/file/iSAVER-Frequency-Inverter-Instructions.pdf

Tomorrow I can continue testing. Now its too dark outside :wink:

If you have shielded cable, ground the shield on esp end.

Good Morning,

next tries today. I have put the shield to PE. No Improvement.

Removed the Shield from PE back and removed Max485 from ESP. 1-Wire is working well, even the inverter is running.

Is it possible that the interference is being transmitted via the RS485?

What’s the difference here exactly?