ESPHome and Centurion D5

RoganDawes

Expert Member
Joined
Apr 18, 2007
Messages
1,444
Reaction score
150
Location
Randburg
I created an ESPHome-based controller for my automatic gate.

It is a Centurion D5, and has a number of terminals via which one can interact with the gate's controller. Included are Free Exit (for inductive loops to trigger opening), Pedestrian (opens the gate enough for a pedestrian to pass through, then closes it a few seconds later), and Trigger (steps through a state machine with each momentary activation - closed - opening - open - closing - closed). There is also an LED that flashes various patterns to provide state information. Off for Closed, slow flashing for opening, On for open, fast flashing for closing. And it can report errors with a pattern of 250ms flashes followed by 2500ms off, repeated.

I see a lot of posts where people use relay boards to switch 12v signals to triggers gates and garage doors, but a much smaller alternative is an optoisolator. This is basically a combination of a transistor and an LED, where activating the LED switches the transistor, allowing a small amount of current to flow in the 12V circuit, and registering as closing the circuit, exactly as would a relay. So, my circuit used 3 optoisolators on output GPIOs to activate the various signals, as well as one on an input gpio to convert the 4.5V LED signal to something that the ESP32 could safely consume.

1760688387152.png1760688397306.png

To keep the board as compact as possible, I actually soldered the optos underneath the ESP32 dev board. You can see how the ESP32 is mounted on pins that have two spacers added instead of the usual one. If I were to make this a professional installation, I would likely make use of a bare module on a PCB, but this was good enough for a 1 day project.

I have attached the YAML (as a txt file), for those that are interested in replicating this.
 

Attachments

Last edited:
Hello can you please provide me a list of components what you have use. Am new to this and will like to build a board link this for my gate.

Tanks
 
can’t recall the part number for the opto isolators that I used, but I think they were KB817. The 12-5V step down converter is a module I got off Aliexpress for less than $1. But I’m sure you can find something similar locally. And the ESP32 is just a dev board I got from Communica locally.
 
Sorry, that discord thread does not open for me.

Can you help me, step by step how to get the status of a gate motor?

Here is my ESPHome YAML.

The key thing is that you monitor the flash of the status LED, and can determine what the gate is doing by analysing the interval between the flashes. Short flashes when the gate is closing, slow flashes when the gate is opening, on when the gate is stopped open, off when the gate is stopped closed. I run a restartable script every time the state of the LED changes, with a timeout of 3 seconds, so that after 3 seconds of no change, the gate will be assumed to have stopped moving, and the state of the gate can be derived from the LED's current state. Of course, if the gate is moving, the script will be restarted continuously as the LED flashes, and the gate state will be updated as opening or closing depending on the interval between flashes.

Note that as the gate starts or stops moving, the flash rate also stretches out, to as much as 2 seconds, which is why there is a 3 second timeout on the script, and a 2.5 second timeout on the interval calculations.
 

Attachments

I did the same for my Centurion D5 Evo. Originally got the idea from this thread on EnergyTalk
With lots of trial and error I ended up with this which works really well, although I haven't really tested all the different blink states. Open, Closed, Opening, Closing and No Mains work well and they are all I need for now. Didn't want to go through more effort to test Low Battery and Pillar Light.
I used some ESP32 WROOM boards that I got from AliExplress.
 
I updated my config to follow @wernerhp 's approach, using the multi-click. I also separated the detection of the LED flash timing from the sensor handling the multi-click, so that I could add logging of the actual timing of the flashes. Additionally, I "optimised" the detection of the opening of the gate, as it was taking as much as 8.5 seconds to detect the transition from closed to opening!

This is what the relevant bits look like now:

Code:
binary_sensor:
# attached to the status LED via an opto
  - platform: gpio
    pin:
      number: GPIO21
      mode: input_pullup
      inverted: true
    id: led
    internal: true
    entity_category: diagnostic
    icon: mdi:led-outline
    disabled_by_default: true
    publish_initial_state: true
    on_state:
      - then:
        - lambda: |-
            static uint32_t last_change = 0;
            static uint32_t opening = 0;
            auto now = millis();
            if (last_change > 0) {
               uint32_t elapsed = now - last_change;
               ESP_LOGI("main", "LED %s for %dms", x ? "OFF" : "ON", now - last_change);
               if (elapsed > 2000 && x) {
                 opening = now;
               }
               if (opening > 0 && id(gate).current_operation == CoverOperation::COVER_OPERATION_OPENING) {
                 ESP_LOGI("main", "Detected gate opening after %dms", now - opening);
                 opening = 0;
               }
            }
            last_change = now;

  # We use a copy binary_sensor to allow debugging the timing in the primary sensor,
  # without messing with the filters in this copy sensor
  - platform: copy
    source_id: led
    internal: true
    id: copy_led
    entity_category: diagnostic
    icon: mdi:led-outline
    disabled_by_default: true
    filters:
      - delayed_on_off: 50ms
    on_multi_click:
      - timing: # Opening - initial long flash after long OFF is during initial acceleration
          - OFF for at least 500ms
          - ON for 1500ms to 2200ms
          - OFF for 250ms to 550ms
        then:
          - text_sensor.template.publish:
              id: status
              state: "Opening"
          - lambda: |-
              id(gate).current_operation = CoverOperation::COVER_OPERATION_OPENING;
              id(gate).publish_state();
        invalid_cooldown: 50ms

With these changes, I get the gate opening detected within less than 3 seconds, which is a nice improvement! The rest of the multi_client timings can be optimised in a similar way.

Note that the measurement of the timing of how long it took to detect the gate opening measures the time from the start of the first flash until the first transition AFTER the multi-click has triggered, and is purely diagnostic. The lambda on the original sensor can be disabled entirely without affecting anything.
 
BTW, I'm also working on a revision of this controller that can detect the pulses from the DOSS optical sensor as the gate is moving, which will let me know how far open the gate is, as well as the instant it starts moving. That doesn't give you direction, unfortunately, so I am also looking at monitoring the voltage to the motor to determine whether it is positive or negative (i.e. direction that the motor is turning).

At which point the multi-click games can be reserved for homing (OFF implies closed ie position 0), and error conditions.

I just wish there was better control over what the motor does, than just "Open - stop - close - stop" on a single pin (recognizing that "Free Exit" FRX does let you choose Open at any time).
 
Top
Sign up to the MyBroadband newsletter
X