Using a momentary switch to toggle between two outputs

Hi,
This is my first post on this forum as I am new to this whole Arduino universe.
I am trying to build a program that will allow me to use one momentary switch to toggle between two different controls. In this case I am trying to modify a reclining hospital bed remote so that the user (who has very limited hand mobility) has to only use one button to operate HEAD UP/DOWN functions.
The ideal operation would be: Hold button for chair UP, pause, hold button for chair DOWN, repeat.

The first code I have cobbled together (through the help of tutorials) makes one push button a momentary switch, where another push button is made in to a toggle switch. I am looking for advice to help me achieve my goal of only using the one push button for both operations.

The second code is built with only one push button in the build, but the code is a little over my head, it doesn't seem to work and I have no problem admitting that I don't quite understand it.

I am using LEDs to simulate the chair operations.

CODE 1:

//momentary toggle switch attempt 1 Dec. 20/2018
//define integers
int led1 = 4;
int led2 = 5;
int button1 = 8;
int button2 = 9;
boolean button1gate = true;  //gate for momentary switch
boolean button2gate = true;  //gate for toggle switch
int button2toggle = 0;


void setup() {

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(button1, INPUT_PULLUP); //using the internal pullup resistor to initially register HIGH
  pinMode(button2, INPUT_PULLUP); //using the internal pullup resistor to initially register HIGH
}

void loop() {
  ////BUTTON1//// - MOMENTARY SWITCH
  //If button1 is on                     //when button is pushed 'button1:1'

  if ( button1gate ) {                   //shorthand for button1gate == true as button1gate is defined above as true
    if ( digitalRead(button1) == LOW ) {
      digitalWrite(led1, HIGH);
      button1gate = false;
    }
    
  }

  //If button1 is off                     //when button is released 'button1:0'
  if ( button1gate == false ) {           //shorthand !button1gate
    if ( digitalRead(button1) == HIGH ) {
      digitalWrite(led1, LOW);
      button1gate = true;
    }

  }
  ////BUTTON2//// - TOGGLE SWITCH
  //If button2 is on                     //when button is pushed 'button2:2'

  if ( button2gate ) {                  //shorthand for button2gate == true as button2gate is defined above as true
    if ( digitalRead(button2) == LOW ) {
      button2toggle = (button2toggle + 1) % 2;    //this increases toggle count from 0  the %2(modulo 2) is t toggle between 2 states(0 and 1)
      button2gate = false;
    }
    
  }

  //If button2 is off                     //when button is released 'button2:0'
  if ( button2gate == false ) {           //shorthand !button2gate
    if ( digitalRead(button2) == HIGH ) {
      button2gate = true;
    }

  }

  //toggle LED2 on and off with button2 button
  if(button2toggle == 0) digitalWrite(led2, LOW);                //shorthand - if all commands are written on the same line {} are not needed
  if(button2toggle == 1) digitalWrite(led2, HIGH);
  delay(15);
}

CODE 2:

/*momentary toggle rocker switch idea
 * Using state change detection to be able to use one button to raise head or lower head of his bed controls; push, raise, push, lower, repeat
 * Determine a debounce time that is suitable, maybe 2 seconds between raise and lower functions
 * 
*/
int switchPin = 2;                              // switch is connected to pin 2
    int led1Pin = 8;
    int led2pin = 9;

    int val;                                    // variable for reading the pin status
    int val2;                                   // variable for reading the delayed status
    int buttonState;                            // variable to hold the button state
    int Mode = 0;                               // What mode is the light in?

    void setup() {
      pinMode(switchPin, INPUT_PULLUP);                // Set the switch pin as input
      pinMode(led1Pin, OUTPUT);
      pinMode(led2pin, OUTPUT);
      buttonState = digitalRead(switchPin);     // read the initial state
    }

    void loop(){
      val = digitalRead(switchPin);             // read input value and store it in val
      delay(10);                                // 10 milliseconds is a good amount of time
      val2 = digitalRead(switchPin);            // read the input again to check for bounces
      if (val == val2) {                        // make sure we got 2 consistant readings!
        if (val != buttonState) {               // the button state has changed!
          if (val == LOW) {                    // check if the button is pressed
            if (Mode == 0) {          
              Mode = 1;               
            } else {
                if (Mode == 1) {        
                Mode = 2;           
            } else {
                if (Mode == 2) {      
                Mode = 3;           
            } else {
                if (Mode == 3) { 
                Mode = 0;          
                  }
            }
           }
          }
         }
        }
        buttonState = val;                      // save the new state in our variable
      }

                                                // Now do whatever the lightMode indicates
      if (Mode == 0) {                          // all-off
        digitalWrite(led1Pin, LOW);
        digitalWrite(led2pin, LOW);
      }

      if (Mode == 1) { 
        digitalWrite(led1Pin, HIGH);
        digitalWrite(led2pin, LOW);
      }

      if (Mode == 2) { 
        digitalWrite(led1Pin, LOW);
        digitalWrite(led2pin, HIGH);
      }
          
    }

I really appreciate all interest and advice I might receive for this project:)

Welcome to the group!

Can you understand what is happening in this discussion?
https://forum.arduino.cc/index.php?topic=525240.0

Tell us more why you are wanting to do this.

Makes a lot of sense to use the State Machine technique.

Are there limit switches at the ends of travel?

Good job using code tags on your first post. This sounds like a good project.

The second code is built with only one push button in the build, but the code is a little over my head, it doesn't seem to work

Please be more specific. What are our expectations for the code? What does the code do that you don't want it to do? What does the code not do that you want it to do?

and I have no problem admitting that I don't quite understand it.

What specifically do you not understand?

@larryd:
Thank you. Yes, I can follow what is happening in the discussion you posted, it contains some very helpful information, so thank you again.
The user of the home-based hospital bed has very limited mobility and would benefit from any independence from, in this case, a modified bed remote. Since he has such limits to his mobility, he can only push one button on the remote. I would like to give him the freedom to both raise and/or lower the head of his bed without requiring his care aid to do it for him.
As for the limit switches, there must be. My mods to the remote would be to just add a button that is parallel to the head up/down controls of the remote, so I shouldn't have to factor it in as the remote will still be operating as it did before modifying.

@cattledog:
Thank you for your interest, I think it is a good project, too.
For my second code, it compiled fine but I haven't spent as much time on it as the first code, it is likely a wiring fault of my own.
When I said it is a little over my head, all I meant to say is that some of the syntax is beyond my knowledge at the moment, part of the curse of copy/paste. I acknowledge that I have a lot of study and research ahead of me and I look forward to it and any guidance along the way.

Yes a good project.

You could have the following states:

StoppedBeforeUp
GoingUp
StoppedGoingDown
GoingDown

Look for a change in switch position to detect a push, maybe add a minimum/maximum push time.

Letting go of the switch stops movement and either goes to state StoppedBeforeUp or StoppedGoingDown.

A push and hold changes from a Stop condition to the moving state.

You could incorporate some kind of a disable function to prevent accidental pushes from operating movement.

@larryd:
Those are very good ideas, thank you:)
One of the things about this Arduino universe I find both liberating and a little intimidating is the ability to do something a multitude of different ways.

The ideal operation would be: Hold button for chair UP, pause, hold button for chair DOWN, repeat.

Your codes appear to be based on state change and transition detection. I would think that you want to be using the actual state of the button.

If the person presses the button and the chair goes in the wrong direction is that a problem?

If the previous move was down, and then some time later they want to do down farther and they push the button and go up will they realize that, release the button, and then press again to go down?

@cattledog:

cattledog:
If the person presses the button and the chair goes in the wrong direction is that a problem?

If the previous move was down, and then some time later they want to do down farther and they push the button and go up will they realize that, release the button, and then press again to go down?

No, not a problem. The end user has been a part of the design process and has other devices that operate in the same way.

My use of state change and transition detection definitely has a lot to do with the tutorials that I have completed. I will try your advice of using the actual state of the button in the next iteration of the project.
Thank you for your advice:)

IMO, I prefer to press, hold, to go into a State, stay in that State while pressed then go to a stop State on switch release.

