Using PCA9685 to control relays: unit defaults to On

So, I’m trying to use a PCA9685 board to control a bunch of relays. The actual application is a room with 3 separate light fixtures, and 2 ceiling fans. The relays will control the lights, but also the speed of the fans. 11 Relays total, and that’s not counting the pins I need for presence detection. But I’m hoping to do it all from one Wemos D1, because the PCA9685 provides 16 PWM outputs on an i2c interface, and you can turn them on and off instead of doing PWM.

Now, this works surprisingly well. Here is what my current test yaml looks like:

esphome:
  name: wem002
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: ""
  password: ""

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

i2c:
  sda: D2
  scl: D1
  scan: True

pca9685:
  - frequency: 500
    address: 0x40

output:
  - platform: pca9685
    id: 'pca_1'
    channel: 0
    inverted: true
  - platform: pca9685
    id: 'pca_2'
    channel: 1
    inverted: true
  - platform: pca9685
    id: 'pca_3'
    channel: 2
    inverted: true
  - platform: pca9685
    id: 'pca_4'
    channel: 3
    inverted: true

switch:
  - platform: template
    name: "Relay 1"
    optimistic: true
    turn_on_action:
      then:
        output.turn_on: pca_1
    turn_off_action:
      then:
        output.turn_off: pca_1
  - platform: template
    name: "Relay 2"
    optimistic: true
    turn_on_action:
      then:
        output.turn_on: pca_2
    turn_off_action:
      then:
        output.turn_off: pca_2
  - platform: template
    name: "Relay 3"
    optimistic: true
    turn_on_action:
      then:
        output.turn_on: pca_3
    turn_off_action:
      then:
        output.turn_off: pca_3
  - platform: template
    name: "Relay 4"
    optimistic: true
    turn_on_action:
      then:
        output.turn_on: pca_4
    turn_off_action:
      then:
        output.turn_off: pca_4

But there’s some weirdness. When power is applied to the PCA9685, all the relays turn on. You can then turn them off, but, they start turned on.

I tried adding an “on boot” statement to the esphome: section to turn all the relays off immediately, and that does work, but, they still click in for a fraction of a second first.

That’s a problem because of how I intend to control the fan speed. I took apart the manual control that comes with the fan, and it works by using capacitors and resistors in series to lower the voltage that arrives at the fan. I can duplicate that circuit on a board, but instead of using a manual switch, I’ll use relays to select which path the power should flow down. If the relay board boots up with all of the relays on, even for just a second, that’s not going to be great for the fan motor. It might foomp.

I toyed with the idea of just running it light that, and connecting my relays on the NC side. With the NO side engaged by default, the channels would only turn on with the relays were “off”. But then it occurred to me that whenever the D1 rebooted, or if it crashed, or whatever, such that the relays all disengaged at once … well that’d be bad too.

Can anyone think of a way to have these outputs not be high by default? I have a feeling that it’s something to do with the output: section but I am a bear of very little brain and large words confuse me.

Are you using common relay board? Link please.

It will be great if you can wire the relay outputs in such a way you can only power one thing only, e g if you have three buttons you need 3 relays. The first relay has common and normally open (NO) output goes no where and NC goes to the common of the next relay then second relay NO goes to speed 1 and NC goes to 3rd relay and then 1 output goes to speed 2 and the other goes to speed 3.

Then you can figure out which outputs you need for each speed, but you’ll never mess up.

Next will be figuring out the electronics, I’ll wait your feedback

Perhaps an esp32, which has easily enough outputs, and a 16 relay board, would be a better fit.

@glmnet The relay boards I am using look very much like this. They are 5V relays with isolation of the electromagnet.

I’m struggling to follow you a little bit. You seem to be describing a 3-way (or 4-way) switch wiring, such as might be used when having multiple switches control one lightbulb. It’s a very interesting idea! If it’s not too much trouble, could you draw a quick sketch of the wiring you described? I am struggling to follow your text, a bit. I tried to draw it based on your instructions and I got lost.

Is what you are describing like this?

@nickrout, I agree, an ESP32 would be excellent!

But, if possible, I would like to do this with the hardware I already have. The Adafruit documentation for this PCA9685 board gives examples of how the PWM pins can be turned fully on and fully off, so I would like to figure out how to do that cleanly in ESPHome, if possible. I do accept that maybe it’s not possible, but I would like to try.

Also I am cheap.


OFF - X - X -> OFF
ON - OFF - X -> Output 1
ON - ON - OFF -> Output 2
ON - ON - ON -> Output 3

