Help with stepper motor and load cell

I am trying to do the following with a load cell, stepper motor with microstepping driver, and HX711 amplifier

  1. Initiate the hx711 and load cell, then print to serial so I can read the load to configure the machine to a certain load

  2. Enter a set of nested loops using a push button. The outer loop sets the total number of revolutions that I want the motor to turn and the inner loop will send step pulses to the driver.

2a) Turn a stepper motor one revolution (200 steps/rev * 4x microstepping = 800 steps/rev)

2b) Print reading to serial from the load cell using the hx711.h module after 1 rev

  1. Exit the nested loops and stop the motor once the desired number of revolutions have been executed.

I have attached the overall code (fatiguetester.ino) and hx711.h. Then I run the code, the motor turns and readings show up in the serial that are coming from the load cell att he right time, but they are constant (i.e. don't change if I add load to load cell).

If I remove all of the motor stuff from the code and just run the load cell code (attached loadcell.ino), the load cell works perfectly.

I need help understanding what may be wrong with the fatiguetester.imo file that has the motor movements combined with the load cell reading sequence.

Any help would be appreciated!!!

fatigue_tester.ino (1.73 KB)

HX711.h (2.32 KB)

loadcell.ino (1.9 KB)

It would be save so much time if you just include the code in your Post - it is short enough,
FATIGUE_TESTER

#include "HX711.h"

#define DOUT  2
#define CLK  3
HX711 scale(DOUT, CLK);

float calibration_factor = -227.00866; //
int dirpin = 2; //direction pin connected to stepper driver
int steppin = 3;  //step pin connected to stepper driver
int d = 7;   // to store on or off value from switch

void setup() 
{
pinMode(7,INPUT);     /input from switch
pinMode(13,OUTPUT);   //LED
Serial.begin(9600);
scale.set_scale();
scale.tare();                             //Reset the scale to 0
long zero_factor = scale.read_average();   //Get a baseline reading
pinMode(dirpin, OUTPUT);  
pinMode(steppin, OUTPUT);
}

void loop()
{
  int s;
  int c;
  d = digitalRead(7);            // read pin 7, connected to start button
  digitalWrite(dirpin, LOW);     // Set the direction.
  delay(100);
    
    if (d==0)  //Start button pressed (low)
    {
      for (c = 0; c<100; c++)          //iterate for 100 revolutions
      {
        digitalWrite(13, HIGH);
        delay(1000);
        scale.set_scale(calibration_factor); //Adjust to this calibration factor
        Serial.println(scale.get_units(), 3);  //print load cell reading
        
        for (s = 0; s<800; s++)        // Iterate for 800 microsteps (1 rev)
        {
          digitalWrite(steppin, LOW);  // This LOW to HIGH change is what creates the
          digitalWrite(steppin, HIGH); // "Rising Edge" so the easydriver knows to when to step.
          delayMicroseconds(625);      // delay time between steps
        }                             
      }
    }
    
    else  //button not pressed (high)
      {
      digitalWrite(13, LOW);  //LED off
      scale.set_scale(calibration_factor); //Adjust to this calibration factor
      Serial.println(scale.get_units(), 3);  //print load cell reading
      }
  
}

HX711

#include "HX711.h"

#define DOUT  2
#define CLK  3
HX711 scale(DOUT, CLK);

float calibration_factor = -227.00866; //
int dirpin = 2; //direction pin connected to stepper driver
int steppin = 3;  //step pin connected to stepper driver
int d = 7;   // to store on or off value from switch

void setup() 
{
pinMode(7,INPUT);     /input from switch
pinMode(13,OUTPUT);   //LED
Serial.begin(9600);
scale.set_scale();
scale.tare();                             //Reset the scale to 0
long zero_factor = scale.read_average();   //Get a baseline reading
pinMode(dirpin, OUTPUT);  
pinMode(steppin, OUTPUT);
}

void loop()
{
  int s;
  int c;
  d = digitalRead(7);            // read pin 7, connected to start button
  digitalWrite(dirpin, LOW);     // Set the direction.
  delay(100);
    
    if (d==0)  //Start button pressed (low)
    {
      for (c = 0; c<100; c++)          //iterate for 100 revolutions
      {
        digitalWrite(13, HIGH);
        delay(1000);
        scale.set_scale(calibration_factor); //Adjust to this calibration factor
        Serial.println(scale.get_units(), 3);  //print load cell reading
        
        for (s = 0; s<800; s++)        // Iterate for 800 microsteps (1 rev)
        {
          digitalWrite(steppin, LOW);  // This LOW to HIGH change is what creates the
          digitalWrite(steppin, HIGH); // "Rising Edge" so the easydriver knows to when to step.
          delayMicroseconds(625);      // delay time between steps
        }                             
      }
    }
    
    else  //button not pressed (high)
      {
      digitalWrite(13, LOW);  //LED off
      scale.set_scale(calibration_factor); //Adjust to this calibration factor
      Serial.println(scale.get_units(), 3);  //print load cell reading
      }
  
}

...R

You seem to have a FOR loop that goes through 100 iterations. I see nothing in that to change the number of iterations depending on the value of the load.

Do you need to set the calibration factor 100 times? Perhaps once in setup() would be sufficient?

...R

Only calibrate the scale once in setup() - it looks like you are taring the loadcell for every reading,
so of course it won't change.

Break you code up into smaller functions, it will be much more readable. Variable names
like d, s, c aren't meaningful, choose better names and you'll be able to read the code in
a year's time!

You read a pin, then delay, then act on the value read before, which isn't a great UI design since
the behaviour is delayed from the command with no way to cancel.

800 is a derived constant in the code, better to name such things and explain where they come from:

#define steps_per_rev 200
#define microsteps_factor 4
#define microsteps_per_rev (steps_per_rev * microsteps_factor)

Then its much easier to adapt and alter the code in the future.

I have a similar problem. Trying to run a stepper motor with a Stepper Motor Shield and a load cell with HX711.

The code is below (HX711_STEPPER). If I run this, I can get the load cell values on serial monitor without an issue. But the motor doesn't move; it makes a jittery noise.

If I run the motor code and load cell code separately, it works well! The separate codes (STEPPER and HX711_SERIAL) are below as well. I have attached the library files for HX711.

Not sure if I'm doing something wrong. Any help would be great!

HX711_STEPPER

#include "HX711.h"

// HX711.DOUT - pin #A1
// HX711.PD_SCK - pin #A0

HX711 scale(A1, A0); // parameter "gain" is ommited; the default value 128 is used by the library

const int stepPin = 6;
const int dirPin = 7;
const int enPin = 8;

void setup() {
 Serial.begin(38400);
 pinMode(6, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(8, OUTPUT);
 digitalWrite(enPin, HIGH);      // stop
  
 Serial.println("h-climb  l-descend  s-stop");
 
 Serial.println("HX711 Demo");

 Serial.println("Before setting up the scale:");
 Serial.print("read: \t\t");
 Serial.println(scale.read()); // print a raw reading from the ADC

 Serial.print("read average: \t\t");
 Serial.println(scale.read_average(20));   // print the average of 20 readings from the ADC

 Serial.print("get value: \t\t");
 Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight (not set yet)

 Serial.print("get units: \t\t");
 Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight (not set) divided 
// by the SCALE parameter (not set yet)  

 scale.set_scale(2280.f);                      // this value is obtained by calibrating the scale with known weights; see the README for details
 scale.tare();        // reset the scale to 0

 Serial.println("After setting up the scale:");

 Serial.print("read: \t\t");
 Serial.println(scale.read());                 // print a raw reading from the ADC

 Serial.print("read average: \t\t");
 Serial.println(scale.read_average(20));       // print the average of 20 readings from the ADC

 Serial.print("get value: \t\t");
 Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight, set with tare()

 Serial.print("get units: \t\t");
 Serial.println(scale.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided 
// by the SCALE parameter set with set_scale

 Serial.println("Readings:");
}

void loop() {
 for (int x = 0; x < 2000; x++)
 {
     Serial.println(scale.get_units(),1);
 if(Serial.available())
 {
   char c = Serial.read();
   if(c=='l')
     {
       //Serial.println("Descending..");
       digitalWrite(enPin, LOW);
       digitalWrite(dirPin, LOW);      // descend
     }
   if(c=='h')
   {
       //Serial.println("Climbing..");
       digitalWrite(enPin, LOW);
       digitalWrite(dirPin, HIGH);      // climb
   }
   if(c=='s')
   {
     //Serial.println("Stopping..");
     digitalWrite(enPin, HIGH);      // stop
   }
 }
   digitalWrite(stepPin, LOW);
   delayMicroseconds(2);
   digitalWrite(stepPin, HIGH);
   delayMicroseconds(2);
   //Serial.print("one reading:\t");

 //Serial.print("\t| average:\t");
 //Serial.print("\t");
 //Serial.println(scale.get_units(10), 1);
 //scale.power_down();    // put the ADC in sleep mode
   delay(1);    
 //scale.power_up();
 }
}

STEPPER

const int stepPin = 6;
const int dirPin = 7;
const int enPin = 8;

void setup() {
 // put your setup code here, to run once:
 pinMode(6, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(8, OUTPUT);
 digitalWrite(enPin, HIGH);      // stop
  
 Serial.begin(9600);
 Serial.println("h-climb  l-descend  s-stop");
 //////// 1 time movement  /////////
 
//  digitalWrite(dirPin, HIGH);     // descend
//
//  for (int x = 0; x < 6000; x++)
//  {
//    digitalWrite(stepPin, HIGH);
//    delayMicroseconds(2000);
//    digitalWrite(stepPin, LOW);
//    delayMicroseconds(2000);
//  }

}

void loop() 
{
 // put your main code here, to run repeatedly:
 for (int x = 0; x < 2000; x++)
 {
 if(Serial.available())
 {
   char c = Serial.read();
   if(c=='l')
     {
       Serial.println("Descending..");
       digitalWrite(enPin, LOW);
       digitalWrite(dirPin, LOW);      // descend
     }
   if(c=='h')
   {
       Serial.println("Climbing..");
       digitalWrite(enPin, LOW);
       digitalWrite(dirPin, HIGH);      // climb
   }
   if(c=='s')
   {
     Serial.println("Stopping..");
     digitalWrite(enPin, HIGH);      // stop
   }
 }
 
 

///////////// actual move //////////////


   digitalWrite(stepPin, LOW);
   delayMicroseconds(2);
   digitalWrite(stepPin, HIGH);
   delayMicroseconds(2);
   delay(10);
 }
 //delay(2000);    // delay pause in milliseconds

}

HX711_SERIAL

#include "HX711.h"

// HX711.DOUT - pin #A1
// HX711.PD_SCK - pin #A0

HX711 scale(A1, A0); // parameter "gain" is ommited; the default value 128 is used by the library

void setup() {
 Serial.begin(38400);
 Serial.println("HX711 Demo");

 Serial.println("Before setting up the scale:");
 Serial.print("read: \t\t");
 Serial.println(scale.read()); // print a raw reading from the ADC

 Serial.print("read average: \t\t");
 Serial.println(scale.read_average(20));   // print the average of 20 readings from the ADC

 Serial.print("get value: \t\t");
 Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight (not set yet)

 Serial.print("get units: \t\t");
 Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight (not set) divided 
// by the SCALE parameter (not set yet)  

 scale.set_scale(2280.f);                      // this value is obtained by calibrating the scale with known weights; see the README for details
 scale.tare();        // reset the scale to 0

 Serial.println("After setting up the scale:");

 Serial.print("read: \t\t");
 Serial.println(scale.read());                 // print a raw reading from the ADC

 Serial.print("read average: \t\t");
 Serial.println(scale.read_average(20));       // print the average of 20 readings from the ADC

 Serial.print("get value: \t\t");
 Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight, set with tare()

 Serial.print("get units: \t\t");
 Serial.println(scale.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided 
// by the SCALE parameter set with set_scale

 Serial.println("Readings:");
}

void loop() {
 Serial.print("one reading:\t");
 Serial.print(scale.get_units(), 1);
 Serial.print("\t| average:\t");
 Serial.println(scale.get_units(10), 1);

 scale.power_down();        // put the ADC in sleep mode
 delay(100);
 scale.power_up();
}

HX711-master.zip (13.8 KB)