Two different "while" statements with same conditions? SOLVED

I have a live test vehicle for my wheelchair lift project. The part I'm having trouble finding a solution for is in the Up(). When the lift is coming up it will hit a limit switch at floor level and come to a stop. Next I need a button change state to determine that it can go beyond floor level with all limit tests being the same as in the previous state.

My question is, how can this be done where if the lift is stopped in the middle of Up() before hitting the limitFloor I still need to keep it from going into the second state? In writing out the question I may have answered my own question. Maybe creating a state variable after the first touch of limitFloor that would have to change to go into the next stage? I'd like to hear any thoughts.

void Up()  {
  while (digitalRead(limitOpen) == LOW && digitalRead(limitDeploy) == LOW && digitalRead(limitFloor) == LOW)
  {
    digitalWrite (up, LOW);
  }
  while (digitalRead(limitOpen) == LOW && digitalRead(limitDeploy) == LOW && digitalRead(limitFloor) == HIGH && digitalRead(limitDown) == HIGH)
  {
    digitalWrite (up, HIGH);
  }
  //button change state here? - dilema with two like "while" statements. I need a complete stop at limitFloor, then continue with release/repress of button.
  while (digitalRead(limitOpen) == LOW && digitalRead(limitDeploy) == LOW && digitalRead(limitFloor) == HIGH && digitalRead(limitDown) == HIGH)
  {
    digitalWrite (up, LOW);
  }
  while (digitalRead(limitOpen) == LOW && digitalRead(limitDeploy) == HIGH && digitalRead(limitFloor) == LOW && digitalRead(limitDown) == HIGH)
  {
    digitalWrite (up, HIGH);
    digitalWrite (stow, LOW);
  }
}

My question is, how can this be done where if the lift is stopped in the middle of Up() before hitting the limitFloor I still need to keep it from going into the second state?

Why would the lift stop moving if it hasn't reached the limit switch?

Why would that matter? Whenever the lift could move again, it still needs to be moving up until it hits the limit switch.

  while (digitalRead(limitOpen) == LOW && digitalRead(limitDeploy) == LOW && digitalRead(limitFloor) == LOW)
  {
    digitalWrite (up, LOW);
  }

How many times is that statement going to iterate? Why do you need to keep setting the up pin LOW? Why does the up variable not have Pin in it's name? Why do none of the other variables that contain pin numbers not have Pin in the name?

What do limitOpen and limitDeploy mean?

Why would the lift stop moving if it hasn't reached the limit switch?

Why would that matter? Whenever the lift could move again, it still needs to be moving up until it hits the limit switch.

My wording may have been confusing. This particular brand of lift has to stop at the limit switch, then continue up beyond the limit switch with no other switches or sensors in between. It won't stop before the limit switch is reached, getting it to move again after that is my dilemma.

How many times is that statement going to iterate? Why do you need to keep setting the up pin LOW? Why does the up variable not have Pin in it's name? Why do none of the other variables that contain pin numbers not have Pin in the name?

The statement happens twice, I need a stop and a move under the same switch conditions. (This is where my problem lies, I should have one to set the up pin HIGH and one to set it LOW) There are no pin names because it's a small program, but I do understand I should rename them for "good practices" and will do so.

What do limitOpen and limitDeploy mean?

Keep in mind this is for a wheelchair van. Also note that upPin and downPin are physical momentary switches that will stop all motion when released. This is why I need it to stop at floor level with the button pressed and then continue past after a release and repress/hold under same limit conditions.

Down()
Van door fully opens (openPin) and hits limitOpenPin
Lift fully unfolds (deployPin) and hits limitDeploy
Lift lowers (downPin) until limitFloor and stops
Load wheelchair from van
Press buttonDownPin again to lower lift to ground - limitDown

Up()
Load wheelchair from ground
upPin until limitFloor level and then stop
Roll wheelchair into van
upPin until limitDeploy
foldPin until limitStowPin
van door closePin until upPin released

void Up()  {
  while (digitalRead(limitOpenPin) == LOW && digitalRead(limitDeployPin) == LOW && digitalRead(limitFloorPin) == LOW)
  {
    digitalWrite (upPin, LOW);
  }
  while (digitalRead(limitOpenPin) == LOW && digitalRead(limitDeployPin) == LOW && digitalRead(limitFloorPin) == HIGH && digitalRead(limitDownPin) == HIGH)
  {
    digitalWrite (upPin, HIGH);
  }
  //button change state here? - dilema with two like "while" statements. I need a complete stop at limitFloor, then continue with release/repress of button.
  while (digitalRead(limitOpenPin) == LOW && digitalRead(limitDeployPin) == LOW && digitalRead(limitFloorPin) == HIGH && digitalRead(limitDownPin) == HIGH)
  {
    digitalWrite (upPin, LOW);
  }
  while (digitalRead(limitOpenPin) == LOW && digitalRead(limitDeployPin) == HIGH && digitalRead(limitFloorPin) == LOW && digitalRead(limitDownPin) == HIGH)
  {
    digitalWrite (upPin, HIGH);
    digitalWrite (stowPin, LOW);
  }
}

I should have one to set the up pin HIGH and one to set it LOW)

No, I don't think so. The point is that you set the value of the pin first, and then you have a while loop that waits for some condition to be met. It is NOT necessary to have anything in the body of the while statement.

  digitalWrite (upPin, LOW);
  while (digitalRead(limitOpenPin) == LOW && digitalRead(limitDeployPin) == LOW && digitalRead(limitFloorPin) == LOW)
  {
  }

I don't see how setting the up pin LOW make the device go up, and then setting it HIGH makes it go up some more.

Also, the names are still confusing. I still don't understand what is connected to the limitOpen pin or the limitDeploy pin.

I'm thinking that a picture is worth a thousand posts.

The rest of the description makes some sense, but I am still missing something.

I think that you need to have loop read the do something pins (upPin and downPin) and call functions that make each step listed below the function happen. When the down switch becomes pressed, call openDoor().
That function start the door moving, and then wait for the door to be all the way open (or until some reasonable "that ain't gonna happen" time has passed.

Then, call unfoldPlatform(). When that returns, call lowerPlatformToFloorLevel(). I presume that, at this point, you want to wait for another switch to become pressed, before calling lowerPlatformToGroundLevel().

Write the individual functions, then have loop() read the appropriate trigger switch. Call the first function, but none of the rest of the functions.

That is, first loop() should ONLY cause the door to be opened and closed. When that works, then add the calls to unfold and fold the platform. When that works, add the functions to lower the platform to floor level and to raise it.

Only add more code when the previous step works as expected.

You need to ignore the limit switch while the chair is in the process of moving past it. Two ways to do this are “ignore the limit switch being on until it goes off again” and “ignore the limit switch being on for the next 2 seconds”.

Write the individual functions, then have loop() read the appropriate trigger switch. Call the first function, but none of the rest of the functions.

Great advice! I also went back and re-read Organizing a Project and it says basically the same thing. It also says to avoid modifying existing code as it leads to confusion. I modified existing code and was obviously confused. I used the part of my old code with “while” statements which wouldn’t have done what I was trying to do. You saw that, I did not.

Last night I re-wrote the entire code in a way that makes much more sense. Tomorrow I can start wiring it in and testing, one stage at a time of coarse. Code below:

int buttonDownPin = 14;
int buttonUpPin = 15;
int limitOpenPin = 2;
int limitDeployPin = 3;
int limitFloorPin = 4;
int limitDownPin = 5;
int limitStowPin = 6;
int limitFoldPin = 7;
int OpenPin = 8;
int ClosePin = 9;
int deployPin = 10;
int stowPin = 11;
int downPin = 12;
int upPin = 13;
/*Stage1 //Door closed, ramp stowed, lift up
  Stage2 //Door open, ramp stowed, lift up
  Stage3 //Door open, ramp deployed, lift floor level
  Stage4 //Door open, ramp deployed, lift down*/
int Stage = 1;

void setup() {
  // put your setup code here, to run once:
  pinMode (buttonDownPin, INPUT_PULLUP);
  pinMode (buttonUpPin, INPUT_PULLUP);
  pinMode (limitOpenPin, INPUT_PULLUP);
  pinMode (limitDeployPin, INPUT_PULLUP);
  pinMode (limitFloorPin, INPUT_PULLUP);
  pinMode (limitDownPin, INPUT_PULLUP);
  pinMode (limitStowPin, INPUT_PULLUP);
  pinMode (limitFoldPin, INPUT_PULLUP);
  pinMode (OpenPin, OUTPUT);
  pinMode (ClosePin, OUTPUT);
  pinMode (deployPin, OUTPUT);
  pinMode (stowPin, OUTPUT);
  pinMode (downPin, OUTPUT);
  pinMode (upPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

  if (digitalRead (buttonUpPin) == LOW || digitalRead (buttonDownPin) == LOW) {
    OutIn();
  }
 
  else {
    for (int i = 8; i <= 13; i++) {
      // all outputs (8-13) off (relay board is active low)
      digitalWrite(i, HIGH);
      delay (10);
    }
  }
}

void OutIn() {
  if (Stage == 1) {
    Door();
  }
  if (Stage == 2) {
    Fold();
  }
  if (Stage == 3) {
    Floor();
  }
  if (Stage == 4) {
    Platform();
  }
}

void Door() {
  if (digitalRead (buttonUpPin) == LOW) {
    digitalWrite(ClosePin, LOW);
  }
  
  if (digitalRead (buttonDownPin) == LOW) {
    digitalWrite (OpenPin, LOW);
    if (digitalRead (limitOpenPin) == LOW) {
      digitalWrite (OpenPin, HIGH);
      Stage = 2;
    }
  }
}

void Fold() {
  if (digitalRead (buttonUpPin) == LOW) {
    digitalWrite(stowPin, LOW);
    if (digitalRead (limitStowPin) == LOW) {
      digitalWrite (stowPin, HIGH);
      Stage = 1;
    }
  }
  if (digitalRead (buttonDownPin) == LOW) {
    digitalWrite (deployPin, LOW);
    if (digitalRead (limitFloorPin) == LOW) {
      digitalWrite (deployPin, HIGH);
      Stage = 3;
    }
  }
  //if upButton fold platform until fold limit, set to stage1
  //if downButton lower platform until floor limit, set to stage3
}
void Floor() {
  if (digitalRead (buttonUpPin) == HIGH) {
    Stage = 2;
  }
  if (digitalRead (buttonDownPin) == HIGH) {
    Stage = 4;
  }
  //if upButton stop motion while button pressed, set to stage2
  // if downButton stop motion while button pressed, set to stage4
}
void   Platform() {
  if (digitalRead (buttonUpPin) == LOW) {
    digitalWrite(upPin, LOW);
    if (digitalRead (limitFloorPin) == LOW) {
      digitalWrite (upPin, HIGH);
      Stage = 3;
    }
  }
  if (digitalRead (buttonDownPin) == LOW) {
    digitalWrite (downPin, LOW);
    if (digitalRead (limitDownPin) == LOW) {
      digitalWrite (downPin, HIGH);
    }
  }
  // if upButton raise lift to floor, set to Stage3
  // if downButton lower lift until down limit* /
}

Depending on where the Arduino is in processing when the button is released I’m not sure it will still set the appropriate stage before going back to loop.

I’ll keep trying until I get stuck again. If it works I’ll be back with pictures and video, if it doesn’t work I’ll be back with pictures and video.

You need to ignore the limit switch while the chair is in the process of moving past it. Two ways to do this are “ignore the limit switch being on until it goes off again” and “ignore the limit switch being on for the next 2 seconds”.

I think that was accomplished in my new code, I’ll let you know the results. Thanks!

int buttonUpPin = 15;`` if (buttonUpPin == HIGH) {
HIGH has the numeric value 1.
In my experience, 1 never, ever equals 15.

Did you forget a digitalRead?

Did you forget a digitalRead?

I forgot a bunch of digitalReads! I'll fix that right away, thank you.

I have this working on the way down just fine. On the way up it gets stuck right here.

void Fold() {
  if (digitalRead (buttonUpPin) == LOW) {
    digitalWrite(upPin, LOW);
    if (digitalRead (limitStowPin) == LOW) {
      digitalWrite (upPin, HIGH);
      digitalWrite (stowPin, LOW);
      if (digitalRead (limitFoldPin) == LOW) {
        digitalWrite (stowPin, HIGH);
        Stage = 1;
      }
    }
  }

What happens is, when it gets to limitStowPin it writes upPin HIGH and goes strait to Stage1 and closes the door into the ramp. This is basically the same code as the down portion in reverse and the down portion works. I was getting inconsistent readings with my meter on the actual limitFoldPin switch so I replaced it and the wiring with new, even tried a different Arduino just in case.

I'm so close, any ideas?

I forgot to mention that I tried disconnecting the limitFoldPin so that it's only state could be HIGH due to input_pullup and it still skipped straight to door()

Ok, man: I would do something like this:

/**
  Down()
  Van door fully opens (openPin) and hits limitOpenPin
  Lift fully unfolds (deployPin) and hits limitDeploy
  Lift lowers (downPin) until limitFloor and stops
  Load wheelchair from van
  Press buttonDownPin again to lower lift to ground - limitDown

  Up()
  Load wheelchair from ground
  upPin until limitFloor level and then stop
  Roll wheelchair into van
  upPin until limitDeploy
  foldPin until limitStowPin
  van door closePin until upPin released
*/

enum State {
  CLOSED,
  OPENING,
  UNFOLDING,
  DOWN_TO_FLOOR,
  FLOOR,
  DOWN_TO_GROUND,
  GROUND,
  UP_TO_FLOOR,
  // FLOOR
  UP_TO_STOW,
  FOLDING,
  CLOSING
} state = CLOSED;

const byte buttonDownPin = 14;
const byte buttonUpPin = 15;
const byte limitOpenPin = 2;
const byte limitDeployPin = 3;
const byte limitFloorPin = 4;
const byte limitDownPin = 5;
const byte limitStowPin = 6;
const byte limitFoldPin = 7;
const byte OpenPin = 8;
const byte ClosePin = 9;
const byte deployPin = 10;
const byte stowPin = 11;
const byte downPin = 12;
const byte upPin = 13;

void setup() {
  pinMode(buttonDownPin, INPUT_PULLUP);
  pinMode(buttonUpPin, INPUT_PULLUP);
  pinMode(limitOpenPin, INPUT_PULLUP);
  pinMode(limitDeployPin, INPUT_PULLUP);
  pinMode(limitFloorPin, INPUT_PULLUP);
  pinMode(limitDownPin, INPUT_PULLUP);
  pinMode(limitStowPin, INPUT_PULLUP);
  pinMode(limitFoldPin, INPUT_PULLUP);

  pinMode(OpenPin, OUTPUT);
  pinMode(ClosePin, OUTPUT);
  pinMode(deployPin, OUTPUT);
  pinMode(stowPin, OUTPUT);
  pinMode(downPin, OUTPUT);
  pinMode(upPin, OUTPUT);
}

void loop() {
  switch (state) {
    case CLOSED:    state = state_CLOSED(); break;
    case OPENING:   state = state_OPENING(); break;
    case UNFOLDING: state = state_UNFOLDING(); break;
    case DOWN_TO_FLOOR: state = state_DOWN_TO_FLOOR(); break;
    case FLOOR:     state = state_FLOOR(); break;
    case DOWN_TO_GROUND: state = state_DOWN_TO_GROUND(); break;
    case GROUND:    state = state_GROUND(); break;
    case UP_TO_FLOOR: state = state_UP_TO_FLOOR(); break;
    case UP_TO_STOW: state = state_UP_TO_STOW(); break;
    case FOLDING:   state = state_FOLDING(); break;
    case CLOSING:   state = state_CLOSING(); break;
  }
}

State state_CLOSED() {
  if(digitalRead(buttonDownPin)==LOW) {
    digitalWrite(OpenPin, HIGH);
    return OPENING;
  }

  return CLOSED;
}

State state_OPENING() {
  if(digitalRead(limitOpenPin)==LOW) {
    digitalWrite(OpenPin, LOW);
    digitalWrite(deployPin, HIGH);
    return UNFOLDING;
  }

  digitalWrite(OpenPin, digitalRead(buttonDownPin)==LOW);
    
  return OPENING;
}

State state_UNFOLDING() {
  if(digitalRead(limitDeployPin)==LOW) {
    digitalWrite(deployPin, LOW);
    digitalWrite(downPin, HIGH);
    return DOWN_TO_FLOOR;
  }

  digitalWrite(deployPin, digitalRead(buttonDownPin)==LOW);
  
  return UNFOLDING;
}

State state_DOWN_TO_FLOOR() {
  if(digitalRead(limitFloorPin)==LOW) {
    digitalWrite(downPin, LOW);
    return FLOOR;
  }
  
  digitalWrite(downPin, digitalRead(buttonDownPin)==LOW);
  
  return DOWN_TO_FLOOR;
}

State state_FLOOR() {
  
  if(digitalRead(buttonDownPin)==LOW) {
    digitalWrite(downPin, HIGH);
    return DOWN_TO_GROUND;
  }
  
  if(digitalRead(buttonUpPin)==LOW) {
    digitalWrite(upPin, HIGH);
    return UP_TO_STOW;
  }
  
  return FLOOR;
}

State state_DOWN_TO_GROUND() {
  if(digitalRead(limitDownPin)==LOW) {
    digitalWrite(downPin, LOW);
    return GROUND;
  }
  
  digitalWrite(downPin, digitalRead(buttonDownPin)==LOW);
  
  return DOWN_TO_GROUND;
}

State state_GROUND() {
  if(digitalRead(buttonUpPin)==LOW) {
    digitalWrite(upPin, HIGH);
    return UP_TO_FLOOR;
  }
  
  return GROUND;
}

State state_UP_TO_FLOOR() {
  if(digitalRead(limitFloorPin)==LOW) {
    digitalWrite(upPin, LOW);
    return FLOOR;
  }
  
  digitalWrite(upPin, digitalRead(buttonUpPin)==LOW);
  
  return UP_TO_FLOOR;
}

State state_UP_TO_STOW() {
  if(digitalRead(limitDeployPin)==LOW) {
    digitalWrite(upPin, LOW);
    digitalWrite(stowPin, HIGH);
    return FOLDING;
  }
  
  digitalWrite(upPin, digitalRead(buttonUpPin)==LOW);
  
  return UP_TO_STOW;
}

State state_FOLDING() {
  if(digitalRead(limitStowPin)==LOW) {
    digitalWrite(stowPin, LOW);
    digitalWrite(ClosePin, HIGH);
    return CLOSING;
  }
  
  digitalWrite(stowPin, digitalRead(buttonUpPin)==LOW);
  
  return FOLDING;
}

State state_CLOSING() {
  if(digitalRead(buttonUpPin)==HIGH) {
    digitalWrite(ClosePin,LOW);
    return CLOSED;
  }
  
  digitalWrite(ClosePin, digitalRead(buttonUpPin)==LOW);
  
  return CLOSING;
}

Wow Paul, talk about above and beyond!! Thank you sooo much. I printed this out so I can go over and over it until I really understand. From a quick glance it looks similar to my last attempt, but yours is done the correct way where mine is a newbie pieced together mess. I need to see where I went wrong.

I'll get this loaded in later today and let you know how it goes, a million karma's to you sir!!!!!

Many thanks to PaulS, PaulMurrayCbr, AWOL and everyone else who’s posted code that I studied and learned from. This post took a big pivot from the original “which” statements I was referencing, but that’s ok - it works!

I’m still going to go back and work with PaulMurrayCbr’s post, he has a better way than what I have now. I need to make some changes due to the hardware being different. Below is the working code, you can view a video at youtube.com/watch?v=KzrlGcWe5F0 to get a better understanding of what is going on.

int buttonDownPin = 14;
int buttonUpPin = 15;
int limitOpenPin = 2;
int limitDeployPin = 3;
int limitFloorPin = 4;
int limitDownPin = 5;
int limitStowPin = 6;
int limitFoldPin = 7;
int OpenPin = 8;
int ClosePin = 9;
int deployPin = 10;
int stowPin = 11;
int downPin = 12;
int upPin = 13;
/*Stage1 //Door closed, ramp stowed, lift up
  Stage2 //Door open, ramp stowed, lift up
  Stage3 //Door open, ramp deployed, lift floor level
  Stage4 //Door open, ramp deployed, lift down*/
int Stage = 1;

void setup() {
  // put your setup code here, to run once:
  pinMode (buttonDownPin, INPUT_PULLUP);
  pinMode (buttonUpPin, INPUT_PULLUP);
  pinMode (limitOpenPin, INPUT_PULLUP);
  pinMode (limitDeployPin, INPUT_PULLUP);
  pinMode (limitFloorPin, INPUT_PULLUP);
  pinMode (limitDownPin, INPUT_PULLUP);
  pinMode (limitStowPin, INPUT_PULLUP);
  pinMode (limitFoldPin, INPUT_PULLUP);
  pinMode (OpenPin, OUTPUT);
  pinMode (ClosePin, OUTPUT);
  pinMode (deployPin, OUTPUT);
  pinMode (stowPin, OUTPUT);
  pinMode (downPin, OUTPUT);
  pinMode (upPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

  if (digitalRead (buttonUpPin) == LOW || digitalRead (buttonDownPin) == LOW) {
    OutIn();
  }

  else {
    for (int i = 8; i <= 13; i++) {
      // all outputs (8-13) off (relay board is active low)
      digitalWrite(i, HIGH);
      delay (10);
    }
  }
}

void OutIn() {
  if (Stage == 1) {
    Door();
  }
  if (Stage == 2) {
    Fold();
  }
  if (Stage == 3) {
    Floor();
  }
  if (Stage == 4) {
    Platform();
  }
}

void Door() {
  if (digitalRead (buttonUpPin) == LOW) {
    digitalWrite(ClosePin, LOW);
  }

  if (digitalRead (buttonDownPin) == LOW && digitalRead (limitOpenPin) == HIGH) {
    digitalWrite (OpenPin, LOW);
  }
  else  if (digitalRead (buttonDownPin) == LOW && digitalRead (limitOpenPin) == LOW) {
    digitalWrite (OpenPin, HIGH);
    Stage = 2;
  }
}


void Fold() {
  if (digitalRead (buttonUpPin) == LOW  && digitalRead (limitStowPin) == HIGH && digitalRead (limitFoldPin) == HIGH) {
    digitalWrite(upPin, LOW);
  }
  else  if (digitalRead (buttonUpPin) == LOW  && digitalRead (limitStowPin) == LOW && digitalRead (limitFoldPin) == HIGH) {
    digitalWrite (upPin, HIGH);
    digitalWrite (stowPin, LOW);
  }
  else   if (digitalRead (buttonUpPin) == LOW  && digitalRead (limitStowPin) == LOW && digitalRead (limitFoldPin) == LOW) {
    digitalWrite (stowPin, HIGH);
    Stage = 1;
  }



  if (digitalRead (buttonDownPin) == LOW && digitalRead (limitDeployPin) == HIGH && digitalRead (limitFloorPin) == LOW) {
    digitalWrite (deployPin, LOW);
  }
  else  if (digitalRead (buttonDownPin) == LOW && digitalRead (limitDeployPin) == LOW && digitalRead (limitFloorPin) == LOW) {
    digitalWrite (deployPin, HIGH);
    digitalWrite (downPin, LOW);
  }
  else  if (digitalRead (buttonDownPin) == LOW && digitalRead (limitDeployPin) == LOW && digitalRead (limitFloorPin) == HIGH) {
    digitalWrite (downPin, HIGH);
    Stage = 3;
  }



  //if upButton fold platform until fold limit, set to stage1
  //if downButton lower platform until floor limit, set to stage3
}
void Floor() {
  if (digitalRead (buttonUpPin) == LOW) {
    delay (1000);
    Stage = 2;
  }
  else if (digitalRead (buttonDownPin) == LOW) {
    delay (1000);
    Stage = 4;
  }
  //if upButton stop motion while button pressed, set to stage2
  // if downButton stop motion while button pressed, set to stage4
}
void   Platform() {
  if (digitalRead (buttonUpPin) == LOW && digitalRead (limitFloorPin) == LOW) {
    digitalWrite(upPin, LOW);
  }
  else  if (digitalRead (buttonUpPin) == LOW && digitalRead (limitFloorPin) == HIGH) {
    digitalWrite (upPin, HIGH);
    Stage = 3;
  }

  else if (digitalRead (buttonDownPin) == LOW) {// && (limitDownPin) == HIGH) {
    digitalWrite (downPin, LOW);
  }
//  else if (digitalRead (buttonDownPin) == LOW && (limitDownPin) == LOW) {
//    digitalWrite (downPin, HIGH);
//  }

  // if upButton raise lift to floor, set to Stage3
  // if downButton lower lift until down limit* /
}

Just realised that there's a big problem with my code. You have to hold down the button to lower the lift to floor, but as soon as the sketch is in "floor" state it says "hey! the button is down! I need to start lowering!".

I needs a flag or another state for "I am in floor state, and both buttons have been released since I got here". FLOOR_ARRIVED and FLOOR_READY, perhaps.