Notifications
Clear all

FastAccelStepper not so fast. I must be missing something

14 Posts
3 Users
1 Reactions
1,486 Views
 pvdb
(@pvdb)
Member
Joined: 7 months ago
Posts: 8
Topic starter  

I have a  NUMA23 stepper motor, controlled by a DM542T, controlled by a Arduino Mega2560. I want this stepper to do the following:

While not using microstepping I need it to do 1000 steps in one direction, followed by 1000 steps in the opposite direction. All within 0.2 seconds.

I used AccelStepper and was not able to go faster than 0.3 seconds. When doing more while also driving the stepper, the speed gets less.

Read about FastAccelStepper. I simple program enables me to do a 1000 steps CW, followed by 1000 steps CCW. However not within 0.2 second time frame, but in ~~1 second.

When looking at the maximum speed I see this is "only" 16000Hz/1000 tics. It is not clear to me if a tic translates to a step... although I assume it is.

Trying to set a value above 1000 with setSpeedInHz() results in a -1 return value: higher value than max allowed.  It seems this max value is related to the pin I use. I checked timers 1, 3, 4, and 5, all three pins per timer, and for all timers one pin has a max of 320, while the other two pins for this timer have a max of 1000. Checked this on both Mega2560s I have, and they give the same result.

 I am reading about registers that can be changed to enable PWM (on "my" ports) at higher frequencies but this is too advanced for me to understand. Not sure if this PWM frequency is the same as the thing I need to drive my stepper at higher speed.

 

BTW using Visual Studio with PlatformIO extension.

#include "FastAccelStepper.h"

FastAccelStepperEngine engine = FastAccelStepperEngine();
FastAccelStepper *stepper = NULL;

#define dirPinStepper    16
#define stepPinStepper   46

void setup() {

   Serial.begin(115200);
   engine.init();
   stepper = engine.stepperConnectToPin(stepPinStepper);
   if (stepper) {
      Serial.println("Got stepper");
      stepper->setDirectionPin(dirPinStepper);

      int8_t rv = stepper->setSpeedInHz(1000L);
      Serial.print("Result : "); Serial.println(rv);
      Serial.print("MaxSpeedInTics : "); Serial.println( stepper->getMaxSpeedInTicks() );
      Serial.print("MaxSpeedInHz   : "); Serial.println( stepper->getMaxSpeedInHz() );
      stepper->setAcceleration(2000);
      stepper->moveTo(4000, true);
      stepper->moveTo(0, true);
   }
}

void loop() {}

   
Quote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1903
 

@pvdb,

I was about to download and look at the library in question, but since you're the software engineer, I'll let you do the dumpster diving on your own.  Just using basic logic and seeing that (Mega 2560 pins 4 and 13: Max 980 Hz) I can say with high confidence that the library is just honoring the Mega's limitations and there is no way it is using the PWM timers.  I would imagine you will find it is using hardware timers and controlling the pulse period directly via bit-banging.  In my own stepper drivers, they routinely get up above 15,000Hz on two steppers independently on a lowly ESP8266... while also hosting a web server!

1000Hz is ridiculously slow for any step rate on a stepper.  That API version must be for very fine control at slow rates.  I would imagine, there is a setSpeed() that uses other units and the driver will do the magic that actually gets you far faster.  

Just as an experiment, you might want to try something like this bit-banging example.  I have not tried to compile this, so there might issues compiling on an Arduino.  It will let you know where your limitations are in your... stepper, stepper driver, library, or logic.  

const int dirPin = 2;  // Direction
const int stepPin = 3; // Step
 
void setup() 
{
    Serial.begin(115200);
    while (!Serial);
    
    // Setup the pins as Outputs
    pinMode(stepPin,OUTPUT); 
    pinMode(dirPin,OUTPUT);
}

u32 speed = 100;  // steps/sec (Hz)
const u32 PULSE_WIDTH = 3;  // μSec
const u32 STEPS = 1000;

void loop()
{
    Serial.printf("Speed=%u Hz\n", speed);
    u32 period = 1000000 / speed;
    u32 betweenPulse = period - PULSE_WIDTH;
    
    digitalWrite(dirPin, HIGH); 
    for(u32 x = 0; x < STEPS; x++) 
    {
        digitalWrite(stepPin, HIGH); 
        delayMicroseconds(PULSE_WIDTH); 
        digitalWrite(stepPin, LOW); 
        delayMicroseconds(betweenPulse); 
    }
    digitalWrite(dirPin, LOW); 
    for(u32 x = 0; x < STEPS; x++) 
    {
        digitalWrite(stepPin, HIGH); 
        delayMicroseconds(PULSE_WIDTH); 
        digitalWrite(stepPin, LOW); 
        delayMicroseconds(betweenPulse); 
    }
  
    // Pause for one second
    delay(1000);
    speed += 100;
}

 

BTW - I'm curious... I note that those box drivers use dip switches or something physical to set micro-stepping.  Can you also programmatically adjust micro-stepping???

VBR,

Inq

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
 pvdb
(@pvdb)
Member
Joined: 7 months ago
Posts: 8
Topic starter  

@Inq,

thanks for thinking with me! I now believe I got the solution. For each Timer there is exactly one pin capable of running high res (50000 Hz), while he other two are limited to 1000Hz. When focusing on a single 50K capable pin and the stepper screams. This is frightening fast, and way above what I need.  Looking great!

So for the two mega2560s I have: not all pins are equal. Only port  5, 6, 11, and 46 make it run fast.


   
ReplyQuote
 pvdb
(@pvdb)
Member
Joined: 7 months ago
Posts: 8
Topic starter  

@Inq,

the driver has switches to control microstepping, however I never heard of a software alternative to do this.

Thanks

Paul


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7435
 

@pvdb I think you need to do more research. To the question 'does microstepping increase speed' the top google answer is 

The rotor responds by swinging to its new magnetic equilibrium, which can be a small fraction of a full step. Microstepping has two principal benefits: it provides increased resolution without a sacrifice in top speed, and it provides smoother low speed motion.

The second question is 'how is microstepping done'

Microstepping is achieved by using pulse-width modulated (PWM) voltage to control current to the motor windings. The driver sends two voltage sine waves, 90 degrees out of phase, to the motor windings. While current increases in one winding, it decreases in the other winding.

The Mega2560 has 15 PWM pins capable of 8 bit resolution. There is an article at LINK  that shows you all the details of PWM freq setting, but does not help you achieve more speed.

According to AccelStepper docs.

Performance
The fastest motor speed that can be reliably supported is about 4000 steps per second at a clock frequency of 16 MHz on Arduino such as Uno etc.

See attached pic for a snapshot of the AccelStepper documentation. I searched on 'speed'

Screenshot 2023 12 26 at 07.59.42

 

 

 

 

 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
Inst-Tech reacted
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1903
 

@pvdb,

What you're asking the Mega2560 to do should be readily possible.  3D Printers started out using Mega2560's.  And even today, many printers still use a motherboard based on the same chip.  The only difference being the MB is laid out with labels for 3D printer connections and have the drivers on the board.  The point being... the Mega2560 should easily be able to do what you're asking for (at least) 4 steppers independently while also reading sensors, a switch and a pot, and while running a display.  Care to share what you're building with such large steppers?  I'm curious. 😊 

VBR,

Inq

 

 

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7435
 

@inq The problem is he thinks he needs 2 Mega2560's for 5 steppers. He thinks the microstepping controls the speed. He thinks microstepping is NOT controlled by software.

 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
 pvdb
(@pvdb)
Member
Joined: 7 months ago
Posts: 8
Topic starter  

@zander, @Inq

 

Must be a language thing because I do not think I need two for 5 steppers; I do not think  microstepping controls speed; and I did not give it any thought if microstepping can be controlled by software (I do not need that (at the moment)).

 

I am using one(1) stepper for a single purpose. I have a TFT instead of a bunch of buttons, sliders and what have you, to create dynamics in my system (speed, acceleration,  travel distance, etc). I found the library used for this TFT (especially checking if the screen was pressed) consumes quite some time, time during which I cannot do a next step command. I assume a second Mega dedicated to the stepper, and a second Mega to controle the TFT will give me a nice solution. Both Mega's to communicate using the SPI protocol: got plenty of pins unused with the Mega 🙂

It can be that a single Mega while using the FastAccelStepper module is able to do it, but that would take away another learning opportunity: SPI 🙂

I just started with all this stuff, so let me stumble, fall and learn 😉

 

Thanks

Paul

 

This post was modified 7 months ago 3 times by pvdb

   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1903
 

@pvdb

Yes, it must be a language barrier.  I never implied you needed to use micro-stepping.  I was asking about it for my curiosity.  This forum is a two way street... that you can and will be asked questions also.  I even used these words to indicate it was for my benefit...  You must have misconstrued them.

Posted by: @inq

BTW - I'm curious... I note that those box drivers use dip switches or something physical to set micro-stepping.  Can you also programmatically adjust micro-stepping???

Since you have not been in any way forthcoming about your project, we can only surmise you know what you are doing by specifying a Mega 2560.  The claim of being a software engineer, gave us an expectation of some certain level of logic and research ability.  The ONLY use for a Mega is the extra pins.  It has the same weak processor as an Arduino UNO or even an Arduino Nano for that matter.  Our common logic says if you think you need 2 Mega's then you must have gobs of things (sensors, servos, steppers, actuators, switches, potentiometers, displays, etc) needing to be connected.  If all you have laid out is all there is... then you'd be far better off getting a single/better board... a $3 NodeMCU or the big fad these days of the Raspberry Pi RP2040 would be a cake-walk through your scenario and not needing the headache of setting up two-way communications.  But if that is what you want to do... Go for it!

It is also assumed, if you're asking questions (or stating a problem - as in your intro-thread) we should offer advice.  In our culture that is common courtesy and us being friendly and willing to take our valuable time to help you.  If you or your culture sees that as some kind of affront, I'll bow out.  Since you clearly don't want our advice and would rather trial and error your way through this learning curve, I'll be glad to go.

 

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7435
 

@pvdb Maybe if you show us your code we can figure out what is causing the problem for you.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
 pvdb
(@pvdb)
Member
Joined: 7 months ago
Posts: 8
Topic starter  

@Inq

I value your thinking and advise. I myself was a bit upset on Ron talking to you about me stating that  "I think A and think B etc". At least that was how I read that message. Please do not be offended! That was absolutely not my intention. I am here to learn. And find learning is best when stumbling, falling etc with a pointer here and there from others to not fall too hard 🙂

AND I fully agree with your "it goes both ways" expectation.!

I believe I answered your question on microstepping in an earlier message: I only know of the dipswitch way, and cannot tell you if there even is a software approach. Looking at the documentation for the stepper driver modules never gave me a hunch this could be the case.

Per advise of the FastAccelStepper author (parallel github communication) I changed a small part of that code and now all my pins are able to generate a 50K Hz pulse frequency. It looks like the 1000Hz thing is now understood, and corrected.

I selected the Mega without any experience with it nor in this field. Initially I just wanted enough pins to connect a small display, a couple of buttons, switches etc. And a single stepper. While learning I get new ideas. New findings making me change some details (the learning process I believe). Thats why I went the Mega way, to make sure pin-shortage would not be an obstacle. I thought the Mega has a little extra memory too.

BTW the goal of the project is to drive an object over one axes in both directions where I can specify speed, acceleration, and distance.

Thanks

Paul

 


   
ReplyQuote
 pvdb
(@pvdb)
Member
Joined: 7 months ago
Posts: 8
Topic starter  

@zander

The code is in my opening post. It is an example in the repo of the FastAccelStepper module where I added a few print statements.

I got a response from the author of that FastAccelStepper module on Github with a request to change some code and try again. This I did today and I believe the problem in this module is located and solved. If I understand it correctly this was a Mega specific part. I am now able to drive all 3 pins of all the four Timers at 50K Hz!

This rocks!


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7435
 

@pvdb When you mention 2 megas, and how changing the timers makes the stepper ' frightening fast' you can hopefully now see the reason for my post.

As far as microstepping being controlled by software, I will accept some blame there. My take is that while you do set some hardware switches to enable it, it's the software that drives it.

Good luck in your endeavours.

 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7435
 

Posted by: @pvdb

@zander

The code is in my opening post. It is an example in the repo of the FastAccelStepper module where I added a few print statements.

I got a response from the author of that FastAccelStepper module on Github with a request to change some code and try again. This I did today and I believe the problem in this module is located and solved. If I understand it correctly this was a Mega specific part. I am now able to drive all 3 pins of all the four Timers at 50K Hz!

This rocks!

Ok, that must be a very specific fix for that board. Since that board is not commonly used for stepper motors it is understandable.

 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote