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

Hello all!

I have a light that has 4 states. 1 is on, 2 is pulse, 3 is sound reactive, and 4 is off.

Can anyone pass me some example code of how to get this working on the esphome side or could you review my code below.

As of now, my issue is the light comes on as soon as I hook the gpio up to the + side of the physical button/ - up to the ground on the device. GPIO I have connected to positive side of button, ground to negative.

Chat gpt got me to here and I feel like I know less now than I did. Thank you all again for guidance. My end goal is to be able to create automations that will set the light to the proper setting. (1-4). Each button press increments the state by 1 as detailed above.

I took out all of the encryption keys, wifi setup etc.

If you all need any pics, I am ok with providing but I’m pretty sure I did a good job of explaining what I’m trying to do.

Thank you all for any assistance, guidance, examples. I have never done anything like this.

Project 2:
I have one other project similar to this that I would like to do next. Essentially on it for everytime I push a button/ switch or whatever the best way to do it is, in home assistant, I would like it to send 2 electrical signals through the gpio to a button. I noticed it took to button triggers on this other device before it made its sound.

The code below is my attempt at project 1:


# 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, with inverted state to start low
output:
  - platform: gpio
    pin: GPIO4  # Use GPIO4 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(300);  // 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);
    ```

Hello,

I think you should spend some time with a multimeter to determine what the button actually does.

Then you will know how to simulate it with your application.

For example, many buttons are designed to connect a GPIO on the device that has a pullup resistor to ground, bringing the GPIO down when the button is pressed.

Then to simulate such a button very closely you would bring your GPIO down to zero to ‘press’ the button, and configure it as ‘no output’ to ‘release’ the button, and the pullup on the device side would take care of bringing the device pin voltage back up.

You may not need to simulate the physical button as closely, and simply change the output between 0 and 1, only 0 meaning the button is ‘pressed’ or ‘on’ in this particular case.

This is only an example, and you should find out how your button is wired in your device.

You might also want to verify what your application is doing with that GPIO with a multimeter. You probably want the initial state to be ‘off’ whatever that means in your particular case.

I did just learn my switch is working to change the state so that makes me so happy! It changes state when I click the home assistant switch to “on”. I will read what you just sent and try to understand.

I thought that is what the part was doing was forcing the gpio to be low so that what it won’t force the light to on immediately like it is doing. The inverted “true” portion.

But for some reason, the light on the device still comes on as soon as the esp gets power.

I’m sorry, I don’t know much about electronics. I am an engineer by trade but I play with dirt, not electronics :-/

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

Yes, that’s why you need a multimeter. You probably assume something about the button or your code that did not work out.

Can you give me guidance on the multimeter idea?

When I plug the device in with no esp attached, it stays off.

When I plug the device in with the esp attached, it comes on.

I am stealing my v power from the device power supply so that everything is powered by 1 psu.

Ahh, I understand. I have the multimeter with me currently but knowing what to do with it is the problem.

You should measure the voltage on both sides of the button when it’s pressed and when it’s not pressed, with no ESP attached.

Then you should measure voltage on your GPIO pin without any connection to the button, as it behaves on start of your ESP, and as it behaves when you issue the ‘on’ and ‘off’ commands in the program.

Thank you for this information. Let me see what it does.

So to make sure I am touching the probes properly. For part 1. I put the red probe on + side of button and black on negative side of button?

If so, I get 3.3 volts when no button pressed on device and 0 when it is pressed.

No, you put the black probe to something you consider ground, and the red probe on whatever you are measuring, using the same reference for each measurement.

For the esp. On command: 1.6v (voltage drops) ; off command: 3.3v, startup:

For button: So with probe on negative side of button and known ground: 0 while pushing button and not pushing button
probe on + side of button and known ground: 3.3 while NOT pushing and 0 when pushing.

On the esp, I put the probe on the gpio4 and on the ground terminal and got these results: On command: 1.6v (voltage drops)–> I think its really taking it to 0 but the digital multimeter is not fast enough, for some reason the switch is acting like a toggle in home assistant and it won’t stay “on”, it kicks to “on” and then goes right back to off ; off command: 3.3v, startup: 3.3v

That sounds like it should generally work, maybe there is some glitch on that specific GPIO on startup.

ok, I added some more info in my last message as an edit, maybe there is something in there that will help.

Do you know of another gpio that may be more trustworthy? I am using esp32 devkit1

I really didn’t think this was going to be as difficult as it is turning out to be. Makes me sad. I don’t really understand the toggling of the switch within home assistant either but one problem at a time I guess :slight_smile: Oh I see the reason for it toggling now. I have a delay and then the off command in the turn on action.

According to this:

the GPIO4 should be OK (if that’s the same board).

Unfortunately, with this kind of program you do not have full control over the details, and it’s difficult to isolate different phases of the program.

For example, you do not have the option to initialize the GPIO only after a delay, and keep it in the boot state for a while. I suppose you could upload an empty program and see what happens to the GPIO in that case.

If all else fails you can compensate for the startup glitch by going through all the modes back to off.