Momentary button press to run code once - stuck

Hi, i need to run a sequence on a stepper motor when a momentary button is pressed, sequence should run once then wait for next button press, not been able to find what i need from searching, my code so far below, at the moment i have to hold the button and it runs continuous as i do

any help appreciated

const int stepPin = 1;
const int dirPin = 2;
const int buttonPin = 3;

int buttonState = 0;

void setup() {

pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
pinMode(buttonPin, INPUT);

while (digitalRead(buttonPin) == LOW) {}
}
void loop() {

if (buttonState == HIGH) {
digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction
// Makes 200 pulses for making one full cycle rotation
for(int x = 0; x < 3400; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);
}
delay(500); // One second delay

digitalWrite(dirPin,LOW); //Changes the rotations direction
// Makes 1600 pulses for making two full cycle rotation
for(int x = 0; x < 400; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);
}
digitalWrite(dirPin,HIGH); //Changes the rotations direction
// Makes 1600 pulses for making two full cycle rotation
for(int x = 0; x < 400; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);
}
digitalWrite(dirPin,LOW); //Changes the rotations direction
// Makes 1600 pulses for making two full cycle rotation
for(int x = 0; x < 400; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);
}
digitalWrite(dirPin,HIGH); //Changes the rotations direction
// Makes 1600 pulses for making two full cycle rotation
for(int x = 0; x < 400; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);
}
digitalWrite(dirPin,LOW); //Changes the rotations direction
// Makes 1600 pulses for making two full cycle rotation
for(int x = 0; x < 400; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);
}
digitalWrite(dirPin,HIGH); //Changes the rotations direction
// Makes 1600 pulses for making two full cycle rotation
for(int x = 0; x < 400; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);
}
digitalWrite(dirPin,LOW); // Enables the motor to move in a particular direction
// Makes 200 pulses for making one full cycle rotation
for(int x = 0; x < 3400; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);
}
//want loop to stop here until button pressed again, dont know how
}
}

i don't think this while (digitalRead(buttonPin) == LOW) {}

should be in setup()

it should be the "one-time" loop-code in loop().
(you whole code is in that while() and the whole thing is in loop() )

you might have to do some debouncing though.

@BabyGeezer ive seen conflicting for that part, found it on another post and someone said to put in loop but then 2 others said to put in setup :confused:

OP's original code:

const int stepPin = 1; 
const int dirPin = 2; 
const int buttonPin = 3; 
 
int buttonState = 0;
 
void setup() {
  
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  pinMode(buttonPin, INPUT);
   
   while (digitalRead(buttonPin) == LOW) {}
}
void loop() {

  
  if (buttonState == HIGH) {
    digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction
  // Makes 200 pulses for making one full cycle rotation
  for(int x = 0; x < 3400; x++) {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(500); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(500); 
  }
  delay(500); // One second delay
  
  digitalWrite(dirPin,LOW); //Changes the rotations direction
  // Makes 1600 pulses for making two full cycle rotation
  for(int x = 0; x < 400; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  } 
    digitalWrite(dirPin,HIGH); //Changes the rotations direction
  // Makes 1600 pulses for making two full cycle rotation
  for(int x = 0; x < 400; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  }
      digitalWrite(dirPin,LOW); //Changes the rotations direction
  // Makes 1600 pulses for making two full cycle rotation
  for(int x = 0; x < 400; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  } 
    digitalWrite(dirPin,HIGH); //Changes the rotations direction
  // Makes 1600 pulses for making two full cycle rotation
  for(int x = 0; x < 400; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  } 
     digitalWrite(dirPin,LOW); //Changes the rotations direction
  // Makes 1600 pulses for making two full cycle rotation
  for(int x = 0; x < 400; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  } 
    digitalWrite(dirPin,HIGH); //Changes the rotations direction
  // Makes 1600 pulses for making two full cycle rotation
  for(int x = 0; x < 400; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  }
    digitalWrite(dirPin,LOW); // Enables the motor to move in a particular direction
  // Makes 200 pulses for making one full cycle rotation
  for(int x = 0; x < 3400; x++) {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(500); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(500); 
  }
  //want loop to stop here until button pressed again, dont know how
  }
}

The "while (digitalRead(buttonPin) == LOW) {}" in setup is not needed - unless, one just wants to hang out in the setup() function until a button is pressed.

Once a button is pressed, it moves on to the void loop() function and does stuff while the button is pressed; in this case, buttonState remains HIGH because it's last pin read was in the void setup().

I would only do something when the oldButton state differs from the newButton state - then, do this stuff.

//const int stepPin = 1; 
//const int dirPin = 2; 
const int buttonPin = 3; 
 
int buttonState = 0;
int oldbuttonState = 0;

