[Accelstepper] Problem on motor speed when using Accelstepper

Dear all,

I'm a newbie just starts my DIY project with Arduino and some steppers motor.

Currently I face some issues which I tried to troubleshoot but cannot :confused:

Firstly, let me explain overall idea of my project:

  • My project is bending wire machine (2D), to bend shape of C1, C2, C3, C4, C5, LA and LB as attachment.

  • I used 03 step motors: 01 for feeding wire, 01 for bending wire and 01 for cutting wire as attachment.

  • Hardware:

  • Feeding: Nema 34 (8Nm) + Driver MA860H (Open Loop)
  • Bending: Nema 23 57HSM24 + Driver H2-506 (Closed Loop)
  • Cutting: Nema 23 57HSM24 + Driver H2-506 (Closed Loop)
  • Arduino Mega 2560
  • Nextion LCD for monitoring and sending command to Arduino
  • Library:
  • Accelstepper
  • Nextion

Secondly, here below are some issues that I faced currently:

  1. As I read a lot of time that all recommend we should not use “delay” in our code, that’s why I follow and use stepper.run() instead of using stepper.runToPosition(). And the code need to check a lot of IF conditions to be sure all 03 motors rotate as my desire.

Then I checked and realized that the interval of sending run() command is not often enough to step the motor (around 20 times/ sec) --> Cannot reach speed as plan.

  1. When I change method and using runToPosition to block and no need to use a lot of IF conditions, it seems can run smoothly, but I cannot stop motor in case it’s over the limit switch?

Could you guys please help me to have a look of my code, anything is unnecessary, need to add more or I do need to change to more powerful Arduino?

I know it will take long time for reading my code, and I’m not too good in English so if you need to get any further information, please let me know.

Really appreciated and thank you for all your help.

Please check code as in attachment (here is over 9000)

//-----------------------------LIBRARY INCLUDED-----------------------------------------------------------

#include <AccelStepper.h>
#include "Nextion.h"

//--------------------------------------------------------------------------------------------------------------

//-------------------------Define PIN and STEPPER----------------------------------------------------------

int FeedingPUL = 4;      // Feeding PUL - pin
int FeedingDIR = 5;      // Feeding DIR - pin
int BendingPUL = 6;      // Bending PUL - pin
int BendingDIR = 7;      // Bending DIR - pin
int CuttingPUL = 8;      // Cutting PUL - pin
int CuttingDIR = 9;      // Cutting DIR - pin

int limitswitch = 3;     // Normal: HIGH  Press: LOW
int homeswitch  = 2;     // Normal: HIGH  Press: LOW

AccelStepper Feeding(1, FeedingPUL, FeedingDIR);
AccelStepper Bending(1, BendingPUL, BendingDIR);
AccelStepper Cutting(1, CuttingPUL, CuttingDIR);

//---------------------------------------------------------------------------------------------------------------

//---------------------------Define INTERVAL-----------------------------------------------------------------

//-----------Cx_timer [C1_Feeding_interval, C1_Bending_1st, C1_Bending_2nd, C1_Bending_3rd, C1_Bending_4th, C1_Cutting_1st]

//-----------Cx [Cx_start, Cx_Feeding_interval_done, Cx_Bending_1st_done, Cx_Bending_2nd_done, Cx_Bending_3rd_done, Cx_Bending_4th_done, Cx_Cutting_1st_done, Cx_Cutting_2nd_done, Cx_done]

int C1_timer[] = {18257, 765, 8365, 9894, 17494, 18257}; // Example for timer, actually its different
int C2_timer[] = {18257, 765, 8365, 9894, 17494, 18257};
int C3_timer[] = {18257, 765, 8365, 9894, 17494, 18257};
int C4_timer[] = {18257, 765, 8365, 9894, 17494, 18257};
int C5_timer[] = {18257, 765, 8365, 9894, 17494, 18257};
int LA_timer[] = {18257, 765, 8365, 9894, 17494, 18257};
int LB_timer[] = {18257, 765, 8365, 9894, 17494, 18257};

int C1[] = {0,0,0,0,0,0,0,0,0};
int C2[] = {0,0,0,0,0,0,0,0,0};
int C3[] = {0,0,0,0,0,0,0,0,0};
int C4[] = {0,0,0,0,0,0,0,0,0};
int C5[] = {0,0,0,0,0,0,0,0,0};
int LA[] = {0,0,0,0,0,0,0,0,0};
int LB[] = {0,0,0,0,0,0,0,0,0};

int whole_set_flag;            // Default dont call WHOLE_SET (WHOLE_SET = 0)
int partly_flag;                  // Default dont call PARTLY (PARTLY = 0)
int home_flag;
int cut_flag;

unsigned long current_ms;
unsigned long start_time;

uint32_t wholequan;
uint32_t partquan;

int i;


//-----------------------------------SETUP VOID---------------------------------------------------------------

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

  Feeding.setCurrentPosition(0);
  Feeding.setMaxSpeed(2000); // SPEED = Steps/second
  Feeding.setAcceleration(1000); // ACCELERATION = Steps/(second)^2
  Feeding.setSpeed(1000); // SPEED = Steps/second
  //Feeding.disableOutputs(); //Disable motor to ensure no current

  Bending.setCurrentPosition(0);
  Bending.setMaxSpeed(4000); // SPEED = Steps/second
  Bending.setAcceleration(4000); // ACCELERATION = Steps/(second)^2
  //Bending.disableOutputs(); //Disable motor to ensure no current

  Cutting.setCurrentPosition(0);
  Cutting.setMaxSpeed(3000); // SPEED = Steps/second
  Cutting.setAcceleration(3000); // ACCELERATION = Steps/(second)^2
  //Cutting.disableOutputs(); //Disable motor to ensure no current

  pinMode(limitswitch,INPUT_PULLUP);
  pinMode(homeswitch, INPUT_PULLUP);

  nexInit();
  
    
  }

//------------------------------------------LOOP VOID---------------------------------------------------------
void loop() {

  nexLoop(nex_listen_list);  // Check for any touch event
  whole_set(whole_set_flag, wholequan);
  partly(partly_flag, type_buffer, partquan);
  //Feeding.run();
  Bending.run();
  Cutting.run();
  Serial.println("SENT RUN COMMAND");
}


  
}
//------------------------------------C1 CONFIGURATION-----------------------------------------------------
void C1_RUN() {
  
  if ((C1[8] == 0) && (digitalRead(homeswitch)) && (digitalRead(limitswitch))) {
  
  
      if (C1[0] == 0) {
          start_time = millis();
          C1[0] = 1;
      }
        
      current_ms = millis();
      //Serial.println(start_time);
      //Serial.println(current_ms);

      if((current_ms - start_time) <= C1_timer[0]) {
        Feeding.runSpeed();
      }

      if(((current_ms - start_time) >= C1_timer[1]) && (C1[2] == 0)) {
        Bending.move(100);  
        C1[2] = 1;

      }

      if(((current_ms - start_time) >= C1_timer[2]) && (C1[3] == 0) && (C1[2] == 1)) {
        Bending.move(-100);  
        C1[3] = 1;

      }

      if(((current_ms - start_time) >= C1_timer[3]) && (C1[4] == 0) && (C1[2] == 1) && (C1[3] == 1)) {
        Bending.move(100);  
        C1[4] = 1;

      }

      if(((current_ms - start_time) >= C1_timer[4]) && (C1[5] == 0) && (C1[2] == 1) && (C1[3] == 1) && (C1[4] == 1)) {
        Bending.move(-100);  
        C1[5] = 1;

      }

      if(((current_ms - start_time) >= C1_timer[5]) && (C1[6] == 0)) {
        Cutting.move(1000);
        C1[6] = 1;

      } 
  
      if((C1[7] == 0) && (C1[6] == 1) && Cutting.distanceToGo() == 0) {
        Cutting.move(-1000);
        C1[7] = 1;

      }
  
      if((C1[7] == 1) && (C1[6] == 1) && Cutting.distanceToGo() == 0) {
        C1[8] = 1;

      }
   }
}

