Multiple Actions at the same time (Stepper and Scale)

Hello community,

I am trying to let a stepper motor run until a certain weight on the load cell has been reached. As this is only the beginning and will be extended with multiple load cells and steppers, I want to use millis() instead of delay. I have used Demonstration code for several things at the same time as a reference but struggle to get it to work as intended.


// Define stepper motor connections and steps per revolution:
#define dirPin 47
#define stepPin 46
#define stepsPerRevolution 200

//Scale
#include "HX711.h"
#define LOADCELL_DOUT_PIN_1 22
#define LOADCELL_SCK_PIN_1 24
HX711 scale_1;
float calibration_factor_1 = -650;

int Scale_Digits = 0;
const int Stepper_Interval = 450;
const int Scale_Read_Interval = 1000;
unsigned long currentMillis = 0;
unsigned long previousScaleMillis = 0;
unsigned long previousStepperMillis = 0;
byte Stepper_Status = 0;
byte Scale_Status = 0;
byte stepPinStatus = LOW;
int current_weight = 0;
int desired_weight = 200;

void setup() {
  Serial.begin(115200);

  // Stepper
  Serial.println("initiate Stepper");  //for debugging
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  digitalWrite(dirPin, LOW);

  //Scales
  Serial.println("initiate Scales");  //for debugging
  scale_1.begin(LOADCELL_DOUT_PIN_1, LOADCELL_SCK_PIN_1);

  Serial.println("Set calibration factors");  //for debugging
  scale_1.set_scale(calibration_factor_1);    // this value is obtained by calibrating the scale with known weights

  Serial.println("tare scales");  //for debugging
  scale_1.tare();                 // reset the scale to 0
}

void loop() {

  currentMillis = millis();
  stepper_status();
  stepper_move();
  scale_status();
  scale_get();
}

void stepper_status() {
  if (Stepper_Status == LOW) {
    Serial.println("Stepper Status = LOW");  //for debugging
    if (current_weight < desired_weight) {
      Serial.println("current_weight < desired_weight");  //for debugging
      Stepper_Status = HIGH;
      Serial.println("Stepper_Status = HIGH");  //for debugging
    }
  }
}

void stepper_move() {
  if (Stepper_Status == HIGH) {
    if (currentMillis - previousStepperMillis >= Stepper_Interval) {
      previousStepperMillis += Stepper_Interval;
      if (stepPinStatus == HIGH) {
        digitalWrite(stepPin, HIGH);
        stepPinStatus = LOW;
      } else {
        digitalWrite(stepPin, LOW);
        stepPinStatus = HIGH;
      }
    }
  }
}

void scale_status() {
  if (Scale_Status == LOW) {
    if (currentMillis - previousScaleMillis >= Scale_Read_Interval) {
      Scale_Status = HIGH;
      previousScaleMillis += Scale_Read_Interval;
    }
  } else {
  }
}

void scale_get() {
  if (Scale_Status == HIGH) {
    Serial.print(" - SUM: ");
    Serial.println(scale_1.get_units(), Scale_Digits);
  }
}

I get the scale to work very reliable, however I can't get the stepper to keep running smoothly without stopping while checking the weight on the scale.

Can anyone support?

I am using an Arduino Mega, a Nema17 and "normal" 1kg load cell.
Thanks in advance!

Maybe try

void scale_status() {
  if (scale_1.is_ready()) {
    Scale_Status == HIGH;
  else
    Scale_Status == LOW;
  }
}
2 Likes

Not quite sure how and why this would help with the stepper motor? Despite missing a few { }

Sorry! Added the missing one in above.

I'm not sure it will help or not. Reviewing your code, the only way I could see that the motor would not run smoothly is if scale_1.get_units() blocks while waiting for the reading to become ready. Checking scale_1.is_ready() should prevent that.

Unfortunately not, but thanks anyway!
I believe the scale is ready and can provide the weight rather fast (faster than I call it).
The issue is that I can not get the Stepper to run in the "background" while I do something else, such as getting the weight.

You could try a non-blocking method to read the scale.

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