void setup() {
  
  //pinMode(stepPin,OUTPUT); 
  //pinMode(dirPin,OUTPUT);
  pinMode(buttonPin, INPUT);

}

void loop(){
  
  buttonState = digitalRead(buttonPin);
  if (oldbuttonState != buttonState && buttonState == HIGH) {
    Serial.println("You told me to print.");
  }
  oldbuttonState = buttonState;
}

Secondly, is your stepin sharing with TX for serial communications?

thanks, using a trinket which i dont believe supports serial, i wont pretend to understand much of what you said but i tried the code and it behaves the same

(removed some stepper stuff to make more concise)

// defines pins numbers
const int stepPin = 1;
const int dirPin = 2;
const int buttonPin = 3;

int buttonState = 0;
int oldbuttonState = 0;

void setup() {

// Sets the two pins as Outputs
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(buttonPin, INPUT);

while (digitalRead(buttonPin) == LOW) {}
}
void loop() {

buttonState = digitalRead(buttonPin);
if (oldbuttonState != buttonState && buttonState == HIGH) {

}
oldbuttonState = buttonState;

//buttonState = digitalRead(buttonPin);

//if (buttonState == HIGH) {
digitalWrite(dirPin, HIGH); // Enables the motor to move in a particular direction
// Makes 200 pulses for making one full cycle rotation
for (int x = 0; x < 3400; x++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin, LOW);
delayMicroseconds(500);

}

}

sorry, just removed the usb pin i had in (picture in prev post) and it kinda works, i have a high pitched noise until i press the button and the loop runs, however the loop runs continuously, how do i get it to stop after one run?

i presume the noise is from the switch or noise in the circuit...

Here is your loop() code formatted for readability using the autoformat feature of the IDE (CTRL-T or Tools, Auto Format).

void loop()
{
   buttonState = digitalRead(buttonPin);
   if (oldbuttonState != buttonState && buttonState == HIGH)
   {
      // ******  put for loop and all conditional code here to execute only 
      // ******  on state change from low to high
   }
   oldbuttonState = buttonState;  
   digitalWrite(dirPin, HIGH); // Enables the motor to move in a particular direction
   // Makes 200 pulses for making one full cycle rotation
   for (int x = 0; x < 3400; x++)
   {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(500);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(500);
   }
}

You see that the for loop is executing unconditionally, independent of state of the switch.

i presume the noise is from the switch or noise in the circuit...
delayMicroseconds(500);

That is a pretty fast speed to start a stepper without acceleration. Lower to maybe 50 -100 milliSeconds (0.05 - 0.1 seconds) for testing.

Do you have a pulldown resistor on the switch input?

Please remember to use code tags.

@groundFungus thanks, i had run the auto format but it didnt work when i 1st tried (just left aligned everything) fine now though

anyhoo thought switch was working but its not really, have to hold down for loop to run, have put a resistor in the pull down config but doesnt change anything

i copied the stepper code from somewhere else, i would like it to accelerate rather that jerk to a start but not sure how to do that, just concerned with getting a momentary press to start the sequence and only run once, had no idea such a seemingly simple thing would be so hard

i dont really understand your edit to be honest, also what do you mean by "code tags"

Here is a demo sketch that waits for the button to be pressed and when pressed will output 200 pulses to the stepper, one time, then wait for another button press. Tested on my Uno with LEDs in place of stepper. Maybe this will clarify what I said in reply #7. You will need to change the pin numbers to pins on your Arduino.

const byte dirPin = 2;
const byte stepPin = 3;
const byte buttonPin = 4;

boolean buttonState = LOW;
boolean oldbuttonState = LOW;

void setup()
{
   //Serial.begin(115200);
   pinMode(dirPin, OUTPUT);
   pinMode(stepPin, OUTPUT);
   pinMode(buttonPin, INPUT);
   digitalWrite(dirPin, LOW);
}

void loop()
{
   buttonState = digitalRead(buttonPin);
   if (oldbuttonState != buttonState)
   {
      if (buttonState == HIGH) // button went from off to on
      {
         digitalWrite(dirPin, HIGH); // Enables the motor to move in a particular direction
         // Makes 200 pulses for making one full cycle rotation
         for (int x = 0; x < 200; x++)
         {
            digitalWrite(stepPin, HIGH);
            delay(100);
            //delayMicroseconds(5000);
            digitalWrite(stepPin, LOW);
            delay(100);
            //delayMicroseconds(5000);
         }
      }
      oldbuttonState = buttonState;
   }
}

If autoformat doesn't seem to work right, that means that there is an error in your coding, usually misplaced brackets or missing semicolon.

Look here to learn about code tags. See #7.

groundFungus thank you very much, pretty much working with this though currently beyond frustrating as i cant get it to work consistently, think im gonna progress to perf board with soldered parts and wires as i think the paperclips and breadboard are introducing issues