Esphome help needed. Would like to "electronically" push a button on a device. Anyone have a how to?

Yeah, thats the board for sure. I may try the empty program idea.

Something doesn’t seem right. It seems like the pin is defaulted to on and I don’t really see a way to get it to start as “off”. I really thought that was the pointed of the “inverted” pin property under gpio output.

I’m not sure what you mean by this.

Oh I see what your are saying. Have the program on the esp, just turn it off at boot by cycling.

I hate to do that but it would work like you said.

Thank you for your help with this again. I think I figured it out with your help. Apparently the inverted statement was supposed to be false and I changed to GPIO2. I believe the whole time, the inversion statement was the issue. :-/

Hey Michal,

Can I ask you a quick question about what I’m doing here. Would it be correct to have the gpio from the esp32 soldered on one side of the button on the device I’m trying to control and the ground from the esp32 soldered on the other side of the button I’m trying to control or should the ground from the esp be soldered to the common ground of the device. Something I’m noticing is that when I put the probe between the gpio and the ground of the device, it shows near 0 voltage but I can take the gpio lead (I’m using jumpers for testing) and if I touch it to the + area of the board, it cycles the lights to the new setting each time I touch it.
Would pictures help you possibly help me figure this out completely?

I thought I had it when we finished last time, I think we figured out the voltage situation but now I’m stumped on this.

Thank you!!

Essentially if I plug in this light without the esp connected to the button/ ground of the device, it doesn’t come on.