When I put X, it really does not mater.
In any condition only one output is connected to the input.

Now lets talk about this board.
You’ll notice that you have to configure the outputs as inverted, that’s because the board turns on the relay when the board inputs is sinked to 0V, e.g. a path to 0V exists.
For the relay to be turned on: connect pin to 0V, for the relay to turn off, either connect the pin to +3.3v or let it float.
May be the PCA9685 sinks the outputs at power on, if that cannot be changed (a lookup on the datasheet) then you’ll need to add an inverter hardware in between, which makes this approach not very sexy at all, I’ll consider @nickrout ESP32 idea a good option.

I’d like to share my personal case: I use this boards a lot with esp8266 and ESPHome and I am using slaved arduino pro mini as port expander. I have at least 8 of these boards running at home. Plus with an Arduino you can also have additional inputs too. I can share that if you need it.

Can I just clarify something? Is the setup

Esp—pca9685—relay board—mains?

With an esp32 you could cut out one stage

Esp32—relay board—mains.

I understand the desire to be cheap. Hell thats why we aren’t all using control4 :smile:

@glmnet That’s beautiful. Thank you so much! Yes, that will effectively solve my problem. Wonderful!

I am slowly learning about these 9685 boards ever since you suggested it for my stair lights project (which is still in the works, I’m waiting for decent pricing on 10mm aluminium angle channel that I need to hide the LEDs). Please do share any info you may have on how to use a 9685 as inputs, here or elsewhere.

@nickrout that’s a fair point, I do concede that it’d also be simpler.

I’m using interlock for the solenoid valves so two of them can’t be turned on in the same time. There is also an automation in the example so the power adapter is only on when a solenoid is on.

switch:
  - platform: gpio
    name: "Sprinklers Backyard"
    icon: "mdi:water-pump"
    restore_mode: ALWAYS_OFF
    id: prskalkipozadi
    pin: 
      number: GPIO0
      inverted: yes
    interlock: [prskalkistrana, prskalkinapred]
    on_turn_on:
      then: 
        - switch.turn_on: dvornapajanjeprskalki
    on_turn_off:
      then: 
        - switch.turn_off: dvornapajanjeprskalki
  - platform: gpio
    name: "Sprinklers side"
    icon: "mdi:water-pump"
    restore_mode: ALWAYS_OFF
    id: prskalkistrana
    pin:
      number: GPIO13
      inverted: yes
    interlock: [prskalkipozadi, prskalkinapred]
    on_turn_on:
      then: 
        - switch.turn_on: dvornapajanjeprskalki
    on_turn_off:
      then: 
        - switch.turn_off: dvornapajanjeprskalki
  - platform: gpio
    name: "Sprinklers front"
    icon: "mdi:water-pump"
    restore_mode: ALWAYS_OFF
    id: prskalkinapred
    pin: 
      number: GPIO16
      inverted: yes
    interlock: [prskalkipozadi, prskalkistrana]
    on_turn_on:
      then: 
        - switch.turn_on: dvornapajanjeprskalki
    on_turn_off:
      then: 
        - switch.turn_off: dvornapajanjeprskalki
  - platform: gpio
    name: "24VAC Power supply"
    icon: "mdi:power"
    id: dvornapajanjeprskalki
    restore_mode: ALWAYS_OFF
    pin:
      number: GPIO4
      inverted: yes

I’m using PCA9685 only for the PWM function, right now for dimming leds. For switch PCF8574 is better extender.

1 Like

@gocenik, thank you for mentioning PCF8574! something new to check out. I agree that it looks more appropriate for this task than PCA9685, and I will definitely grab some next time I have money.

The interlock would also be a good idea for me, especially with the ceiling fans - thank you for sharing your yaml!

My main problem with this project is that the relays all turn on when power goes on. I turn them off again immediately with on boot: section, but it happens before the interlock code would run. PCF8574 would fix this, for sure, but, I use what I have.

@gocenik, is PCF8574 supported in ESPHome? It’s I2C, so, the interface is sort of there. Have you used it in ESPHome? And if you have, would you mind sharing the yaml so I could see how? Thank you.

Come on you do realise that esphome is documented, and the PCF8574 is on the front page https://esphome.io/components/pcf8574.html

I missed it, because I was looking in the wrong section: I was looking in Output Components. Thanks for pointing me in the right direction.

That’s good :slight_smile:
I see there is a 16 pin version too, may be just the job for you.