Control stepper with loadcell

I'm trying to control a linear actuator using a stepper motor with a load cell.
The goal is to be able to apply a precise force on a surface with the actuator.
For the moment my stepper is only going in one direction and it isn't going back when too much pressure is applied.

Thanks for your help :grinning_face_with_smiling_eyes:

Here is my code:

#include <Stepper.h>
#include "HX711.h"

#define calibration_factor 2130 //This value is obtained using the SparkFun_HX711_Calibration sketch

#define LOADCELL_DOUT_PIN 3
#define LOADCELL_SCK_PIN 2

HX711 scale;

const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
int stepCount = 0;

void setup() {
// set the speed at 60 rpm:
myStepper.setSpeed(60);
// initialize the serial port:
Serial.begin(115200);
Serial.println("HX711 scale demo");

scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0

Serial.println("Readings:");

}
void loop() {

Serial.print("Reading: ");
Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
Serial.print(" g"); //You can change this to kg but you'll need to refactor the calibration_factor
Serial.println();

Serial.print("steps:");
Serial.println(stepCount);
stepCount++;

if (0<scale.get_units()<200) {
myStepper.step(5);
stepCount++;
delay(10);

}
else if (scale.get_units()>300) {
myStepper.step(-5);
stepCount--;
delay(10);
}

else {
myStepper.step(0);
delay(10);
}
}

You mean:
if (0<scale.get_units() && scale.get_units()<200) {

Why the extra increment of stepCount?

myStepper.step(0);
That line does nothing.

You could merge the three delay(10); calls into one after the 'if' statement.

void loop()
{
  float weight = scale.get_units();

  Serial.print("Reading: ");
  Serial.print(weight, 1); //scale.get_units() returns a float
  Serial.print(" g"); //You can change this to kg but you'll need to refactor the calibration_factor
  Serial.println();

  Serial.print("steps:");
  Serial.println(stepCount);

  if (weight > 0 && weight < 200)
  {
    myStepper.step(5);
    stepCount++;
  }
  else if (weight > 300)
  {
    myStepper.step(-5);
    stepCount--;
  }

  delay(10);
}

What a coincidence, I am doing exactly that at the moment for an Europa Ice sampling project.
Stepper Speed Control Library

Multi-tasking in Arduino includes a complete stepper example controlled by user input and a sensor

For force control suggest you add a 'spring' between the stepper and the surface so that the stepper can move a step and not be stalling against a hard stop.

Your project sounds interesting.
I'm using it with a diamond drag bit which has a spring inside.
I'm also wondering if there is a way to make the stepper motor react faster.

Thanks for the advice

Step 1 at a time instead of 5 at a time?

Already tried, doesn't change much.

Maybe the scale has a slow response. The stepper can't change speed faster than it can get new data from the scale.

I had problems due to the 10Hz sample rate of the load cell and the noise in the sample. Faster load cell sample rates were even noisier. Finally had to add a moving average filter which slows the measurement down even more and then slow down the control system to match.
I am using a K + I control with a slow I.