Unwanted Delay after button press with voltage ladder

Hello!

Trying to set up a voltage ladder for a single analog input into multiple digital outputs. Everything seems to be working the way I want (with a few minor hiccups that I will look into fixing). The problem I'm having and can't figure out where I'm going wrong is - when I press any of the 4 buttons, it seems like I need to hold it until the voltage drop occurs. Delay is around 0.5-1 second, depending on the button pressed. I would like instantaneous response from all of them. Like a keyboard, or video game controller. It is going into a race car to control signals/power output/other things. The outputs themselves don't matter, but I want the button pressed to be left on until I press the button again, AND I would like a master switch to control power to all the buttons AND the outputs given. i.e. If master switch is on and I press a button for hazards, a separate button for rev limit and a separate button for some sort of cooling system, I would like the master switch to turn off all those outputs as well as supply the buttons.

Any diagram help or programming help is appreciated! I know I'm missing SOMETHING.

I've only tested my finished concept on tinkercad, so if its a delay with THAT software, that would be the easiest fix :sweat_smile:


```cpp
// Define the analog input pin (for the voltage ladder)
const int analogPin = A0;

// Define the digital output pin
const int outputPin1 = 3;
const int outputPin2 = 4;
const int outputPin3 = 5;
const int outputPin4 = 6;

// Define voltage thresholds for each button (adjust as needed)

const int switchOn = 1000;
const int button1Threshold = 100;
const int button2Threshold = 600;
const int button3Threshold = 760;
const int button4Threshold = 900;



// Variable to store the current state of the output pin
bool outputState = LOW;

void setup() {
  // Set the output pin as an output
  pinMode(outputPin1, OUTPUT);
  pinMode(outputPin2, OUTPUT);
  pinMode(outputPin3, OUTPUT);
  pinMode(outputPin4, OUTPUT);


  // Set the analog input pin as an input
  pinMode(analogPin, INPUT_PULLUP);
  // Initialize serial communication for debugging (optional)
  Serial.begin(9600);
}

void loop() {
  // Read the analog value from the voltage ladder
  int analogValue = analogRead(analogPin);
  Serial.print("Analog Value: ");
  Serial.println(analogValue);
  delay(10);

  // Check which button is pressed based on the analog value
  if (analogValue > button1Threshold && analogValue < button2Threshold) {
    // Button 2 pressed
    Serial.println("Button 2 Pressed");
    if (outputState == HIGH) {
      digitalWrite(outputPin2, LOW);
      outputState = LOW;
    } else {
      digitalWrite(outputPin2, HIGH);
      outputState = HIGH;
      delay(70);
    }
  } else if (analogValue > button2Threshold && analogValue < button3Threshold) {
    // Button 3 pressed
    Serial.println("Button 3 Pressed");
    if (outputState == HIGH) {
      digitalWrite(outputPin3, LOW);
      outputState = LOW;
    } else {
      digitalWrite(outputPin3, HIGH);
      outputState = HIGH;
      delay(70);
    }
  } else if (analogValue > button3Threshold && analogValue < switchOn) {
    // Button 4 pressed
    Serial.println("Button 4 Pressed");
    if (outputState == HIGH) {
      digitalWrite(outputPin4, LOW);
      outputState = LOW;
    } else {
      digitalWrite(outputPin4, HIGH);
      outputState = HIGH;
      delay(70);
    }
  } else if (analogValue < button1Threshold && analogValue != 10) {
    // Button 1 pressed
    Serial.println("Button 1 Pressed");
    if (outputState == HIGH) {
      digitalWrite(outputPin1, LOW);
      outputState = LOW;
    } else {
      digitalWrite(outputPin1, HIGH);
      outputState = HIGH;
      delay(70);
    }
  } else {
    Serial.println("    ");


}

  // Add a small delay to avoid rapid toggling
}

Also, I can't seem to figure out how to post a photo

In the absence of a schematic all i can say is that the below seems odd.

I'm very much a trial-and-error person, I have a screenshot of my doings on tinkercad, but can't get it posted

4 function str whl buttons schematic.pdf (7.6 KB)

  • OP’s schematic.

  • It is not recommended to switch GND to your switches or LEDs.

  • You have started with a schematic which is admirable, but you need to redraw it in a more conventual way, please try again.

  • In the Arduino IDE, use Ctrl T or CMD T to format your code.

  • Highly urge you place { and } on lines by themselves.

  • You LEDs are not wired correctly.

  • Avoid using HIGH or LOW, use macros so your code is self documenting.

Example


//================================================
#define LEDon              HIGH   //PIN---[220R]---A[LED]K---GND
#define LEDoff             LOW
 
#define PRESSED            LOW    //+5V---[Internal 50k]---PIN---[Switch]---GND
#define RELEASED           HIGH
 
#define CLOSED             LOW    //+5V---[Internal 50k]---PIN---[Switch]---GND
#define OPENED             HIGH
 
#define ENABLED            true
#define DISABLED           false

Are you really using 10Ω, 15Ω, and 20Ω resistors in the resistor ladder? Those values are way too low, 5V across a 10Ω resistor will produce a current of 500mA.

According to the sketch, there are NO actual buttons unless I am going blind. The wiring diagram, however, does have four buttons. You will also need to learn about bouncing, and you should check the pinned posts on almost any Category to do with a state machine or 'doing many things at once'
BTW, NO delay statements, your requirements tell you that.

Thank you for the inputs! I've never done ANY programming before and am tackling this all by myself as quickly as possible, so there's a few things I don't understand but will research to learn up on terminology and applications.

A lot of this was copy/paste from an AI request, but I really want to learn the actual language and be able to replicate this myself.

The LED's and resistors are just there (and in those values) to try to make the program do what I want it to do. I would not use those small values for real world application.

I see now that I haven't actually coded any buttons......oops......learning :smiley:

The example posted by @LarryD, I don't understand fully, but I know it's because of my lack of programming knowledge and not because it's confusing. It seems simple enough looking at it, is it just stating to define actual descriptive states instead of the values associated with them?

  • Which is easier to follow 6 months from now ?
digitalWrite(outputPin2, HIGH);

or

#define LEDon              HIGH   //PIN---[220R]---A[LED]K---GND
#define LEDoff             LOW
.  .  . 

digitalWrite(outputPin2, LEDon);
  • Your schematics should be logically drawn so you and others can see exactly what is happening.

  • Try to use this as an example, believe this is what you have, please confirm.

Edit

We will make this a learning moment and cover things one step at a time until you fully understand everything that is happening.

I'd say that looks correct! is that schematic done with the IDE?

I see what you mean by the #define macro. I can use that to clearly indicate whatever task or information is needed instead of loosely defining based on the arduino's output/input, then implement the macro instead of typing everything that could be INSIDE the macro?

I'd say that looks correct! is that schematic done with the IDE?
PCB design software was used to draw the schematic (mine is no longer available).
There are free versions available, KICAD and EASY EDA

I see what you mean by the #define macro. I can use that to clearly indicate whatever task or information is needed instead of loosely defining based on the arduino's output/input, then implement the macro instead of typing everything that could be INSIDE the macro?
Yes

Thank you! I will absolutely work on that, anything that makes coding easier is well worth my time :joy:

Based on my super fun tinkercad schematic and code, could you tell me why it takes a second after pressing a button to execute the request?

  • I am a bit fastidious with things.

  • See schematic below for resistor values.

  • Try this sketch, what does it do ?

  • Are the three schematics below effectively the same ?

  • Ask questions.

//
//================================================^================================================
//                                   S w i t c h e s   a n d   L E D s
//
//  https://forum.arduino.cc/t/unwanted-delay-after-button-press-with-voltage-ladder/1365743
//
//  SwitchesResistorLadderNetwork.ino
//
//  Version    YY/MM/DD    Comments
//  =======    ========    ========================================================================
//  1.00       25/03/20    Running code
//
//
//
//  Notes:
//
//
//
//

//================================================
//#define LEDon                  LOW    //GPIO(Pin)---[220R]---A[LED]K---GND
//#define LEDoff                 HIGH

#define LEDon                    HIGH   //+5V---[220R]---A[LED]K---GPIO/Pin
#define LEDoff                   LOW

#define PRESSED                  LOW    //+5V---[Internal 50k]---PIN---[Switch]---GND
#define RELEASED                 HIGH

#define CLOSED                   LOW    //+5V---[Internal 50k]---PIN---[Switch]---GND
#define OPENED                   HIGH

#define ENABLED                  true
#define DISABLED                 false


//================================================
//Define the analog input pin (for the voltage ladder)
const int analogPin            = A0;
int analogValue;
int lastAnalog;

//Define the digital output pin
const byte LED1                = 3;
const byte LED2                = 4;
const byte LED3                = 5;
const byte LED4                = 6;

const byte heartbeatLED        = 13;

//================================================
//Define voltage thresholds for each switch (adjust as needed)
//Note: 5V = 1023
const int switch4treshhold     =   0;   //0.0v
const int switch3treshhold     = 511;   //2.5v  Example: (511.0 * 5.0) / 1023.0 = 2.15v
const int switch2treshhold     = 681;   //3.3v
const int switch1treshhold     = 767;   //3.75

const int hysteresis           = 50;

//timing stuff
unsigned long heartbeatTime;
unsigned long checkSwitchTime;


//                                           s e t u p ( )
//================================================^================================================
//
void setup()
{
  //Initialize serial communication for debugging (optional)
  Serial.begin(9600);

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(heartbeatLED, OUTPUT);

  //read the current voltage on A0
  analogValue = analogRead(analogPin);
  lastAnalog = analogValue;

} //END of   setup()


//                                           l o o p ( )
//================================================^================================================
//
void loop()
{
  //========================================================================  T I M E R  heartbeat
  //is it time to toggle the heartbeat LED ?
  if (millis() - heartbeatTime >= 500ul)
  {
    //restart this TIMER
    heartbeatTime = millis();
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //========================================================================  T I M E R  check switches
  //is it time to scan our switches ?
  if (millis() - checkSwitchTime >= 50ul)
  {
    //restart this TIMER
    checkSwitchTime = millis();

    checkSwitches();
  }


  //================================================
  //       Other non blocking code goes here
  //================================================


} //END of   loop()


//                                   c h e c k S w i t c h e s ( )
//================================================^================================================
void checkSwitches()
{
  //read the current voltage on A0
  analogValue = analogRead(analogPin);

  //has the voltage changed significantly since the last time we checked it ?
  if (lastAnalog < (analogValue - hysteresis) || lastAnalog > (analogValue + hysteresis))
  {
    //update to this new value
    lastAnalog = analogValue;

    Serial.print("\nAnalog Value = ");
    Serial.print(analogValue);
    Serial.print("\t");
    Serial.print((analogValue * 5.0) / 1023.0);
    Serial.println(" Volts");

    //========================
    //based on the new analog voltage, which button is pressed
    if (analogValue < switch4treshhold + hysteresis)
    {
      Serial.println("Switch 4 Pressed");

      //ledsOff();
      //digitalWrite(LED4, !digitalRead(LED4));
      digitalWrite(LED4, LEDon);
    }

    //========================
    else if (analogValue < switch3treshhold + hysteresis)
    {
      Serial.println("Button 3 Pressed");
      
      //ledsOff();
      //digitalWrite(LED3, !digitalRead(LED3));
      digitalWrite(LED3, LEDon);
    }

    //========================
    else if (analogValue < switch2treshhold + hysteresis)
    {
      Serial.println("Button 2 Pressed");

      //ledsOff();
      //digitalWrite(LED2, !digitalRead(LED2));
      digitalWrite(LED2, LEDon);
    }

    //========================
    else if (analogValue < switch1treshhold + hysteresis)
    {
      Serial.println("Button 1 Pressed");

      //ledsOff();
      //digitalWrite(LED1, !digitalRead(LED1));
      digitalWrite(LED1, LEDon);
    }

    //========================
    //no switch was pressed
    else
    {
      ledsOff();
    }

  } //END of this switch

  //========================================================================  nextSwitch

} //END of   checkSwitches()


//                                         l e d s O f f ( )
//================================================^================================================
//
void ledsOff()
{
  digitalWrite(LED4, LEDoff);
  digitalWrite(LED3, LEDoff);
  digitalWrite(LED2, LEDoff);
  digitalWrite(LED1, LEDoff);

} //END of   ledsOff()


//                                       
//================================================^================================================
//



Sure. Serial is constipated. With nothing pressed, your loop cycles 100 times per second, sending this

  Serial.print("Analog Value: ");
  Serial.println(analogValue);

and this
Serial.println(" ");

every time, at 9600 baud. Don't just increase the baud, by the way, fix the problem.
Transmit nothing, or at least most a single
Serial.println('.');
unless a button is newly pressed, at which time you should report the analog value to begin with - after that, then you'll need to explore debouncing techniques. Look at the StateChangeDetection example in the IDE for clues

Knocks on door... "Hello, anybody home?".
24 hour silence, right after asking a question.

Oh well. Another newb ingrate to mute. Patience threshold? Nope, I got none. If they do come back, they're all yours, @LarryD.

  • Scaring off someone is directly related to offering to explain a solution :shushing_face:

Participation is necessary to converge on a solution. Always.

Out of curiosity, what in post #15 would have "scared them off", in your opinion? The explanation of serial constipation might not have been clear enough, but that should elicit a follow-on question, not silence.