Joystick Button should stay pressed after pressed once

Hello!

I want to use a joystick button to start a if-statement in the void loop, so if I press the button once, the button will stay pressed.

I have tried to write the code but it the pushbuttonstate does not stay pressed as I want to.

const int Joystick_X = A0; 
const int Joystick_Y = A1;
const int pushbutton = 3;
int JoystickValue_X = 0; 
int JoystickValue_Y = 0;
int pushbuttonState;



void setup() {
  pinMode(Joystick_X, INPUT); // X-axis
  pinMode(Joystick_Y, INPUT); // Y-axis
  pinMode(pushbutton,INPUT); // press button
  digitalWrite(pushbutton, HIGH);
  
  Serial.begin(9600); 

}

void loop() {
  pushbuttonState = digitalRead(pushbutton);  
  Serial.print(pushbuttonState); 

    if (pushbuttonState == 0) {
      digitalWrite(pushbuttonState, 0);
      Serial.print(JoystickValue_X);
      Serial.print(";");
      Serial.print(JoystickValue_Y);
      Serial.print(";");
      Serial.println(pushbuttonState);
    }
    else {
      Serial.println("done.");
    }

}

You are setting the value of pushbuttonState each time through loop() so no wonder it does not stay at the same value when the button is released

If pushbuttonState is already in the pushed state then don't read its value again

Why are you doing this?

From the digitalWrite() reference:

"If the pin is configured as an INPUT , digitalWrite() will enable (HIGH ) or disable (LOW ) the internal pullup on the input pin. It is recommended to set the pinMode() to INPUT_PULLUP to enable the internal pull-up resistor. See the Digital Pins tutorial for more information."

I thought I would need to set the pushbutton to 0, because if I only press it once, it won't stay pressed

And each time the loop starts again, the pushbuttonstate will then stay 0... at least that was my thought

Delete that line and do as I suggest. Ignore the button once it has been pressed

Now it already starts as pressed button.

But I want to start the loop only once I press it

Seems like a simple porblem but I can't think of a solution :confused:

Is it the loop() function that you want to start once the button is pressed ? If so then read its state in setup() and only leave setup() once the button is pressed

If you are trying to do something else then please explain in more detail

Well actually I want to start the loop once the button is pressed once.
If nothing is pressed, nothin should happen yet.

Later on I want the loop to automatically stop , once a certain time has expired or another conditions is fulfilled.

I am trying to reach that step by step

How do I "leave setup() once the button is pressed"?

  while (digitalRead(pushbutton) == HIGH);   //EDITED

Put that as the last line in setup()

I am reading the state now in setup, like you suggested, but now it is constantly 1 even if I push the button


void setup() {
  pinMode(Joystick_X, INPUT); // X-axis
  pinMode(Joystick_Y, INPUT); // Y-axis
  pinMode(pushbutton,INPUT); // press button
  digitalWrite(pushbutton, HIGH);
  pushbuttonState = digitalRead(pushbutton);
  Serial.begin(9600); 

}
 
void loop() {


    if (pushbuttonState == 0) {
      digitalWrite(pushbutton, 0);
      Serial.print(JoystickValue_X);
      Serial.print(";");
      Serial.print(JoystickValue_Y);
      Serial.print(";");
      Serial.println(pushbuttonState);
    }
   else {
     Serial.println("done.");
    
   }
}

I added the line but the pushbutton does not change its state once pressed

But once you read it you ignore it's state and setup() ends

On a more general matter, I suggest that you use INPUT_PULLUP in pinMode instead of writing HIGH after using INPUT to turn on the internal pullup resistor as it is so much more obvious what you are doing

okay my code now looks like this:


void setup() {
  pinMode(Joystick_X, INPUT); // X-axis
  pinMode(Joystick_Y, INPUT); // Y-axis
  pinMode(pushbutton,INPUT); // press button
  digitalWrite(pushbutton, INPUT_PULLUP);
  pushbuttonState = digitalRead(pushbutton);
  Serial.begin(9600); 
  while (digitalRead(pushbutton) == HIGH);

}
 
void loop() {

    if (pushbuttonState == 0) {
      digitalWrite(pushbutton, 0);
      Serial.print(JoystickValue_X);
      Serial.print(";");
      Serial.print(JoystickValue_Y);
      Serial.print(";");
      Serial.println(pushbuttonState);
    }
   else {
     Serial.println("done.");
    
   }
}

It now starts once I press the button (yay). However it prints out "done.", which means that the button does not stay 0 once I press it

Your code is now in a real mess I am afraid, but it can be fixed

Let's start with the basics. If I remember correctly from another of your topics the button is connected between the pin (it was a different pin in the other topic) and GND so the pin will go LOW when the button is pressed, hence the use of INPUT_PULLUP to turn on the built in pullup resistor, but you do that in pinMode(), not with digitalWrite()

With that in mind, here is the corrected code up to the end of setup()

const int Joystick_X = A0; 
const int Joystick_Y = A1;
const int pushbutton = 3;
int JoystickValue_X = 0; 
int JoystickValue_Y = 0;
int pushbuttonState;

void setup()
{
  pinMode(Joystick_X, INPUT); // X-axis
  pinMode(Joystick_Y, INPUT); // Y-axis
  pinMode(pushbutton, INPUT_PULLUP); // press button
  Serial.begin(9600);
  while (digitalRead(pushbutton) == HIGH);
}

Once you press the button the loop() function will start. In loop() there is no need to test the value of pushbuttonState unless you want the button to make the code do something else so you could just write

void loop()
{
  Serial.print(JoystickValue_X);
  Serial.print(";");
  Serial.println(JoystickValue_Y);
}

but note that the joystick values will not change because you are not reading the joysticks in loop()

ooh right, yes thank you!! Works great!

Do you understand what was wrong with your sketch and how this one works ?

Yeah I think so, if I understand correctly the Joystick Input_Pullup gives the joystick constantly the state of being HIGH, so as long as the button is unpressed it will stay in void setup()

If I press the button it will go to void loop and I dont need to redefine the state as it is already in the loop

Correct

If you want to use the button to initiate some action whilst in loop() you can, of course, read its state and act upon it