Prototype.png

Prototype machine.png

ma860h.pdf (311 KB)

H2-506.pdf (1.15 MB)

Prototype.png

Prototype machine.png

FINAL_TESTING.ino (33.3 KB)

Sorry, but I am too lazy to study 33k of code.

If this is a program that you wrote yourself how come it has grown to 33k before you became aware of this problem?

If it is a program written by someone else then maybe the author can help you?

The code should be written so that the loop() function can repeat hundreds of times per second - that way the run() function could be called sufficiently frequently.

Do two or more of your stepper motors need to move at the same time, or is one-at-a-time sufficient. If it is it will makes things easier. It's a bit of a kludge but it blocking code is OK you could call the run() function from a WHILE loop which also checks the state of your limit switch.

...R

Robin2:
Sorry, but I am too lazy to study 33k of code.

If this is a program that you wrote yourself how come it has grown to 33k before you became aware of this problem?

If it is a program written by someone else then maybe the author can help you?

The code should be written so that the loop() function can repeat hundreds of times per second - that way the run() function could be called sufficiently frequently.

Do two or more of your stepper motors need to move at the same time, or is one-at-a-time sufficient. If it is it will makes things easier. It's a bit of a kludge but it blocking code is OK you could call the run() function from a WHILE loop which also checks the state of your limit switch.

...R

Thank you for your information, Robin.

I wrote all these code by myself, at the beginning, I tried to separate and its OK for single code function, but when I do combine, it takes time for checking conditions, flag variables, current milis... and I thought maybe I need to change something for more frequently run() in loop.

The ideal is 03 motors should move at the same time, Feeding motor will run with constant speed (by runSpeed) to feed wire to bending wheel, bending motor will move like servo (by position for bending), then cutting will do its function. (like here: 2mm-6mm Diameter Stainless Steel 2D CNC Wire Bending Machine - YouTube).

But for positioning of bending motor, it seems take too many steps, if you have any idea for easily control, please help me where can I refer from.

thiennd7:
But for positioning of bending motor, it seems take too many steps, if you have any idea for easily control, please help me where can I refer from.

I can't help unless you can reduce your code to a short demo program that illustrates the problem.

I'm currently working on a 4-axis CNC program myself (using my own code rather than the AccelStepper library) and I consider it essential to test the code after every few lines are written.

My gcode parser is written in Python on my PC and the Arduino only has the job of moving the motors according to a set of numbers provided by the Python program. My Arduino program is about 12k and I suspect 30% of that is in blocks of comments.

...R

@Robin2
Comments are not compiled and are not included in the program size

@thiennd7
I ran into this issue while building my wire cutting and stripping machine.

First are the steppers really running simultaneously or are they running consecutively? my guess is the latter as I'm sure you don't want to be feeding wire at the same time your cutting it etc. This would mean your only running one at a time which makes this much easier.
The key to making this work is to only run the bare minimum code needed while running each stepper and since the run() function returns true while the stepper is running it makes this easy.

You loop() should look something like this:

void loop() {
  if(Feeding.run())
  {
    // Bare Minimum code that needs to run during during Feeding.run
  }
  else if(Bending.run())
  {
    // Bare Minimum code that needs to run during during Bending.run
  }
  else if(Cutting.run())
  {
    // Bare Minimum code that needs to run during during Cutting.run
  }
  else
  {
    // ALL other code - will only run when no steppers are running
  }
}

Hutkikz:
Comments are not compiled and are not included in the program size

I'm well aware of that. I was trying to convey the fact that my actual code is only about 8k - but the only convenient piece of data is the overall size of the file.

...R