esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
294 stars 37 forks source link

esp32 LEDC with OUTPUT_OPEN_DRAIN #1975

Closed osresearch closed 2 years ago

osresearch commented 3 years ago

Operating environment/Installation (Hass.io/Docker/pip/etc.):

esphome 1.16.2 installed via pip3 on ubuntu 20.04

ESP (ESP32/ESP8266, Board/Sonoff):

esp32cam board

ESPHome version (latest production, beta, dev branch)

1.16.2

Affected component:

ledc

Description of problem:

The ledc component switches the pin mode to output, so a pin configured as OUTPUT_OPEN_DRAIN will not behave correctly. When used as a binary lamp, this works fine for turning on and off an external MOSFET:

output:
  - platform: gpio
    id: lamp
    inverted: True
    pin:
      number: GPIO3
      mode: OUTPUT_OPEN_DRAIN

light:
  - platform: binary
    output: lamp
    name: "lamp"

However, when it is switch to use the ledc output platform the pin is switched back to OUTPUT and the dimming does not work correctly. The problem might be in the underlying call to ledcAttachPin(), as discussed here: https://esp32.com/viewtopic.php?t=15783

void ledcAttachPin(uint8_t pin, uint8_t chan)
{
    if(chan > 15) {
        return;
    }
    pinMode(pin, OUTPUT);
    pinMatrixOutAttach(pin, ((chan/8)?LEDC_LS_SIG_OUT0_IDX:LEDC_HS_SIG_OUT0_IDX) + (chan%8), false, false);
}

I can add a lambda that switches it to open drain when turning the lamp on, and this works for dimming, but is unable to turn the lamp off. I thought perhaps adding an explicit switch back to input mode would work, but that leaves it in a flickering state.

output:
  - platform: ledc
    id: lamp_pwm
    inverted: True
    pin:
      number: GPIO3
      mode: OUTPUT_OPEN_DRAIN

light:
  - platform: monochromatic
    output: lamp_pwm
    name: "lamp"
    on_turn_on:
      - lambda: pinMode(3, OUTPUT_OPEN_DRAIN);
    on_turn_off:
      - lambda: pinMode(3, INPUT);

Problem-relevant YAML-configuration entries:

esphome:
  name: bigswitch
  platform: ESP32
  board: esp32cam

wifi:
  ssid: "xyzzy"
  password: "password"

# Enable logging on the second uart, leaving RX=GPIO3 free
# for the PWM to the big switch LEDs
logger:
  hardware_uart: UART2

# Do NOT Enable Home Assistant API
#api:

# talk to mqtt broker for grafana updates
mqtt:
  broker: dashboard

ota:

output:
  - platform: ledc
    id: lamp_pwm
    inverted: True
    pin:
      number: GPIO3
      mode: OUTPUT_OPEN_DRAIN

light:
  - platform: monochromatic
    output: lamp_pwm
    name: "lamp"
    on_turn_on:
      - lambda: pinMode(3, OUTPUT_OPEN_DRAIN);
    on_turn_off:
      - lambda: pinMode(3, INPUT); digitalWrite(3, 0);

Logs (if applicable):

PASTE DEBUG LOG HERE

Additional information and things you've tried:

ssieb commented 3 years ago

Why do you need open drain for a mosfet? When you switch the pin to INPUT, the mosfet gate will be floating.

intermittech commented 3 years ago

I'm confused, why would you need open-drain for driving a MOSFET? I run lots of ESPhome lights using ESP32's and use the following:

output:

light:

This works perfectly as is with the correct MOSFETs (and/or MOSFET gate drivers). It allows for on/off, dimming, etc.. You should not be doing any lambda or pin mode switching?

Maybe I'm missing something, try my code. :)

osresearch commented 3 years ago

image

I'm interfacing the ESP with an existing device: a big-switch shaped nightlight with a binary tilt sensor and several high power LEDs that are low-side switched via an open-collector MOSFET. The original design had the tilt sensor wired directly to the MOSFET and ground. In one orientation the sensor let' the pin float, which turns off the LEDs; in the other orientation it shorts the pin to ground and turns on the LEDs When the ESP drives the pin to 3.3v in the normal PWM mode, it causes the MOSFET to not turn off all the way so it doesn't dim.

intermittech commented 3 years ago

But then why not connect the "switch" to a binary input (add a pull-high to 3.3v so you always have a defined state) and then use that as the digital signal to drive the MOSFET connected to the ESP32 board. So transforming the switch input to a logical on/off signal and then driving the MOSFET the regular way, no open-drain or floating ways used.

That would solve all problems I'd think?

github-actions[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.