0
\$\begingroup\$

I am trying to detect a power toggle event for a smart lamp I am building. Essentially, I want the lamp to behave differently when turned on after a long off period compared to when toggled on/off/on. I want to use a simple RC circuit to achieve this.

I am using an esp32-wroom-32d. R=80k, C=10u

RC Circuit

To test, I can set IO13 output HIGH to charge the capacitor and then set IO13 to analog input mode to read the discharge of the capacitor. The readings look as follows (blue=expected, red=actual readings):

ADC measurements

This looks as expected, and shows that I will have a couple seconds to make an analog reading at boot to detect a power toggle. If I read 0V then I know the power has been off for a long period, and if I read >0V then I know the power has toggled in the last few seconds. See sample code below.

from machine import Pin, ADC
import time

D7 = 13
LED = 2 # D9

adc_pin = Pin(D7, Pin.IN, Pin.OPEN_DRAIN)
adc_pin.value(1) # set high Z open drain

led = Pin(LED, Pin.OUT)

def boot():
    rc_V = read_rc()

    # R = 83k, C = 10u, tau = 0.8sec
    if rc_V > 0.5: # was on very recently
        led.value(1)
    else:
        led.value(0)

# read RC, then set the pin high to begin recharging the RC for the next power on/off event
def read_rc():
    adc_pin = Pin(D7, Pin.IN, Pin.OPEN_DRAIN)
    adc_pin.value(1) # set high Z open drain
    adc = ADC(adc_pin)
    adc.atten(ADC.ATTN_11DB) # attenuation for esp32
    rc_V = 3.3*adc.read()/4096
    print(rc_V)

    adc = Pin(D7, Pin.OUT)
    adc.value(1) # reset adc pin high so it can begin recharching the RC circuit
    return rc_V

If I call read_rc() a few seconds after booting the voltage measured is around 3.3V, as expected. At this point, if I toggle the power to the board off/on very quickly, I expect to see a >0V reading, however it reads 0V. Why is this? Why does the RC circuit drain so quickly when the board is off? How can I get this RC circuit to drain at the expected rate?

I'm curious to the underlying mechanism behind this behavior in the mcu (what state is the GPIO during power off?), so please do discuss.

Ultimately, I need a simple solution to allow the mcu to "remember" recent power toggles.

Thanks

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Comment rather than answer as just speculation - It sounds like the pin goes low impedance to low voltage when off. It should at least go a 'protection diode drop' to low voltage when off. Put a resistor, say 10k, in series with the pin, which will slow discharge. Or put a diode in series, which will prevent back discharge via the pin at all. \$\endgroup\$
    – Neil_UK
    Commented Apr 24, 2023 at 10:41
  • \$\begingroup\$ Have you made measurements of the pin (with an external voltmeter) while you turn it off? \$\endgroup\$
    – jonathanjo
    Commented Apr 24, 2023 at 10:47
  • \$\begingroup\$ If you have to change the pin output setting, it seems reasonable to assume this is the problem. If the pin is low impedance on startup, even for the few ms it takes to boot and set it to high Z, this could be enough to discharge the cap. If you have a scope you could look at the pin during power cycling. \$\endgroup\$
    – LordTeddy
    Commented Apr 24, 2023 at 11:08
  • \$\begingroup\$ Why are you using Pin.OPEN_DRAIN rather than Pin.IN? In any case, depending on the exact protection circuit used in the ESP32 you might expect the capacitor to be clamped at whatever the power supply voltage got down to in the interruption, minus a diode drop or so. So I think you'll need a more complex circuit, maybe one using two GPIO. \$\endgroup\$ Commented Apr 24, 2023 at 11:29

1 Answer 1

1
\$\begingroup\$

Chip IO pins can't have voltage when MCU has no supply voltage. You are only allowed to have VDD+0.3V on an IO pin, which means that if MCU VDD supply drops to 0V, there can only be 0.3V on the IO pin.

Chip IO pins have protection and when MCU supply starts falling towards zero, the protection diodes inside the MCU will discharge the capacitor to MCU supply pin.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.