Assistance Required with 3-Axis Stepper Motor Control Using STM32 and AccelStepper Library

80 views
Skip to first unread message

ELAN THAMIZHAN

unread,
Aug 10, 2024, 4:40:13 AM8/10/24
to accelstepper

Dear All,

I hope this email finds you well. My name is Elan, and I am currently working on a project involving a 3-axis robotic arm controlled by stepper motors. I am using the STM32 microcontroller along with Keil Studio Cloud for programming, and I am leveraging the AccelStepper library to control the stepper motors.

I have encountered a couple of issues that I hope you can assist me with. Below are the details of my implementation:


Issue 1: Movement Control

I am using the following function to move the X-axis stepper motor:

void X_stepper_Move(int move, int acc) {
    X_Stepper_Relay = 1;
    Y_Stepper_Relay = 1;
    Z_Stepper_Relay = 1;
    printf("\n\n Robotic Arm XY Stepper");
   
    X_Stepper.enableOutputs();
    wait_ms(10);
    X_Stepper.setAcceleration(acc);
    wait_ms(10);
    X_Stepper.moveTo(move);
    wait_ms(10);

    while(X_Stepper.distanceToGo() != 0) {
        X_Stepper.run();
    }

    X_Stepper.stop();
}

This function generally works well, but I would like to ensure that I am using the library optimally, especially regarding the X_Stepper.run() function within the while loop. Are there any best practices or potential improvements you would suggest for this implementation?

Issue 2: Limit Switch Behavior

I also implemented a limit switch function to ensure the stepper motor stops at the desired position:

void X_stepper_Limit() {
    X_Stepper_Relay = 1;
    wait_ms(10);
    Y_Stepper_Relay = 1;
    wait_ms(10);
    Z_Stepper_Relay = 1;
    wait_ms(100);
    printf("\n\n Robotic Arm X Stepper Limit");

    X_Stepper_Limit.mode(PullDown);
    wait_ms(100);
    X_Stepper.setMaxSpeed(maxSpeed);
    wait_ms(10);
    X_Stepper.setAcceleration(1000);  
    X_Stepper.move(200000);    
    wait_ms(10);

    while (X_Stepper_Limit == 0) {
        X_Stepper.run();
    }

    wait_ms(100);
    X_Stepper.setCurrentPosition(0);
    wait_ms(100);
    X_Stepper.stop();
    printf("\n\n Robotic Arm X Stepper Limit Done ");
}


However, I am experiencing an issue where the motor sometimes exits the while loop prematurely, even when the limit switch hasn't been triggered. This results in the stepper motor not moving to the intended limit. Could you provide any insight or advice on how to address this issue?

I would greatly appreciate any guidance or recommendations you can provide to help me improve the reliability and performance of the stepper motor control in my project.

Thank you for your time and for creating such a useful library. I look forward to your response.

Best regards,

Elan.

Jim Larson

unread,
Aug 12, 2024, 12:53:44 AM8/12/24
to accelstepper
Hello Elan-

First, a general suggestion: Have a look at the Missing Manual to better understand the AccelStepper library and how to use it.

Regarding your first question, it is typical to put the call to run() in your main loop. That way you can avoid blocking while the movement is happening. You might consider a state machine to control things. Also note that calling stop() is unnecessary once the motor has reached its final position. Calling the enable() function is probably not necessary either since I don't see any calls to disable(). Finally, I'm curious as to why you need the wait_ms() calls.

Regarding your second question, It is likely that noise is causing false triggering of your sensor. Consider a loop that delays some number of milliseconds (30?) whenever your sensor reads high, then reads the sensor again. If the sensor still reads high, then you should stop. Otherwise, ignore the signal from the sensor and keep stepping. The actual values you need may not be these, but you get the idea. Stepper motors can generate a lot of noise.

HTH!
      
                         -jim

ELAN THAMIZHAN

unread,
Aug 16, 2024, 8:53:05 AM8/16/24
to accelstepper

Dear Mr. Jim,

Thank you again for your previous response, it was very helpful!

I have one more question I was hoping you could assist me with. I am using the DM542 driver to run the stepper motors in my project, and I am curious about how the AccelStepper library can be effectively utilized in conjunction with this driver. Could you provide some guidance on how to integrate the library with the DM542?

Additionally, I would like to know if the DM542 is a suitable driver for use with the AccelStepper library, or if you would recommend a different driver that might be more compatible or efficient for my application.

I would greatly appreciate your advice on this matter. Thank you once again for your help!

Best regards,

Elan

Jim Larson

unread,
Aug 16, 2024, 3:24:31 PM8/16/24
to accelstepper
Hello Elan -

Accelstepper will work with most stepper drivers that respond to step and direction control signals. It should work fine, but stepper driver selection is really beyond the scope of my knowledge since I do not, and am not likely to, own them all and therefore can't test them.

           -jim

Ralph Hulslander

unread,
Aug 16, 2024, 5:47:48 PM8/16/24
to accels...@googlegroups.com
First question is: does it work? If so, go for it.

--
You received this message because you are subscribed to the Google Groups "accelstepper" group.
To unsubscribe from this group and stop receiving emails from it, send an email to accelstepper...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/accelstepper/d3175d05-270c-4c53-b612-af8eece192d4n%40googlegroups.com.

ELAN THAMIZHAN

unread,
Aug 17, 2024, 3:00:57 AM8/17/24
to accels...@googlegroups.com

Dear Mr. Jim,

Thank you once again for your assistance so far!

I have another question regarding the usage of the AccelStepper library in my project. I am using a DM542 driver along with a 4-wire stepper motor. In the library, I noticed that 4 pins are assigned from the microcontroller for controlling the stepper motor.

Could you clarify whether these 4 pins are meant to be connected directly to the motor as inputs, or are they intended as inputs to the DM542 driver? If they are driver inputs, could you please explain how to properly handle the connection and functionality of these pins from the microcontroller to the driver?

Your guidance on this matter would be greatly appreciated, as it will help me ensure that I am wiring and configuring everything correctly.

Thank you in advance for your help!

Best regards,

Elan.


--

gjgsm...@gmail.com

unread,
Aug 17, 2024, 7:13:33 AM8/17/24
to accelstepper
Hello Elan, the DM542 digital driver is a standard type driver for any small to medium bipolar stepper motor. The manual is easily Googled and has everything you need to get your driver/stepper going including wiring diagrams.

To get you started though, the 4 wires from the motor are from the 2 windings in the motor which will have roughly 2 ohms resistance each. One pair of wires for one winding will go to the +A and -A driver terminals and the other pair will go to the +B and -B terminals.
Stepper motor power (VDC) goes to the GND and +Vdc terminals.
Your MCU only needs 2 pins, one for 'pulse' PUL  - (connect to PUL+ terminal) and one for direction DIR - (connect to DIR+ terminal).
Connect PUL- and DIR- to MCU GND. No other connections are needed.

The next step is to use an Accelstepper instance/constructor that uses only PUL and DIR.

AccelStepper stepperA(AccelStepper::DRIVER, PUL_A, DIR_A);
For more steppers, create more instances...
AccelStepper stepperB(AccelStepper::DRIVER, PUL_B, DIR_B);
AccelStepper stepperC(AccelStepper::DRIVER, PUL_C, DIR_C);


See the 'Bounce' Example below. This example is a good way to test your setup.
-----------------------------------------------------------------------------------------------------------------------------------
// Bounce.pde
// -*- mode: C++ -*-
//
// Make a single stepper bounce from one limit to another
//
// Copyright (C) 2012 Mike McCauley
// $Id: Random.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $

#include <Arduino.h>
#include <AccelStepper.h>

// Define a stepper and the pins it will use
#define DIR_A 21
#define PUL_A 18

AccelStepper stepperA(AccelStepper::DRIVER, PUL_A, DIR_A); // Assign Pins

//   For more steppers create more instances...
//     AccelStepper stepperB(AccelStepper::DRIVER, PUL_B, DIR_B); 
//    AccelStepper stepperC(AccelStepper::DRIVER, PUL_C, DIR_C); 


void setup()
{  
  // Change these to suit your stepper if you want
  stepperA.setMaxSpeed(1000);
  stepperA.setAcceleration(1000);
  stepperA.moveTo(400);

  stepperA.setMinPulseWidth(20);   // May not be needed unless using a very fast MCU.
}

void loop()
{
    // If at the end of travel go to the other end
    if (stepperA.distanceToGo() == 0)
      stepperA.moveTo(-stepperA.currentPosition());

    stepperA.run();
}
Reply all
Reply to author
Forward
0 new messages