Forum Rule: Always post complete source code & details to reproduce any issue!
Page 3 of 4 FirstFirst 1 2 3 4 LastLast
Results 51 to 75 of 77

Thread: New Stepper Motor Library

  1. #51
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429
    Which Arduino / Teensyduino version do you use? Compiles here without problem for Arduino 1.8.5 and Teensyduino 1.44. (Of course you need to add

    #include "RotateControl.h"
    #include "ResponsiveAnalogRead.h"
    to the code from #47, but it looks like you did that. Do you have any other includes in your code?

  2. #52
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429
    Ups, found it. I had a slightly newer version locally. It correctly includes <cmath> instead of <math.h>. This avoids conflicts with macros defined in wiring.h. Just uploaded the newest version which should fix it.
    Last edited by luni; 12-28-2018 at 03:29 PM.

  3. #53
    Junior Member
    Join Date
    Dec 2018
    Location
    Portugal
    Posts
    3
    Quote Originally Posted by luni View Post
    Ups, found it. I had a slightly newer version locally. It correctly includes <cmath> instead of <math.h>. This avoids conflicts with macros defined in wiring.h. Just uploaded the newest version which should fix it.
    I tried your example code and it works now (Arduino 1.8.5 and Teensyduino 1.45).

    I will do some more tests and report back if I find any bugs.

    Once again, thanks a lot for your effort!!!

  4. #54
    Junior Member
    Join Date
    Dec 2018
    Location
    Portugal
    Posts
    3
    Hi Luni,

    Do you know of a straightforward way to modify the library to have minimum speeds and accelerations less than 1?

    Thanks!

  5. #55
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429
    Are you sure that you need a stepper library for speeds below 1s? You won't need acceleration for that low speeds so you can just do something like:
    Code:
    ...
    
    while(notAtTarget)
    {
      digitalWriteFast(stepPin,HIGH)
      delayMicroseconds(10);
      digitalWriteFast(stepPin,LOW)
    
      delay(1000); 
      ...
    }
    ...
    Anyway, here some information from an older discussion about the same requirement: https://github.com/luni64/TeensyStep/issues/9

  6. #56
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429

    Speed Override Demo

    Here a quick video demonstrating the new speed override feature of TeensyStep. It first accelerates a disk with 4 holes to 1500 rpm and then synchronizes the speed and position of a second motor to the disk by adjusting its speed on the fly. After the motors run synchronized pins of the second motor dive into the holes of the disk at 1500 rpm.

    https://youtu.be/o9pRKvfJtoU

  7. #57
    Junior Member
    Join Date
    Jan 2019
    Posts
    3
    Hello,

    I have tried your new library and everything seems to work except the stopAsync() function. The motor just goes to the target position with the velocity that it had when the stopAsync() function was called and then stops abruptly. Am I doing something wrong?

    Thank you.

    Code:
    #include <StepControl.h>
    
    Stepper motor(23, 22);         // STEP pin: 23, DIR pin: 22
    StepControl<> controller;    // Use default settings 
    
    void setup(){
    
    
      motor.setAcceleration(18750);
      motor.setMaxSpeed(18750);
      motor.setInverseRotation(true);
    }
    
    void loop() 
    {
    
      motor.setTargetAbs(-100000);
      controller.moveAsync(motor);    // Do the move
      delay(2000);
      controller.stopAsync();
      delay(2000);
      
      motor.setTargetAbs(0);
      controller.move(motor);    // Do the move
      delay(1000);
      controller.stopAsync();
    }

  8. #58
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429
    I didn't test your code yet but there are some things to note:

    First block in loop:
    Instead of the delay(2000) after the stopAsync you should wait until the motor really stopped (e.g. place a while(controller.isRunning(){delay(10);} after stopAsync) or you can use stop() instead which does exactly this. Sending new target position while the motor runs will mess up internal state of the motor. (Since this seems to be a common error I'll add some checks in the call...)

    Second block:
    After your stopAsync you leave the loop without waiting for the motor to stop. A couple of microseconds later you set a new targetPosition while the motor is in full movement. This won't work.

    Unless you really need it, I recommend to use the synchronous (blocking) commands instead of the async (non blocking) commands. I.e. move() instead of moveAsync(), and stop() instead of stopAsync()

  9. #59
    Junior Member
    Join Date
    Jan 2019
    Posts
    3
    Hello luni,

    Thank you for the quick reply and for pointing the mistakes in my test code. I believe I have fixed them.

    Unfortunately neither the stop() or stopAsync() functions seem to work properly for me with this new library. The code below just moves once (i.e. doesn't loop) to the position 100000 and back to 0 and completely ignores both the stop() and stopAsync() commands (the code below works fine with the old library).


    Code:
    #include <StepControl.h>
    
    Stepper motor(23, 22);         // STEP pin: 23, DIR pin: 22
    StepControl<> controller;    // Use default settings
    
    void setup() {
    
    
      motor.setAcceleration(18750);
      motor.setMaxSpeed(18750);
      motor.setInverseRotation(true);
    }
    
    void loop()
    {
    
      motor.setTargetAbs(100000);
      
      controller.moveAsync(motor);    // Do the move (non-blocking)
      
      delay(2000);
      
      controller.stop();              // Stop the motor before move is finished (blocking)
      
    
      motor.setTargetAbs(0);
      
      controller.moveAsync(motor);         // Do the move (non-blocking)
      
      delay(1000);
      
      controller.stopAsync();             // Stop the motor before move is finished (non-blocking)
      
      while (controller.isRunning()) {
        delay(10);                        // Wait until the motor is stopped 
      }
    }

  10. #60
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429
    Sorry for the late response, I was busy with another project on the weekend. You are right, there was a bug in the development branch. I hope I fixed it, can you give it a try (Branch: develop)?

    Here the code which I tried:
    Code:
    #include "TeensyStep.h"
    
    Stepper motor(23, 22);  // STEP pin: 23, DIR pin: 22
    StepControl controller; // Use default settings
    
    void setup()
    {
      motor
          .setAcceleration(18750)
          .setMaxSpeed(18750)
          .setInverseRotation(true);
    }
    
    void loop()
    {
      motor.setTargetAbs(100000);
    
      controller.moveAsync(motor); // Do the move (non-blocking)
      delay(2000);
      controller.stop();           // Stop the motor before move is finished (blocking)
    
      motor.setTargetAbs(0);
      controller.moveAsync(motor); // Do the move (non-blocking)
      delay(1000);
      controller.stopAsync();      // Stop the motor before move is finished (non-blocking)
    
      while (controller.isRunning())
      {
        delay(10); // Wait until the motor is stopped
      }  
    }

  11. #61
    Junior Member
    Join Date
    Jan 2019
    Posts
    3
    Hi luni,

    Thank you very much for your help! The functions seem to work as expected now. I'm trying to build a camera slider and your library seems to be perfect for this application.

    Cheers

  12. #62
    Junior Member
    Join Date
    Feb 2019
    Location
    France
    Posts
    8

    Smile

    Hi Luni,

    I try to use your librairy for my project:
    https://groups.io/g/TeenAstro/wiki/home

    Currently when I use your library before I start a new move I have to check that the motor is not running.
    When the library is use with an human machine interface it is quite annoying. Is it on your todo list to improve that?
    For my purpose it would be great if the target can be change any time.
    For example the absolute stepper position is 10000, I send an absolute move to 0, the motor starts to rotate and accelerate.... now I send a command move absolute to 20000, the motor must first decelerate and then goto the new target.

    Charles

  13. #63
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429
    Currently when I use your library before I start a new move I have to check that the motor is not running.
    Yes, the design goal was automated synchronized movements

    When the library is use with an human machine interface it is quite annoying.
    Agreed.

    Is it on your todo list to improve that?
    Sort of.
    First of all, solving that for one motor would be quite simple, but the whole architecture of the library is done for multiple synchronized motors. So what should happen to the other motors if you change the target for one motor on the fly? Technically you'd need to recalculate all acceleration and Bresenham parameters, take care that the transistion is smooth for all motors etc... So I'm a bit reluctant to open that can of worms.

    However, I recently added the possibility to override the speed in the rotational modes. (see the development branch of the library). This can easily be used to do a very simple position regulator. The motor will then follow any change of the target position as quick as possible. I think that this could be used for a human interface as well.

    Here a few examples showing the application of that feature

    The slider/pen in this example follows a simple function (cos(k*phi) calculated from the rotation angle (phi) of the spindle motor. Instead of calculating the target you could of course use some user input.



    Here the speed and precision of the principle is demonstrated.



    And here https://github.com/luni64/TeensyStep...onFollower.ino some code showing (again) a function follower (Rose functions in this case )


    I'll post an example following user input on the weekend.

    Hope that helps

  14. #64
    Junior Member
    Join Date
    Feb 2019
    Location
    France
    Posts
    8
    So I'm a bit reluctant to open that can of worms.
    I can understand that

    Could you confirm that the development branch is compiling, I had some issue this afternoon, with my Teensy3.2
    I'll post an example following user input on the weekend.
    Thanks
    Charles

  15. #65
    Junior Member
    Join Date
    Feb 2019
    Location
    France
    Posts
    8
    Hi Luni,
    I tried the new control interface on the dev branch but without success. If you have time it would be nice, if you can update the sample. for my applications I will need all the controllers... For me it seems that there is on the devbranch all what I need.

  16. #66
    Junior Member
    Join Date
    Feb 2019
    Location
    France
    Posts
    8
    I am almost done. I am not the interrupt expert, and maybe can somebody help me.
    on my Teensy 3.2 the pin 23 is used in PWM mode, in the TeensyStep IRQ in the config.h is set to default and an IntervalTimer is used for the Movement tracking.
    The problem is in that configuration the led on the pin 23 is always off, but the stepper works has expected
    If I change in the config.h the IRQ to TIMER_FTM1, the LED on pin 23 is on, but the Stepper in rotation override mode doesn't work any more.

    is there away to clearly assign the IntervalTimer to an IRQ?

    Charles

  17. #67
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429
    I tried the new control interface on the dev branch but without success. If you have time it would be nice, if you can update the sample. for my applications I will need all the controllers... For me it seems that there is on the devbranch all what I need.
    I updated the examples in the development branch to the new interface. Should compile now out of the box.

  18. #68
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429
    I am almost done. I am not the interrupt expert, and maybe can somebody help me.
    on my Teensy 3.2 the pin 23 is used in PWM mode, in the TeensyStep IRQ in the config.h is set to default and an IntervalTimer is used for the Movement tracking.
    The problem is in that configuration the led on the pin 23 is always off, but the stepper works has expected
    If I change in the config.h the IRQ to TIMER_FTM1, the LED on pin 23 is on, but the Stepper in rotation override mode doesn't work any more.
    If you post a minimal example showing the effect I can have a look into it.

    is there away to clearly assign the IntervalTimer to an IRQ?
    TeensyStep should not have problems with other code using IntervalTimers as long as there are some left. (Each controller uses one interrupt timer, total number of available timers: 4)

  19. #69
    Junior Member
    Join Date
    Feb 2019
    Location
    France
    Posts
    8
    Thanks that's great!

  20. #70
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429
    Here a quick implementation of a "user input follower". I simulated the user input by using a random number between +/- 10000 as target and update that number every second. The motor regulates its position to the new target in the background. The regulator is implemented as a very simple P regulator (if necessary, extending to a full PID is straight forward). The picture shows the motor position (blue) and the target posiiton (orange) over time.

    Click image for larger version. 

Name:	follower2.PNG 
Views:	24 
Size:	10.7 KB 
ID:	15999

    Code:
    #include "Arduino.h"
    #include "TeensyStep.h"
    
    constexpr unsigned PID_Interval = 10; // ms  
    constexpr float P = 0.01;             // (P)roportional constant of the regulator needs to be adjusted (depends on speed and acceleration setting)
    
    Stepper stepper(0, 1);
    RotateControl controller;
    
    int32_t target = 0;
    
    void pid()
    {
      static unsigned lastTick = 0;
    
      if (millis() - lastTick > PID_Interval)
      {    
        float delta = (target - stepper.getPosition()) * (P / PID_Interval);  // This implements a simple P regulator (can be extended to a PID if necessary)
        float factor = std::max(-1.0f, std::min(1.0f, delta)); // limit to -1.0..1.0
    
        controller.overrideSpeed(factor); // set new speed
        lastTick = 0;
      }
    }
    
    void setup()
    {
      pinMode(LED_BUILTIN, OUTPUT);
    
      while (!Serial && millis() < 1000);
    
      stepper
          .setMaxSpeed(10000)
          .setAcceleration(75000);
    
      controller.rotateAsync(stepper);
      controller.overrideSpeed(0); // start with stopped slide
    }
    
    elapsedMillis retargetTimer = 0;
    elapsedMillis outputTimer = 0;
    
    void loop()
    {
      pid();
      
      if(retargetTimer > 1000)  // new random target every second 
      {
        retargetTimer = 0;
        target = random(-10000, 10000);
      }
    
      if (outputTimer > 20)  // print position for display
      {
        outputTimer = 0;
        Serial.printf("%d\t%d\t%d\n", millis(), stepper.getPosition(), target);
      }
    }
    Last edited by luni; 02-23-2019 at 07:33 PM.

  21. #71
    Junior Member
    Join Date
    Feb 2019
    Location
    France
    Posts
    8
    Thanks luni!
    The graph looks really really good. Great video Documentation and I like the implementation too.
    just a small information for people that have problem to compile the TeensyStep lib: please update your arduino IDE and Teensy lib.
    ***dein Lib ist hammergeil***

  22. #72
    Junior Member
    Join Date
    Feb 2019
    Location
    France
    Posts
    8
    Hi luni,

    I guess, I found a small bug on the dev branch in the method getCurrentSpeed
    Code:
    inline int getCurrentSpeed()
      {
        return timerField.getStepFrequency();
      }
    timerField has no method called getStepFrequency.

    Charles

  23. #73
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429
    Sorry for the late answer, I was quite busy the last days. Fixed that and updated the code on GitHub. Should work now.

  24. #74
    Junior Member
    Join Date
    Feb 2019
    Location
    France
    Posts
    8
    Thanks!
    it works very well, there is just a minor bug: when it is no more running, it returns the last valid speed and not 0. But it is a minor issue.
    I added you to the list of contributors of my project.
    Merci beaucoup.
    Charles

  25. #75
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    429
    Great that everything works. I'll have a look at the issue with the returned speed.
    I'm currently working on a documentation web page, may I add a link to your project page in the applications section?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •