adccommunitymod (AutomationDirect) asked a question.

PWM Ramping (Feature Request)

Created Date: February 03,2020

Created By: jamestalmage

**** This post has been imported from our legacy forum. Information in this post may be outdated and links contained in the post may no longer work.****

When using the PWM modules to control a stepper, it would be nice to have a smooth acceleration curve built in. The API doesn't seem to accommodate that. I am sure it is possible to send frequency changes very rapidly, but most Arduino stepper libraries modify the pulse interval with every step during ramp up and ramp down.


  • adccommunitymod (AutomationDirect)

    Created Date: February 03,2020

    Created by: jamestalmage

    When using the PWM modules to control a stepper, it would be nice to have a smooth acceleration curve built in. The API doesn't seem to accommodate that. I am sure it is possible to send frequency changes very rapidly, but most Arduino stepper libraries modify the pulse interval with every step during ramp up and ramp down.

  • adccommunitymod (AutomationDirect)

    Created Date: February 03,2020

    Created by: jamestalmage

    Thank you for the quick reply.

    I'm all for keeping it simple. Anything that can be implemented in a userland module should be.

    I considered your solution. I would need to modify it (I can't block during acceleration, and I need to accelerate multiple motors at the same time). My only concern was weather the acceleration curve would be smooth enough sending them periodically over the serial bus like that (my experience with Arduino steppers, I'm driving pins directly from the Arduino, not a separate module).

    Expand Post
  • adccommunitymod (AutomationDirect)

    Created Date: February 03,2020

    Created by: FACTS_ENG_TEAM1

     

    The P1AM library itself is focused on basic IO functions. We didn't include anything purpose specific like stepper acceleration. That being said, if we start seeing certain things frequently be requested as core features we may re-evaluate that approach. Currently, forum posts and library examples are our preferred method for this sort of thing.

     

    Since the API is pretty basic though, it does make it simple to create your own functions and libraries for more complex tasks.

    This is a real quick and dirty example of ramping frequency up/down.

     

    1. //channelLabel PWMChannel= {1,1};
    2. void rampPWM(float dutyCycle, uint32_t startFreq, uint32_t targetFreq, uint32_t steps){
    3.  
    4. uint32_t currentFreq = startFreq;
    5. int freqDif = targetFreq - startFreq; //Get difference
    6. int stepDif = freqDif / steps; //Get freq change per step
    7.  
    8. P1.writePWM(dutyCycle, startFreq, PWMChannel);
    9.  
    10. for(int i = 0; i < steps; i++){
    11. currentFreq += stepDif; //Increment frequency one ramp step
    12. P1.writePWMFreq(currentFreq, PWMChannel); //Write change
    13. }
    14. }

     

    You can definitely give it a shot using some non-blocking logic. If you aren't familiar with doing that, the blinkWithoutDelay example for Arduino shows a simple approach. You could use millis() or micros() to try and factor in the delay in base communications with that timing as well.

    Another time save would be looking at the writeBlockData() function. It's more complicated to use, but would allow you to write to several channels at once. There's plenty to explore in how you ramp your curve as well, maybe a non-linear approach would work well for you.

    The left hand side header has some PWM pins like a normal Arduino as well. Using simple micro pins will always have the best speed/latency, though you lose all of the ruggedness an actual P1000 module brings to the table.

    Expand Post