Hello!
This is my first post, however I have spent a lot of time here searching for examples and solutions for various of my projects.
I have done a lot of projects, however I consider myself as begginer as most of the time all I was doing was just copy/pasting code to suit for my needs.
However a lot of things changed in last project as I can not find solution online, that is why I am hoping you can help me.
The plan is to use load cell, to measure force in positive and negtive dirrection and the stepper motor should lincrease the velocity as the force increases. Naturaly when there is no force pressent the motor should stop. Also I would like to put in the code, that when the push button is pressed, the stepper motor returns to initial position
For my setup i am using:
- 20kg load cell (primaraly used in weight scales)
- HX711 load cell amplifier
- arduino nano
- stepper motor driver Gecko G213V (max 7.5A, 80V), running at 5A and 36V
- Nema 24 stepper motor stepper motor site
- 36V PSU link
There is no problem with connection as everything is working as I wrote the code.
I know exactly that there is a problem in my code I just do not know how to write it to behave it as I want.
In current code stepper behaves as it should until about 50RPM, after that, when I increase the force and therefore stepper velocity it starts to stop between each loop, updating the new velocity only then starting the motor again. That way I can only reach about 300 RPMs as everytime stepper stops it starts with full velocity without acceleration and naturaly stalls. I would like to get the stepper up to 1000 RPM which I know it is achivable as I am using accelStepper libary to return stepper to initial position.
I know that this is not the right way to achive what I want since stepper.step is a blocking function and it is not right way to achive continous motion.
I would much rather use accellStepper libary with non blocking function but so far it was worse than before, every time I have tried.
I have tried with move function and then runSpeed wich I think should give non blocking continous motion, but all I get is even more lag.
So here is my code with stepper libary for velocity control that is working the best so far:
//code for turning Stepper motor CW/CWW with load cell measurments for controlling direction and velocity, and push button switch for return to initial position
#include <Stepper.h>
#include "AccelStepper.h"
#include "HX711.h"
//Stepper
#define dir_pin 5 // Pin 5 connected to Direction pin
#define step_pin 6 // Pin 6 connected to Steps pin
#define SLEEP 7 // Pin 7 connected to SLEEP pin
//Load cell values
#define calibration_factor -100 //This value is obtained using the SparkFun_HX711_Calibration sketch load cell:575 rocka:33
#define DOUT 11
#define CLK 12
//For returning to first position after button is pressed
volatile boolean forceDetected = false ; // false initial state
volatile boolean rotationdirection; // CW or CCW rotation
const int PinSW = 2; // Reading Push Button switch
int StepperPosition = 0; // initial Stepper Motor Position
const int stepsPerRevolution = 2000; // steps per revolution: motor: 200 steps microsteping: 10
Stepper stepper(stepsPerRevolution, dir_pin, step_pin);
AccelStepper accStepper(AccelStepper::DRIVER, step_pin, dir_pin);
HX711 scale;
//load cell value, if force is detected
float val = 0;
int velocity;
const float positionZero = 0;
const float flimit = 50; //limit when there is enough force to start motion
const float minforce = -5000;
const float noforce = 0; //value when there is no force present
const float maxforce = 5000; //maximal value of force
const float minvelocity = 1; //minimal motor velocity
const float maxvelocity = 200; //maximal motor velocity
volatile boolean middle = true; // define middle position
// Interrupt routine runs if load cell detects force
void rotarydetect () {
//delay(1); // delay for Debouncing
val = scale.get_units();
if (val > noforce + flimit) { //if force is greater than minimum triger ammount, turn motor CCW
rotationdirection = true;
forceDetected = true;
middle = false;
}
else if (val < noforce - flimit) { //if force is smaller than minimum triger ammount in negative value, turn motor CW
rotationdirection = false;
forceDetected = true;
middle = false;
}
else {
middle = true;
}
}
void setup () {
pinMode(dir_pin, OUTPUT);
pinMode(step_pin, OUTPUT);
pinMode(SLEEP, OUTPUT);
digitalWrite(SLEEP, LOW); // Wake up Driver
delay(5); // Wait for Driver wake up
pinMode(PinSW, INPUT_PULLUP);
accStepper.setMaxSpeed(20000); // Set speed for accelstepper
accStepper.setAcceleration(10000); // Acceleration for accelstepper
scale.begin(DOUT, CLK);
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
}
void loop ()
//button return to zero
{
if ((int) digitalRead(PinSW) == 0) { // check if button is pressed,
if (StepperPosition == 0) { // check if button was already pressed
}
else {
if (StepperPosition > 0) { // Stepper was moved CW
// set stepper to the new calculated position
accStepper.setSpeed(20000);
accStepper.move(-StepperPosition);
accStepper.runToPosition();
}
else {
// Do until Motor position is back to ZERO
// set stepper to the new calculated position
accStepper.setSpeed(20000);
accStepper.move(StepperPosition);
accStepper.runToPosition();
}
StepperPosition = 0; // Reset position to ZERO after moving motor back
}
}
//move stepper if force on load cell is detected
rotarydetect();
//stepper control (currently this is the best as I can get. I would rather use accelStepper non blocking functions,
// but I get worse results. Currently this code runs OK till about 50 RPM
if (forceDetected == true && middle == false) {
forceDetected = false; // do NOT repeat IF loop until new Force detected
// Which direction to move Stepper motor
if (rotationdirection) { // Move DOWN
velocity = map(val, noforce, maxforce, minvelocity, maxvelocity); // Map velocity value as force increases
stepper.setSpeed(velocity);
stepper.step(5 * velocity);
StepperPosition = StepperPosition + ((5 * velocity) / 4); //because stepper libary gives position in RPM,
//I have to recalculate value in order to accelStepper libary return to initial position in button is pressed
}
if (!rotationdirection) { // Move motor UP
velocity = map(val, noforce, minforce, minvelocity, maxvelocity); // Map velocity value as force increases
stepper.setSpeed(velocity);
stepper.step(-(5 * velocity));
StepperPosition = StepperPosition - ((5 * velocity) / 4); //because stepper libary gives position in RPM,
//I have to recalculate value in order to accelStepper libary return to initial position in button is pressed
}
}
}
Entire sketch is commented in order to explain as much as I can. The part that is causing problems is the lower part after stepper control part, everything else is working as I want it to.
I am really desperate, since I am strugling with this for several days now and I do not know how to proceed further.
Any advice or solution will be deeply apreciated. Thank you.
Dominik