Pushbutton Dillema

Hi all,

I have an issue i can't seem to figure out.
I am just starting out with everything so give me a break.

its a little tricky to understand but hopefully i can explain..

i have a loop sequence which contains 3 loops within it. 1,2,3.
before loop 1 there is a "button read" loop. so you could say there is a 4th. we will call it button limbo. button limbo is where the loop continuously reads the state of the button and waits for a button HIGH to enter the 3 loop sequence.

i have already coded the loops to flow from 1-2-3 with the push of a button and then once loop 3 is finished it goes back to reading the button in button limbo.

basically i would like a pushbutton to start my 3 loop sequence from loop 1 on its rising edge.
during any of the 3 loops i want to be able to press the button again and it will jump back to the beginning of my 1st loop in the sequence and start the 3 loop sequence again from no. 1. thru to 3.

i have tried adding digitalRead for the button into each loop and so i can start the loop again and again every time i press the button and it works perfectly..
BUT
when i hold the button down it starts loop 1 but then it jumps back to the button limbo and starts loop 1 again and then jumps back to limbo etc.
this is because loop 1 is told if the button reads high to start loop1 again, so it does and it gets stuck in a continuous loop of its own.

i want to be able to press the button and it will start the sequence and hold the button and it won't affect the sequence and it will finish the 3 loop sequence or until i press the button again for it to repeat. etc

basically i want the pushbutton only to start the loop on the rising edge and do nothing at all if it is held down from that first press. until it is pressed again and repeated. etc.

i have been thinking about this for days and my hair is falling out.
I've tried using edgeDetection (but i don't need to count it i just need to detect the rising edge..??) and i just don't think my brain is that bit big enough to realise what to do here.

the code is full of unrelated confidential things so i can't share it and i know that makes everything harder for you all to understand,
SO i have created another code which is basically the same but stripped right back so you guys can give it a try :~)

if you put this code in your IDE and view the serial monitor with a button on pin 5 it should all make sense now.

// Rex's hypothetical button scenario.



unsigned long time_since_last_reset = 0;

int l1Time = 1000;                    //ie.  Milliseconds
int l2Time = 1000;                    //ie.  Milliseconds
int l3Time = 1000;                    //ie.  Milliseconds

const byte buttonPin = 5;                 // pin  which button is attached to

int buttonState = 0;                    //current state of button


void setup() {
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);
  

}

void loop() {

  // read the state of the button and assign it to the variable
  boolean buttonPressed = digitalRead(buttonPin);
  //display the button state in the monitor
  Serial.print("Button Limbo = ");
  Serial.println(buttonPressed);



BUTTON:


  int reading = digitalRead(buttonPin);
  buttonState = 0;


  if (buttonPressed == HIGH) {

    goto START;



START:


    ///////////////////////////////LOOP1//////////////////////////////////////

  
    time_since_last_reset = millis();     //obtain the reference
    while ((millis() - time_since_last_reset) < l1Time) {
      
      boolean buttonPressed = digitalRead(buttonPin);
      Serial.println("LOOP 1"); Serial.print("    ");
      Serial.print("Button State = ");
      Serial.print(buttonPressed); Serial.print("    ");


      l1Time = 500;


      delay(50);


    }

    Serial.println(""); Serial.println(""); Serial.print("    ");
    ///////////////////////////////LOOP2////////////////////////////////////

LOOP2:


    time_since_last_reset = millis();     //obtain the reference
    while ((millis() - time_since_last_reset) < l2Time) {
      
      boolean buttonPressed = digitalRead(buttonPin);
      Serial.println("LOOP 2"); Serial.print("    ");
      Serial.print("Button State = ");
      Serial.print(buttonPressed); Serial.print("    ");


      l2Time = 400;

      delay(50);
    }

    Serial.println(""); Serial.println(""); Serial.print("    ");

    //////////////////////////////LOOP3////////////////////////////////////
LOOP3:


    time_since_last_reset = millis();
    while ((millis() - time_since_last_reset) < l3Time) {
      
      boolean buttonPressed = digitalRead(buttonPin);
      Serial.println("LOOP 3"); Serial.print("    ");
      Serial.print("Button State = ");
      Serial.print(buttonPressed); Serial.print("    ");



      l3Time = 600;

      delay(50);
    }
  }
}

press the button once and it will run 3 loops.
hold the button down it will run the 3 loops but then start loop 1 again.
i want the HELD button to do nothing to the sequence ONLY that first rising edge.
so you can press and hold and it will run the sequence and then sit on button limbo until you lift and press again.
i ALSO want to be able to press the button during say loop 2 and it will jump straight back to the start of loop 1.

sorry to be so thorough, i just cannot figure this out and i know its something simple.

please and thank you,
RR

i have created another code which is basically the same but stripped right back so you guys can give it a try

Did you forget to post the code ?

Welcome to the Forum. Please read this post:

How to use this forum - please read.

Please post your code using code tags. The code tags make the code look

like this

when posting source code files. It makes it easier to read, and can be copied with a single mouse click. Also, if you don't do it, some of the character sequences in the code can be misinterpreted by the forum code as italics or funny emoticons.

Your code is only 2.3k. Unless the sketch is too large, it's better if you post your code, rather than attach it. When it's attached, we have to download it, create a folder then open your code in our IDE. And afterwards, the folder remains unless we navigate to the "Temp" folder and manually remove it. It's much easier to just view the code in your post.

ok, should be better now.
sorry and thank you
RR

    goto START;

No. Just no. Redo the entire thing without using goto's.

goto START;

and the next line is

START:

Doesn't matter, the compiler will optimize it. :slight_smile:

but if you had to use the goto's could you do it?

the goto's don't make sense in the hypothetical sketch obviously.

if you had to use the goto's could you do it?

Yes, but why would you ?

in the original sketch there are different analog ins which determine which loop to go to and where to start depending on sensor variables. hence why i decided to go with the goto's.

i know everyone hates goto's but can you imagine you just had to do this as if there was no other way.

any ideas on the button ?

rexrick:
in the original sketch there are different analog ins which determine which loop to go to and where to start depending on sensor variables. hence why i decided to go with the goto's.

i know everyone hates goto's but can you imagine you just had to do this as if there was no other way.

any ideas on the button ?

There is another way. Assuredly many ways. Your first sentence is self referential. It's like saying, "I have to clean the floor with a toothbrush, that's why I must use a toothbrush". Use a mop, like everyone else. Or don't ask for help doing it.

basically i would like a pushbutton to start my 3 loop sequence from loop 1 on its rising edge.
during any of the 3 loops i want to be able to press the button again and it will jump back to the beginning of my 1st loop in the sequence and start the 3 loop sequence again from no. 1. thru to 3.

This sounds like an ideal candidate for a state machine. It sounds scary but its not.
Write down each of the states that the program could be in. Perhaps

state 0 - waiting for the user to press the start button
state 1 - executing code in loop1 (whatever that is)
state 2 - executing code in loop2 (whatever that is)
state 3 - executing code in loop3 (whatever that is)

Write down the exit conditions for each state and the state that will be moved to when the condition is met
In state 0 - exit if user presses start button and move to state 1
In state 1 - exit when complete and move to state 2
or exit when the user press the start button and move to state 0
In state 2 - exit when complete and move to state 3
or exit when the user press the start button and move to state 0
In state 1 - exit when complete and move to state 0
or exit when the user press the start button and move to state 0

Write the code for each state and test it independently. None of the code should block the free running of the loop() function so no delay()s or whiles. Your loop1, 2 and 3 code will need to be changed so that it checks whether the required time has passed (use an if) rather than sittong in a while loop until the time has passed.

Write the program using switch/case with state as the switch variable.
Only the code for the current state will be executed inside the switch/case but you can read the state of the start button at each pass through the freely running loop() function to keep the program responsive.

Not a goto in sight and free running, responsive code