My use of state change and transition detection definitely has a lot to do with the tutorials that I have completed. I will try your advice of using the actual state of the button in the next iteration of the project.
Thank you for your advice:)

I've thought a bit more, and since you are toggling the next move condition, you will need to detect the button press as well as move the chair as long as it is pressed. It is probably easiest to do this with start move and change next state on button press, stop the move on button release.

I would recommend that you use a button library to help with the debounce. I recommend Bounce2 which is available through the library manager. I think this is the basic outline of a sketch

// Include the Bounce2 library
//available through Arduino ide library manager
//https://github.com/thomasfredericks/Bounce2
 
#include <Bounce2.h>

#define buttonPin 5
#define Up 1
#define Down 0
byte direction = Down;//default initial move direction
const byte ledPin = 13;

// Instantiate a Bounce object called button
Bounce button = Bounce();

void setup() {
  Serial.begin(115200);
  pinMode(buttonPin, INPUT_PULLUP);
  button.attach(buttonPin);
  button.interval(25);//set debounce interval
  pinMode(ledPin, OUTPUT);
}

void loop() {

  // Update the Bounce instance, does digitalRead of button
  button.update();

  // Button press transition from HIGH to LOW)
  if (button.fell())
  {
    if (direction == Up)
      Serial.println("Moving Up");
    else
      Serial.println("Moving Down");

    //turn on motor, direction of last state
    digitalWrite(ledPin, HIGH);

    //toggle direction
    if (direction == Up)
    {
      direction = Down;
    }
    else
    {
      direction = Up;
    }
  }

  // Button release transition from LOW to HIGH) :
  if (button.rose())
  {
    //turn off motor
    digitalWrite(ledPin, LOW);
    Serial.println("Stopping");
  }
}

You must pay attention to safety regulations using electrical devices with patient beds.

@cattledog:
Thank you for your sketch. I really appreciate your advice:)

@cattledog and @larryd

Hi again,
Sorry, it's been a while since I've been on this forum.
I have compiled this code that works well as a toggle. I still am trying to get the buttons to operate as a momentary switch instead of as a latching toggle. Any advice or critique you could provide is always welcome.
I have included my codes for my momentary switch as well as my toggle concept.
Thanks:)

 const int buttonPin = 2;
 const int ledPin = 13;

 // define variables
 int buttonState = 0;

 
 void setup() 
 {
  pinMode(ledPin, OUTPUT);    // initializes LEDpin as an output
  pinMode(buttonPin, INPUT);  // initializes buttonPin as an input
}

void loop() {
  buttonState = digitalRead(buttonPin);   // reads the state of the buttonPin value

  if ( buttonState == HIGH) {             // checks to see if pushbutton is pushed, if yes, then buttonState is HIGH
    digitalWrite(ledPin, HIGH);           // turns LED on
  }
  else {
    digitalWrite(ledPin, LOW);            // turns LED off
    
  }
  

}
int ledPin1 = 10;
int ledPin2 = 9;
int switchPin = 2;
int count = 0;

boolean lastButton;
boolean currentButton = false;
boolean ledOn = false;

void setup() {

  pinMode(switchPin, INPUT);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  
  count = 0;
}
//debounce function to stabilise the button
boolean debounce(boolean last)
{
  boolean current = digitalRead(switchPin);
  if (last != current)
  {
    delay(5);
    current = digitalRead(switchPin);
  }
  return current;  
}
void loop() {
  lastButton = currentButton;
  currentButton = debounce(lastButton);
  if (lastButton == false && currentButton == true)
  {
    if (count == 0) 
    { 
      count++;
      digitalWrite(ledPin1, HIGH);
      digitalWrite(ledPin2, LOW);
    }

    else if (count == 1)
    { 
      count++;
      digitalWrite(ledPin1, LOW); 
      digitalWrite(ledPin2, LOW);
    }

        else if (count == 2)
    { 
      count++;
      digitalWrite(ledPin1, LOW); 
      digitalWrite(ledPin2, HIGH);
    }

    else if (count == 3)
    { 
      count = 0;
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
    }

  } 
}