How to share hardwired signals between two ESPHome modules?

Thanks for the link to the Lambda Magic. I’m aware of Lambda, but I had not seen that site. I’m quite new to create my own ESPHome code.

Yes, UART was my first thought too, but I wanted to ask an open question in case there is some clever function I don’t know about. ESPome have all kind of weird & wonderful things already built in! :slightly_smiling_face:

But with UART it’s easy to add a RS232 level shifter circuit like MAX232 on each side to add some more robustness to the signal and avoid exposing the ESP32 I/O directly to the environment.
For “error correction” it will probably be enough here to go at low speed and just send the data maybe three times and only accept it if all three are the same.

A simple “protocol” maybe can be something like:

  1. Send all data three times in one stream
  2. Wait for the other node to respond with the same data to confirm
  3. If the responded data is wrong, resend the correct data again
  4. Stop retrying and rise an alarm if the respond is wrong five times in a row

Anyone that has done something similar and is willing to share some code? :wink:

Did you look into just having one esp and say long wire runs to the greenhouse sensors from the pump one? Not sure how feasible that is and guessing you’ve thought about it but curious if/how that was knocked out.

Quick search…

To be honest, I’d put wireless and long-wires-in-a-wet-environment on the same level as far as expected reliability… To improve wireless reliability, I’d just put a cheapo dedicated router for that purpose.

Keep in mind that pure wired also implies hardwiring a way to upload firmware updates, no logging, … (unless you keep wireless for “non-essential” functions like this).

One ESP is of course the easiest way and something I have considered, but it will have some drawbacks in my opinion.

  1. As I will have sensors in both the greenhouse (temp, moister, light humidity…) and in the pump (water level, critical low level, leakage…) I’m facing similar problems with long sensor cables regardless where I place the ESP.
  2. One ESP will make it harder to add more sensors at the “wrong” place later on as more cables likely has to be installed.
  3. As the functions of the systems are very different (pump control vs evaluating environment sensors) I think it can be easier to develop, test, and maintenance if it is separate systems.

My experience is that a proper installed hardwired connection hardly never can beat wireless. Well ok, maybe hardwire isn’t the best chose for space flights then… :stuck_out_tongue_winking_eye:

However, as it looks like there is no easy “of the shelf” solution to handle hardwired signals between two ESPHome I’m starting to thinking on a plan B for wireless, at least to start with:

Problem 1: Flooding
The biggest fear is that the stop/shut off command not will be received and causing a flooded greenhouse.

Solution 1: Hart beat
This can probably be handled in a way where the “pump ESP” only open the water valve for a short time. That means the “greenhouse ESP” must resend that trigger as long it’s requesting for more water. This will acting like a hart beat / watchdog and stop the water if the signal for some reason is lost.

Problem 2: Drying / HA down
I will have the automations local in the ESP not being dependent of Home Assistant running.
Is it possible for two ESPHome nodes to communicate and trig the water “hart beat” if HA is down but wifi is up?

Never used it myself, but ESPHome has a “web server” component that does just that

together with “http request”, I guess

That web server solution looks interesting, but I’m afraid that may me a little over my head to master, at least for the moment.

Thinking this over a little more during some grass cutting the last hours I may have a solution that hopefully will be both quite easy and reliably enough for my needs:

  1. Two ESP as discussed above, one for the pump and one for the greenhouse.
  2. Connect the two ESP trough UART and MAX232 level shifters.
  3. Use the UART Switch and Lambda Magic Custom UART Switch to send and receive the “valve open hart beat signal” witch will open the water valve for a short time, and close it again if a new hart beat is not received.
  4. More signals should be possible add through UART the same way if needed, and the text sensor is probably reliable and fault tolerant enough for this purpose as the received string is a couple of bytes that must mach exactly to flip the switch.
  5. All other kind of “non critical / for fun” signals can be handeld wireless.

For now I think this will be the way I go, at least to start with.
Any obvious thought errors?

Honestly, if that’s over your head, UART will be worse :wink:

As both ESP will have the same logic, I don’t think you need the level shifter, but that’s a bit above my head :wink:

I’m not that deep into this new fancy web rubbish. I’ll stick to an good old trusted UART, like I used to in the -90s! :stuck_out_tongue_winking_eye:

Well to be honest, it feels like a web server is a little to much and komplex for my needs, but I can be wrong. Could be worth to have a look at.

However, I will start with the UART trace as that (hopefully) will give me a system with both robustness and some flexibility where the core functions are working regardless of wifi, HA or any other surrounding systems, as long as I have 230VAC power.

You are absolutely right about that the level shifters are not needed from a signal level aspect, but it is not wise, and not a common praxis, to expose the “naked” I/Os to the world. Especially if the wires are long, like they will be in my case, the risk is quite high that the sensitive, high impedance 3,3V inputs will pick up some noise that can interfere or block the signal, or worse be destroyed by some electro static discharge (ESD).

Those risks can be reduced by using the MAX232 level shifter as they will boost the signal several volts (to RS232 level) and bring some basic ESD protection to it as well.
Not needed in theory or on the bench, but probably nearly a “must have” in the real world. :blush:

2 Likes

Are you comfortable with reading uart in ESPHOME? It’s a bit more involved than writing it.

Nope, not at all. :grin:
But until I know better I believe that the Magic Lambda Custom UART Switch example will do pretty much what I want - I hope!
As long as the interrupt pick up the receiving message and i don’t overflow the input buffer, I think it will be pretty straight forward.
We’ll find out… :stuck_out_tongue_winking_eye:

Whats the hard part in your opinion?

If you’re comfortable with the custom sensor approach you should be fine. c++ scares me.

There’s this kind of thing too, which gives a good overview of the challenge and an alternative. I tend to use this approach to read uart.

That’s looks interesting. I may give that a try as well.

If you would make an effort to read the documentation, you’d quickly realize its not rubbish at all and it’s very simple to use.

Yes, now when I have a solution that I believe is right for my purpose, I will dig down deeper into the documentation and do some testing.

1 Like

Your plan re uart and max232’s will work just fine. I’ve done exactly this and it works fine over long runs that I’ve tested up to a few hundred feet.

1 Like

Yes, correct used RS232 is a fairly reliable and easy communication over reasonable distances.

How did you implement the readings?

@Pjoms it’s probably not be best/cleanest implementation but here’s a snippet of one of the switches on the receiver side:

- platform: template
  id: text_switch_z2
  name: "Text Switch 2"
  lambda: |-
    if (id(uart_readline).state == "1-Z2-ON") {
      id(relay2).turn_on();
      return true;
    } else if(id(uart_readline).state == "1-Z2-OFF") {
      id(relay2).turn_off();
      return false;
    } else {
      return {};
    }

I think I´m on something here that can have the potential to work.
This is what I have done:

  • The “Custom UART Text Sensor” example is taken stight off from Lambda Magic
  • I replaced the “Custom UART Switch” with a own variant of a binary sensor, using the “delayed_off” for the heartbeat.function.

The function is:

  • If the right string is recievd by the UART the output will turn on for 5s and then turn off
  • If the right string is recievd again within 5s the output will remain on
  • The flag “b_prohibit” allows the output to only be set once and clears the “uart_readline” textsensor, forcing a new string to be recieved to keep the output enabled.
  • If the string is sent once per second it can lose up to 4 of 5 strings and still work, and will stop within 5s if the string is stuck or lost.
  • The if statement “if (id(uart_readline).state == “OPEN_VALVE_1”)” can be extended with an or statement ( || ) to allow different triggers if needed.
  • I’m using "uart.write: “Water ON” and “OFF” for testing so far instead of digital outputs.

I have just tested this a little on the bench, but so far it looks good!

binary_sensor:
  - platform: template
    id: water_valve1
    name: "Water Valve 1"
    lambda: |-
      static bool b_prohibit = false;
      if (id(uart_readline).state == "OPEN_VALVE_1") {
        if (b_prohibit == false) {
          id(uart_readline).publish_state("");
          b_prohibit = true;
          return true;
        } else {
          return false;
        }
      } else {
        b_prohibit = false;
        return false;
      }
    filters:
      - delayed_off: 5s
    on_press:
      then:
        - uart.write: "Water ON\n"
    on_release:
      then:
        - uart.write: "Water OFF\n"

Canbus works very well if you get the transceiver to support it. I have multiple nodes using wires to communicate.