Button control

Turning a stepper forward and backward with each push of a button. The loop should go around and around, repeatedly going forward and backward with each button press.

Should be easy but it’s not!

This code does not work. It only turns the stepper one time. It does not return to it’s previous position on the second button press. It should return on the second press, and it should go forward and backward repeatedly:

#include <Tic.h>


#ifdef SERIAL_PORT_HARDWARE_OPEN
#define ticSerial SERIAL_PORT_HARDWARE_OPEN
#else
#include <SoftwareSerial.h>
SoftwareSerial ticSerial(10, 11);
#endif

TicSerial tic(ticSerial);


int buttonState = 0;
//this is the button function
void buttonWait(int buttonPin) {
  int buttonState = 0;
  while (1) {
    buttonState = digitalRead(buttonPin);
    if (buttonState == LOW) {
      return;
    }
  }
}
void setup()
{

  pinMode(3, INPUT_PULLUP);
  // Set the baud rate.
  ticSerial.begin(9600);

  delay(20);

  // Set the Tic's current position to 0, so that when we command
  // it to move later, it will move a predictable amount.
  tic.haltAndSetPosition(0);

  // Tells the Tic that it is OK to start driving the motor.  The
  // Tic's safe-start feature helps avoid unexpected, accidental
  // movement of the motor: if an error happens, the Tic will not
  // drive the motor again until it receives the Exit Safe Start
  // command.  The safe-start feature can be disbled in the Tic
  // Control Center.
  tic.exitSafeStart();
}

// Sends a "Reset command timeout" command to the Tic.  We must
// call this at least once per second, or else a command timeout
// error will happen.  The Tic's default command timeout period
// is 1000 ms, but it can be changed or disabled in the Tic
// Control Center.
void resetCommandTimeout()
{
  tic.resetCommandTimeout();
}

// Delays for the specified number of milliseconds while
// resetting the Tic's command timeout so that its movement does
// not get interrupted by errors.
void delayWhileResettingCommandTimeout(uint32_t ms)
{
  uint32_t start = millis();
  do
  {
    resetCommandTimeout();
  } while ((uint32_t)(millis() - start) <= ms);
}

// Polls the Tic, waiting for it to reach the specified target
// position.  Note that if the Tic detects an error, the Tic will
// probably go into safe-start mode and never reach its target
// position, so this function will loop infinitely.  If that
// happens, you will need to reset your Arduino.
void waitForPosition(int32_t targetPosition)
{
  do
  {
    resetCommandTimeout();
  } while (tic.getCurrentPosition() != targetPosition);
}

void loop() {
  { buttonWait(3); // wait for button press on pin 10
    tic.haltAndSetPosition(0);
    tic.exitSafeStart();
    resetCommandTimeout();
    tic.setTargetPosition(160.6667);
    waitForPosition(160.6667);

  }{
    //the Mega board rotates the stepper properly the first time, then stops
    //here and does nothing more on any button press.
    buttonWait(3); // wait for button press on pin 10
    // Tell the Tic to move to position 100, and wait until it gets
    // there.
    tic.haltAndSetPosition(0);
    tic.exitSafeStart();
    tic.resetCommandTimeout();
    tic.setTargetPosition(-160.6667);
  }{
    waitForPosition(-160.6667);


  }
}

You need to detect when the state of the input changes, not its current state

See the StateChangeDetection example in the IDE

One releases the button immediately, putting it back into HIGH. Then the stepper turns. Waiting for the next LOW should be quite effective.

I got it working fine.

There was a problem with the Pololu instructions, there was no problem with the button recognition. It might be possible to use the input changes to run the button, but with this simple while loop you can indeed get nice button response.

Thanks!

with this simple while loop you can indeed get nice button response.

Until the time comes when blocking code like that causes a problem, but it is probably OK in this use case

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