Help with code for Stepper motor, FSR and Button

Hi there,
I am currently working on a project, I am a kind of new to this and was wondering if I could get a little bit of help in getting it to work.

My circuit includes a stepper motor (step connected to pin 2 and direction connected to pin 3), a button (connected to pin 5) and a force sensitive resistor (connected to A0) and 2x 10k ohm
resistors for the button and the FSR.

I would like my circuit to work in the following way.
When the FSR detects a force of 500 or more pressed for 1 second or longer, the stepper motor turns 10 revolutions clockwise at 60rpm. However if the button is pressed for 2 seconds or less, and is released before the 10 revolutions have been achieved, the motor will stop exactly where it is when the button is released.
Then once the motor has stopped turning, if the button is held down for 5 seconds or longer, the motor will reset to it's starting position by turning anticlockwise (either 10 revolutions anticlockwise or however many revolutions it took if the motor was stopped early).

The stepper motor I am using is: https://uk.rs-online.com/web/p/stepper-motors/1805279

It is a 6 wire stepper motor but I am leaving the centre tap wires disconnected as I only want unipolar motion, so want it to function as if it was a 4 wire motor.

The FSR I am using is: https://uk.rs-online.com/web/p/force-sensors/2122467

The button I am using is: https://www.amazon.co.uk/Sourcingmap-6x6x4-5mm-Momentary-Tactile-Button/dp/B008DS1GY0/ref=sr_1_5?crid=31KFV36P2EBCV&dib=eyJ2IjoiMSJ9.ouuEYMaHYxSRFWXCEQysaHhp6xBqMoOtUcqnhUBrRYq3wBQCqYKampy0YsJhiklmnQGSEN0LzGupGg6ypa44KHBCRUQekM7bve64OnRWYLVcKYFii9q7m22ukmtFRUpq0Zb73wf9KoLSBB8OxcNvpWvIZLIjwqbucgwu3LsjiX7vFFbT0Lc8ypklJgeybN4zVJqO3Ptq5LyVDNBLS5fyB08aKzOK-JbPv5wl7sekuDzMIouwm9L2YphBwAkGqXcTXLw1-po8G8iWfeyTj53eUlDFIP6wOeNJ8c3lMu9K2PM.GqAiU-inds3tDWJwUL4IwVLbZ6oqyQZjL1v5AoN8iRU&dib_tag=se&keywords=4+pin+momentary+push+button+switch&qid=1712926497&refinements=p_72%3A419153031&rnid=419152031&sprefix=4+pin+momentary+push+button+switch%2Caps%2C92&sr=8-5

I have included a wiring diagram and the code currently used.

Any help would be much appreciated. Thank you!

#include <Stepper.h>

// Define number of steps per revolution
const int stepsPerRevolution = 200;

// Define FSR pin
const int fsrPin = A0;

// Define stepper motor pins
const int stepPin = 2; // Changed to pin 2
const int dirPin = 3;  // Changed to pin 3

// Define button pin
const int buttonPin = 5;

// Create stepper object
Stepper myStepper(stepsPerRevolution, stepPin, dirPin);

// Define variables
unsigned long startMillis = 0;
unsigned long currentMillis = 0;
const unsigned long sensingInterval = 1000; // Sensing interval in milliseconds
const int forceThreshold = 500; // Force threshold for activation
bool stopMotor = false;
long stepsTaken = 0; // To keep track of steps during clockwise rotation
bool clockwiseRotationComplete = false;

void setup() {
  // Set up the FSR pin as input
  pinMode(fsrPin, INPUT);
  // Set up the motor pins
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  // Set up the button pin
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  // Read the value from the FSR
  int fsrValue = analogRead(fsrPin);

  // Check if the force is above the threshold
  if (fsrValue >= forceThreshold) {
    // If force is detected, start the timer
    if (startMillis == 0) {
      startMillis = millis();
    }
    // Check if the elapsed time is more than the sensing interval
    currentMillis = millis();
    if (currentMillis - startMillis >= sensingInterval) {
      // If the sensing interval has passed, rotate the motor
      rotateMotor();
      // Reset the timer
      startMillis = 0;
    }
  } else {
    // If force is not detected, reset the timer
    startMillis = 0;
  }

  // Check if the button is pressed
  if (digitalRead(buttonPin) == LOW) {
    // Start the timer when the button is pressed
    unsigned long buttonPressStart = millis();
    // Wait for the button to be released or timeout after 2 seconds
    while (digitalRead(buttonPin) == LOW && millis() - buttonPressStart < 2000) {
      delay(10);
    }
    // If the button is released before 2 seconds, stop the motor
    if (millis() - buttonPressStart < 2000) {
      stopMotor = true;
    } else if (millis() - buttonPressStart >= 5000) {
      // If the button is held for 5 seconds or more, return the motor to its starting position anticlockwise
      returnToStart();
    }
  }

  // If the motor was stopped by the button, update the flag
  if (stopMotor) {
    stopMotor = false;
    clockwiseRotationComplete = false;
  }
}

// Function to rotate the motor 10 revolutions at 60 RPM
void rotateMotor() {
  // Set the direction to clockwise
  digitalWrite(dirPin, HIGH);

  // Calculate the delay between steps based on RPM
  int rpm = 60;
  int delayBetweenSteps = 60000 / (stepsPerRevolution * rpm);

  // Rotate the motor for 10 revolutions or until stopped
  for (int i = 0; i < 10 * stepsPerRevolution && !stopMotor; i++) {
    // Step the motor
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(delayBetweenSteps);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(delayBetweenSteps);
    // Increment steps taken during clockwise rotation
    stepsTaken++;
  }

  // If the motor completes the rotation, set the flag
  if (!stopMotor) {
    clockwiseRotationComplete = true;
  }
}

// Function to return the motor to the starting position anticlockwise
void returnToStart() {
  // Set the direction to anticlockwise
  digitalWrite(dirPin, LOW);

  // Calculate the delay between steps based on RPM
  int rpm = 60;
  int delayBetweenSteps = 60000 / (stepsPerRevolution * rpm);

  // Calculate the number of steps needed to return to the starting position
  int stepsToStart = clockwiseRotationComplete ? stepsTaken : 0;

  // Rotate the motor to return to the starting position
  for (int i = 0; i < stepsToStart; i++) {
    // Step the motor
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(delayBetweenSteps);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(delayBetweenSteps);
  }

  // Reset steps taken
  stepsTaken = 0;
}

Before I start making suggestions, please answer these questions.

What are the problems that you are having?

The Stepper library is not the right library to use with step/dir type current output drivers. I suggest the MobaTools stepper library. Install the library using the IDE libraray manager,

Which driver are you using?

Have you properly adjusted the driver's coil current limit?

What is the current limit set to?

What is the motor supply voltage? A 100uF (or so) cap is needed on the motor power supply to peotect the driver, It is not really optional.

3 Likes

nice question to ask

Hi there, thank you very much for your reply.
Apologies, I was so caught up in trying to give all the context to the problem that I realised I've forgotten to actually say what was wrong, which is that my code isn't working as intended.

I am using these A4988 motor drivers (https://www.amazon.co.uk/HALJIA-Stepstick-Stepper-Driver-Printer/dp/B0793K9KF8/ref=asc_df_B0793K9KF8/?tag=googshopuk-21&linkCode=df0&hvadid=310830238305&hvpos=&hvnetw=g&hvrand=13005091757799622454&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1006891&hvtargid=pla-650348118632&psc=1&mcid=ec82da8675c335d290bbd38b30648246)

I think I set the current limit to around 1.5A

The supply voltage of the motor is 12V.

However, I believe that the problem is all from the code (I just included the hardware details in order to help explain the situation better). I have verified each component (motor, FSR and button) all work by testing them with some sample code independently, so I think the main issue is the code I have written.

I'm not very confident with the coding and it seems as what I am trying to achieve is pretty complex (for me as a beginner at least), so I don't think it's correct, so any help with fixing this would be much appreciated.

Kind Regards

Sorry about, I was so focussed on trying to give all of the context to the problem that I didn't actually say what was wrong, which is that my code isn't working - nothing happens when I run it.

Currently, the largest value that will produce an accurate delay is 16383; larger values can produce an extremely short delay. This could change in future Arduino releases. For delays longer than a few thousand microseconds, you should use delay() instead.

Insert some serial prints to track your program sequence and the values of your variables. Temporarily use delay to slow things down.

Your switch is wired contradictory to its pinMode and usage in the program.
Should be wired like so:

Hi,
according to the datasheet, your motor ( 180579 ) is a high impedance stepper. Those motors are designed to be connected to a simple H-bridge. A current controlling driver needs a low impedance stepper to work best. At least you need a PSU voltage much higher than 12V - at least 24V. The 180577 type from the datasheet would be a better suited motor.

That does not really make sense with your motor. The rated current is only 0.31A. But with a 12V PSU and the A4988 driver you cannot exceed this current.

You should include Serial.prints in your code for debugging as @groundFungus already suggested.

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