gin66 / FastAccelStepper

A high speed stepper library for Atmega 168/328p (nano), Atmega32u4, Atmega 2560, ESP32, ESP32S2, ESP32S3, ESP32C3 and Atmel SAM Due
MIT License
282 stars 67 forks source link

Arduino Mega 2560 with DM542T to drive a single NUMA23 stepper #221

Closed Paulvandenbogaard closed 6 months ago

Paulvandenbogaard commented 6 months ago

I need a setup that can driver a steppen motor with the following requirements: 5 full rotations clockwise, followed by 5 full rotations counter clockwise in 0.2 seconds.

I tried AccelStepper which can do a single 5+5 in 0.25 seconds. Now trying FastAccelStepper but the initial setup does not come close It seems to be hindered by a MaxSpeedTics setting of 16000. (MaxSpeedHz: 1000).

I tried all pins on Timer 1, 3, 4, and 5. Each timer has a pin where MaxSpeedTics is 320, while on the other two pins the value is a 1000. I tried this on both my two Arduino Mega 2560's and these show the same behaviour.

I am using the code listed in FastAccelStepper_API.md, with some Serial.print stuff to show these MaxSpeedTics/Hz values.

When using "valid" values, the stepper turns and goes back as expected, albeit "slow".

Is there a simple way to get it faster? Please consider me as a newbe in both Arduino and stepper motors!

gin66 commented 6 months ago

Could you please share your code ? Which maxSpeedTicks are you referring to ?

With a single stepper the limit should be 50kSteps/s.

Paulvandenbogaard commented 6 months ago

@gin66 Hi I was trying the following example code. In there are the getMaxSpeedXXX() functions.

`

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() {} ` I have been playing a bit more and now think I found the solution. I see that for each set of three pins belonging to a single Timer (Timer 1, 3, 4, and 5) there are two pins listing 1000 as the max Hz value, and one with a setting of 50000. Testing one of the last (50000Hz capable) ports makes the thing run fast. It looks like both my Mega2560's only have 4 pins capable of running high speed, and 8 pins downgraded to 1000Hz.

gin66 commented 6 months ago

For atmega2560 (and avr in general), the code does not distinguish between timer 1,3,4,5. The max speed is only set in dependence of the used steppers. One stepper is limited to 50kStep/s, two steppers are limited to approx. 37.6 kStep/s and three stepper to 20kSteps/s. But in no way 1000 Hz should be reported as the limit. In the past there has been a fix for maintaining the max speed done for esp32 and apparently I have missed to copy it over to avr. Perhaps this is the root cause. Even so in github actions, every timer and every channel for atmega2560 is tested. Just not two/three steppers at once and not high speed, and perhaps the simulator behaves in regard to RAM content at reset differently, too.

As you encounter this issue quite reliably, perhaps you can help and manually change the loop in FastAccelStepper.cpp line 90 to:

for (uint8_t i = 0; i < MAX_STEPPER; i++) {
    FastAccelStepper* sx = _stepper[i];
    if (sx) {
       fas_queue[sx->_queue_num].adjustSpeedToStepperCount(_stepper_cnt);
    }
  }

from:

for (uint8_t i = 0; i < _stepper_cnt; i++) {
    FastAccelStepper* sx = _stepper[i];
    fas_queue[sx->_queue_num].adjustSpeedToStepperCount(_stepper_cnt);
  }

Does this gives then consistent results?

This bug should will not hit, if the stepper pins are attached in the right sequence:

Two questions:

BTW: FastAccelStepper only supports one of the four timer modules - as compile time decision. It cannot support two timer modules at the same time or in the same compiler run.

Paulvandenbogaard commented 6 months ago

@gin66

I'll give that code snippet a try.

I am using platformIO and FastAccelStepper version 0.30.9.

When checking another timer I set the build_flags option in platformio's .ini file and recompile.

platformio.ini:

[env:megaatmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
lib_extra_dirs = /Users/paul/Documents/Arduino/libraries/FastAccelStepper/src
monitor_speed = 115200
lib_deps = gin66/FastAccelStepper@^0.30.9
build_flags = -DFAS_TIMER_MODULE=5

I am not sure if I understand your message with:

This bug should will not hit, if the stepper pins are attached in the right sequence:

    timer 1: 11->12->13
    timer 3: 5->2->3
    timer 4: 6->7->8
    timer 5: 46->45->44

Do you mean that if I check say Timer 1 I need to test pin 11 first, and only then 12 and 13. In this sequence?

The DIR pin is number 16 (chosen randomly), the enable pin is not used.

Paulvandenbogaard commented 6 months ago

@gin66

after patching the code as per your advise:

Tested Timer 5, 4, 3, and 1 on all 3 pins. All report 50K. Followed the 46->45->44 sequence; all 50K and 8->7->6 (Timer 4) all 50K and 44->45->46 (Timer 5) all 50K and 3->2->5 (Timer 3) all 50K and 13->12->11 (Timer 1) all 50K

I only tested this on one of the Mega's. If you would like to have these tests done on the other Mega let me know.

Thanks Paul

gin66 commented 6 months ago

Thanks a lot for confirmation. Could you please crosscheck the latest 0.30.10 from today ? Does it now work as expected or any issue left ?

Paulvandenbogaard commented 6 months ago

Will do!

Paulvandenbogaard commented 6 months ago

@gin66 With FastAccelStepper lib 0.30.10:

Timer 5: all three pins 50K. ✅ Timer 4: all three pins 50K ✅ Timer 3: all three pins 50K ✅ Timer 1: all three pins 50K ✅

I tested the return value of getMaxSpeed. And did a test on some pins while actually driving with Acceleration: 45k, and speed 20K; Only on one of my Mega's.

Looks good !

gin66 commented 6 months ago

Great and thanks for your splendid support.

Seems this issue can be closed.