If I plug it in with the esp connected. The light comes on immediately upon receiving power from the outlet. (Even though I do have the gpio now starting in “low”.

With your measurement it looks like the button indeed works by pulling a gpio on your device low when pushed.

With the ‘inverted’ gpio flag you should be correctly emulating momentary button presses with your function that turns the gpio on and then off again.

Without the flag you are emulating the button pressed all the time, and your function doing ‘on’ and ‘off’ does a momentary release of the button. In either case it does both press and release so it should move forward through the lamp states.

The problem you are seeing is that the lamp initially advances to to ‘on’ state when your ESP device is connected. This is likely a bug in the ESPHome framework: It initializes the GPIO in the low state momentarily even though the ‘inverted’ flag is specified. However, this is very difficult to debug working inside the ESPHome framework. To confirm using the Arduino framework directly, or patched ESPHome is likely required (unless ESPHome has some option to initialize GPIO dynamically while the program is running, without declaring it beforehand).

If your lamp changed state on button release then using the non-inverted GPIO which emulates pressing and holding the button on ESP32 startup, and momentarily releasing it in the button press function would work.

If that does not you could try to get the GPIO handling fixed, try to add a transistor to invert the GPIO value electrically, or try to add some initialization code to your program that sends enough pulses to go back to ‘off’ state.

This is where I’m at now:

# Global variable to track the state
globals:
  - id: button_counter
    type: int
    restore_value: no
    initial_value: '1'

# Define the GPIO output to simulate button presses
output:
  - platform: gpio
    pin: GPIO5  # Use GPIO4 to simulate the button press
    id: simulated_button
    inverted: false  # Inverts the signal, making it low by default


# Template switch to simulate button presses and track the counter
switch:
  - platform: template
    name: "Simulated Button"
    turn_on_action:
      - lambda: |-
          // Increment the counter
          id(button_counter) += 1;

          // Reset the counter after state 4
          if (id(button_counter) > 4) {
            id(button_counter) = 1;
          }

          // Log the state with meaningful names
          switch (id(button_counter)) {
            case 1:
              ESP_LOGD("main", "State 1: Device ON");
              break;
            case 2:
              ESP_LOGD("main", "State 2: Device PULSING");
              break;
            case 3:
              ESP_LOGD("main", "State 3: Device REACTS TO SOUND");
              break;
            case 4:
              ESP_LOGD("main", "State 4: Device OFF");
              break;
          }

          // Simulate the button press
          id(simulated_button).turn_on();
          delay(3000);  // Simulate the physical button press duration
          id(simulated_button).turn_off();

          // Update the sensor value after every press
          id(button_counter_sensor).publish_state(id(button_counter));

  # Virtual reset button to reset the counter
  - platform: template
    name: "Reset Button"
    turn_on_action:
      - lambda: |-
          // Reset the counter to 1
          id(button_counter) = 1;
          ESP_LOGD("main", "Button counter reset to 1");

          // Optionally, update the sensor state to reflect the reset
          id(button_counter_sensor).publish_state(id(button_counter));

# Expose the button_counter as a sensor to Home Assistant
sensor:
  - platform: template
    name: "Button Press Counter"
    id: button_counter_sensor
    lambda: |-
      return id(button_counter);


yellow and 1 of the blacks can be ignored because I’m using the jumpers (blue-gpio, black-ground) as I was testing

So I can tell you one thing I’m noticing on this. When I push the physical button on the device, it cycles (on push, not release). I feel like when I’m doing it through using the virtual switch (and the previous code), it is not actually cycling until the 3 second delay is up. I think my code is , turn on, 3 secs, turn off (in terms of the switch state. not the light

I can try to learn how to do this so we will have more data/ information over the next week. I’m sorry, my brain is burned from all of the new things I’m learning so it will take me longer than most :slight_smile:

EDIT: Luckily this is no longer necessary.

Another thing I have noticed. The physical button on the device does not cycle the light anymore with the esp attached. That doesn’t seem normal. I would think I could still push the button on the side to cycle it with the esp attached but that is not the case.

EDIT: This was probably because I had changed the pin inverted to FALSE at some point. This was in error. It kept everything like it was being pushed.

And even more information. I used a multimeter and put it on continuity mode. With the physical button of the device not pressed, continuity flowed through the switch on the device. When I press the button on the side of the device, the flow stopped.

Does this change our conversation we have been having?

I’m sorry, that seems like a really big thing that may be important based on how we were originally doing all of this. Is there anything I can do to remedy this— I’m starting to think the reason it immediately cycles with the esp attached is the button is always in a “pressed” state. That would make sense as to why the physical button wouldn’t cycle the light anymore with the esp attached. I think?

With this information, would my code a few post up need to be much different. I apologize again for not having much of a handle on all of this.

@hramrach

Everything is finally working. I have no clue why but now the device is not coming on at esp boot. Below is the final code:

# Global variable to track the state
globals:
  - id: button_counter
    type: int
    restore_value: no
    initial_value: '1'

# Define the GPIO output to simulate button presses
output:
  - platform: gpio
    pin: GPIO5  # Use GPIO5 to simulate the button press
    id: simulated_button
    inverted: True  # Inverts the signal, making it low by default


# Template switch to simulate button presses and track the counter
switch:
  - platform: template
    name: "Simulated Button"
    turn_on_action:
      - lambda: |-
          // Increment the counter
          id(button_counter) += 1;

          // Reset the counter after state 4
          if (id(button_counter) > 4) {
            id(button_counter) = 1;
          }

          // Log the state with meaningful names
          switch (id(button_counter)) {
            case 1:
              ESP_LOGD("main", "State 1: Device ON");
              break;
            case 2:
              ESP_LOGD("main", "State 2: Device PULSING");
              break;
            case 3:
              ESP_LOGD("main", "State 3: Device REACTS TO SOUND");
              break;
            case 4:
              ESP_LOGD("main", "State 4: Device OFF");
              break;
          }

          // Simulate the button press
          id(simulated_button).turn_on();
          delay(3000);  // Simulate the physical button press duration
          id(simulated_button).turn_off();

          // Update the sensor value after every press
          id(button_counter_sensor).publish_state(id(button_counter));

  # Virtual reset button to reset the counter
  - platform: template
    name: "Reset Button"
    turn_on_action:
      - lambda: |-
          // Reset the counter to 1
          id(button_counter) = 1;
          ESP_LOGD("main", "Button counter reset to 1");

          // Optionally, update the sensor state to reflect the reset
          id(button_counter_sensor).publish_state(id(button_counter));

# Expose the button_counter as a sensor to Home Assistant
sensor:
  - platform: template
    name: "Button Press Counter"
    id: button_counter_sensor
    lambda: |-
      return id(button_counter);

@hramrach
Michal,

If I Post one more of these. Could you give me a bit of help on figuring it out. This will be the last one

On the new one below is my code, this device is a simple on and off button. I have learned these things with a multimeter:

The device button is normally open. When I push and hold the device button, voltage is found on the bottom left terminal of the push button. I connected my gpio to that point. I have common ground between device and esp.

On my esp, with the code below when I have not pushed any buttons within home assistant, I am showing 10.7 mV. When I turn on my switch in home assistant, I get a 3 second period of 3.3v followed by a short pause, the 3 more seconds of 3.3v.

On my esp, while checking startup: I get a short burst of 3.3 volts.----> This is my problem I believe. The other esp from our original device/ conversation seems to have stopped this behavior and I have no clue why. The new device/ esp project seems to be doing this.

Can you tell me how to fix this issue?-- sense it seems by software doesn’t work.

Or as a hack, is there a way to put in the code that upon boot, send a single signal to turn it back off.—> I would be ok with this I believe.

Honestly, I would like to know the right way to fix it and the hacky way :slight_smile:

Are there pins on the 30 pin esp32 that wont exhibit this behavior?

Also, I keep getting a warning that GPIO5 (the pin I am using), is strapping pin. Could this be the issue?

# Define the GPIO output to simulate button presses
output:
  - platform: gpio
    pin: GPIO5  # Use GPIO5 to simulate the button press
    id: simulated_button_for_block_light
    inverted: False

# Template switch to simulate two button presses
switch:
  - platform: template
    name: "Simulated Button"
    turn_on_action:
      - lambda: |-
          // Simulate first button press
          ESP_LOGD("main", "Simulating first button press...");
          id(simulated_button_for_block_light).turn_on();
          delay(3000);  // Duration of the button press
          id(simulated_button_for_block_light).turn_off();
          delay(500);  // Wait before the second press

          // Simulate second button press
          ESP_LOGD("main", "Simulating second button press...");
          id(simulated_button_for_block_light).turn_on();
          delay(3000);
          id(simulated_button_for_block_light).turn_off();

Try with Gpio4 for example, 5 is giving signal at boot(if you use normal Esp32).

Thank you for this. I ended up going to GPIO 18 and it seems to have done the trick. Can you explain why that works? I don’t really understand. I just know it seems to have worked.

Esp32 has pins that gives signals at boot, also strapping pins that might cause a normal boot failure if pulled high/low.
Easy to remember: use pins 16-32 if available.

Thank you for the reply and the link. Very appreciative of both! Things can be such a headache sometimes when you’re just learning.

And later as well.
Esp has normal Wroom32, S2, S3, C2, C3,C6,H2… All with different pinouts, different memory etc. Then there are hundreds of dev boards based on these, all with different characteristics… :wink:

Yeessh. Yeah, I was noticing this just trying to find the pinout for mine. It seems like a bit of a mess :slight_smile: