Why is my code after the do..while loop not executing?

Hi everyone. I am an Arduino newbie, but I have started my first diy project which is a cargo lift that utilizes a discarded garage door opening system and is controlled by an Arduino Uno R3. Basically, my Arduino circuit is supposed to:

  1. read the state of two remote momentary on/off switch buttons to detect any button pressed event
  2. if either button is pressed momentarily, then a NO relay is closed for a half second and then opened
    (which simulates pressing the manual garage door switch on a typical garage door system)
  3. this momentary relay close starts the cargo trolley moving as the motor kicks on
  4. after waiting 2 seconds for the trolley to leave one end of the lift, I continuously read two IR collision detectors to see when the trolley arrives at the other end of the lift
  5. when either one of the IR sensors reports a detection, I stop my sensor reading do...while loop and execute the trolley has arrived at one end code
  6. upon arrival, I perform the same NO relay toggle to signal the garage door motor to stop
  7. my code should return to the top of the main loop and read the momentary switches again to watch for the next operator press

PROBLEM: when I press the button, the NO relay code seems to be executed, but the trolley has arrived code after the do..while IR sensors read loop doesn't seem to execute. The relay doesn't toggle. But, if I press the button, then the relay toggles like my code went back to the start of the main loop without executing the trolley arrival stop code. Note that the IR sensors do work, and the one on Pin 13 toggles the Arduino Uno's onboard LED. Clearly I am not understanding something fundamental here.

[code]
const int topPin=13;
const int botPin=12;
const int buttonPin=2;
const int relayPin=7;
int buttonState=1;
int topState=1;
int botState=1;

void setup() {
  // put your setup code here, to run once:
  pinMode(buttonPin, INPUT_PULLUP);//connected to Operator button
  pinMode(topPin, INPUT);//sensor at top of stairs
  pinMode(botPin, INPUT);//sensor at bottom of stairs near motor
  pinMode(relayPin, OUTPUT);//connected to signal terminal of relay
  
}

void loop() {
  // put your main code here, to run repeatedly:
  buttonState = digitalRead(buttonPin);// button pressed or not
  if(buttonState == LOW){
    digitalWrite(relayPin,HIGH);//turn relay on
    delay(500);//keep on for half sec for a brief pulse to move trolley
    digitalWrite(relayPin,LOW);//turn relay off to end the move pulse
    // trolly has started moving
    delay(2000);//wait for trolley to leave a station
    do {
      topState = digitalRead(topPin);
      botState = digitalRead(botPin);
      } 
    while (topState==HIGH && botState==HIGH); //read IR sensors while trolley not at either end
    // trolley has arrived at one end so execute stop sequence pulse
    digitalWrite(relayPin,HIGH);//to stop trolley turn relay on
    delay(500);//keep on for half sec for a brief pulse to stop trolley
    digitalWrite(relayPin,LOW);//turn relay off to end the stop pulse
    // trolley is parked at top or bottom
   }
// return to button state reading at beginning of main loop   
}

[/code]

My Circuit Diagram.jpg

My Circuit Diagram.jpg

You are checking for the state of your button not for a CHANGE in the state of your button. Since all of your code is within the if statement of your button state check that code only executes while you are HOLDING the button down.

Also calling delay() function is bad news when detecting button presses. You should time everything using millis() and a state machine.

Thanks for your reply Todd!

So you are saying that as my main loop starts to execute code sequentially, a button press read of a momentary NO switch that detects it got pressed momentarily will not result in the following conditional code's execution unless the button remains pressed?

That would mean that the conditional code in an IF statement ceases to be executed as soon as the IF expression is no longer true, even if execution of the dependent code has already begun?

Or is it that the duration of the pressed button state is so short that the IF buttonState == LOW event is still being evaluated when the buttonState quickly returns to its normal HIGH (Normally Open) as the momentary button springs back as the finger disengages?

I would have thought that code execution happens so fast that even a momentary buttonState == LOW would trigger the IF statement's code and execution would plow onward without looking back to see that the buttonState had rebounded back to HIGH?

If you are right, then it seems like an IF statement's conditional code terminates IMMEDIATELY if the IF Condition becomes FALSE. (That implies that the IF statement monitors the condition expression evaluation constantly, not just at the beginning of the conditional code section.) Is this a correct understanding of how the IF statement actually works?

while (topState==HIGH && botState==HIGH);

Where in that while loop do you do anything that would change topState or botState?

[Edits, lots of edits; doing this on a mobile phone is hard work!]

Perry, it’s a ‘do/while’

do {
topState = digitalRead(topPin);
botState = digitalRead(botPin);
}
while (topState==HIGH && botState==HIGH);

Thanks larryd!

Yes, that Do...While loop keeps reading the IR obstacle sensors until one of them detects the arrival of the cargo trolley. As soon as trolley arrival is detected, my code exits the Do...While loop and runs the "toggle the relay" code to generate a "stop the trolley" signal to the garage door motor.

Thanks Larry,
The perils of reading code on a tiny screen.

I tried the standard push button "state change" code, but I got the same result.

So, I am trying to debug using the Serial Monitor by inserting some Serial.print commands in key places in my code.

I'll report back with what I find.

In the meantime, if anyone else can critique my code for why it doesn't execute correctly I would love to hear an informed analysis.

P.S. I may also try the capacitor switch debounce solution to see if that might help.

I tried the standard push button "state change" code, but I got the same result.

Please post what you tried

So, I used serial monitor along with strategically placed print messages & some delays to debug my code.

What I found out was that one of my IR sensors wasn't reading properly because it was plugged into the wrong header pin, so the Do While loop wasn't working as intended.

Also, I misunderstood the internal pullup resistor wiring and had an actual connection from the switch to the +5VDC pin on the Uno. I didn't realize that the internal pullup is also powered internally so the pin doesn't need an external connection to 5V. Duh!

So, the code works perfectly on my test bench, and I'm ready to mount all the components into enclosures and then on to my diy cargo lift for live testing. (My niece's boyfriend is designing enclosures for the IR Obstacle Detection Sensors and he'll 3D print them for me so I can mount them in a ruggedized configuration.)

Here's what the Cargo Lift looks like at present, before the control system is installed:

What cargo are you lifting?

I'm moving boxes, plastic bins, plastic trash bags, and lots of stuff from 80 years of middleclass family life in two separate houses.

The cargo lift will eliminate the need to carry items up the basement stairs repeatedly.

Instead, workers in the basement will load items onto the lift and push the send button. Workers at the top of the stairs will take the items off the lift and press the return button to send the cargo trolley back down to the basement for the next load.

That should make this double move much easier for all involved.

NOTE: a garage door opener is a pretty powerful motorized lift. So powerful that safety sensors are also required to make sure that if someone falls on the tracks they won't get seriously injured by the high torque of the electric motor.

You've seen my basement- I should build something similar when we move.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.