Giter VIP home page Giter VIP logo

Comments (17)

dinther avatar dinther commented on August 16, 2024 1

I left it running for 30 minutes and as you can see that code worked perfectly fine.

Wheel_sample_1.mp4

In the reality stepper motors never suddenly get engaged to a speed. Inertia and poor torque causes the motor to loose track with the rotating field and it could just sit there and rattle instead.

Normally an acceleration mechanism is built in.

I did a crude one where I increased the speed in a for loop. Increasing the speed one unit at the time didn't work well. The acceleration was not smooth and the wheel just decelerated in two steps. But the below code in steps of 10 did work.

void loop() 
{
  int i;
  for (i = 1; i < 100; ++i)
  {
    setSpeed(i*10);
    delay(30);
  }
  for (i = 100; i > 0; --i)
  {
    setSpeed(i*10);
    delay(30);
  }

  for (i = 0; i > -100; --i)
  {
    setSpeed(i*10);
    delay(30);
  }

  for (i = -100; i < 0; ++i)
  {
    setSpeed(i*10);
    delay(30);
  }
}

That is of course incredibly inefficient. First of all I have no idea how many calls are made as a result of calling
stepper->setPWM(STEP_PIN, 500, 0); and the use of delay is bad. But it worked OK.

Wheel_sample_2.mp4

The TCM2209 is an incredibly advanced driver chip rarely used to it's potential. Currently used in it's most basic form: using STEP and DIR pins. I already have working code to set the finer features of the chip via UART. The most notable features of the TMC2209 are the ability to micro step and allows a user specified max current to the motor coils by using what they call the Chopper. But from what I understand this is all just PWM based

Realizing the speed and capability of the Pico PIO I think it should be possible to move the most important features of the TMC2209 into the pico POI and replace the TCM2209 driver with basic power electronics in the form of a few mosfets. The resulting footprint of the pico and a few mosfets would be tiny.

from rp2040_pwm.

dinther avatar dinther commented on August 16, 2024 1

In my application I don't need acceleration because I manage that in my own code. Currently I am currently using this library https://github.com/bblanchon/ArduinoContinuousStepper It's the continuous rotation aspect that drew me to this library. PWM is of course perfect for continuous rotation. Most Stepper motor users will be more interested in position operation or in other words: Rotate the stepper motor x steps cockwise with a certain acceleration deceleration profile.

I am pleased you ran with the PWM idea and embraced some out of the box thinking. I need to experiment and educate myself with PIO and get a better handle on what might be possible. Replacing the stepper driver with mosfets is actually not that simple.

from rp2040_pwm.

khoih-prog avatar khoih-prog commented on August 16, 2024

Hi @dinther

I'm glad that you find out a new way to drive the stepper-motor driver using PWM, instead of using conventional Timers, etc.
The fully-hardware PIO PWM of cheap-yet-powerful RP2040 is perfect for this purpose to offload the MPU for other purposes.

You can read The RP2040's PWM excellence to appreciate RP2040 PWM if you'd like to use for more complex purpose (phase-shift PWM, etc.)

there is a common clock and my motors will be perfectly in sync.

I believe you're correct.

Best Regards,

from rp2040_pwm.

khoih-prog avatar khoih-prog commented on August 16, 2024

Hi @dinther

Just have an idea from you novel implementation using PWM for Stepper-Motor control, which is better solution than using Timers.

As I have many PWM-related libraries, can you make PRs to add the similar examples controlling Stepper to those libraries, as I don't have the motor as well as driver (such as TMC2209) to test.

Please inform if you're OK

Best,

from rp2040_pwm.

dinther avatar dinther commented on August 16, 2024

I have not checked your source yet but I have been assuming that the RP2040 uses PIO for PWM because PIO can also offer up to 8 independent channels. Same limit as PWM other limitations match PIO limitations as well. You are absolutely correct that the PIO is just ideal for this from what I read and watched in PIO for beginners videos. I am way out of my depth on all this as I don't have the expertise you have.

I will have to dig deeper but a stepper library making use of PIO is the right way to go about it. I definitely avoid timers.

This code below using your library worked although after a while I noticed irregularities in the running of the motor. I have not examined that yet. I'' put it on the oscilloscope sometime this week.

// Use with Stepper-Motor driver, such as TMC2209

#define _PWM_LOGLEVEL_        1

#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || \
      defined(ARDUINO_GENERIC_RP2040) ) && defined(ARDUINO_ARCH_MBED)

  #if(_PWM_LOGLEVEL_>3)
    #warning USING_MBED_RP2040_PWM
  #endif

#elif ( defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || \
        defined(ARDUINO_GENERIC_RP2040) ) && !defined(ARDUINO_ARCH_MBED)

  #if(_PWM_LOGLEVEL_>3)
    #warning USING_RP2040_PWM
  #endif
#else
  #error This code is intended to run on the RP2040 mbed_nano, mbed_rp2040 or arduino-pico platform! Please check your Tools->Board setting.
#endif

#include <RP2040_PWM.h>

RP2040_PWM* stepper;

#define STEP_PIN      8
#define DIR_PIN       9

void setSpeed(int speed)
{
  if (speed == 0)
  {
    // Use DC = 0 to stop stepper
    stepper->setPWM(STEP_PIN, 500, 0);
  }
  else
  {
    //  Set the frequency of the PWM output and a duty cycle of 50%
    digitalWrite(DIR_PIN, (speed < 0));
    stepper->setPWM(STEP_PIN, abs(speed), 50);
  }
}

void setup() 
{
  pinMode(DIR_PIN, OUTPUT);
  
  Serial.begin(115200);

  while (!Serial && millis() < 5000);

  delay(100);

  Serial.print(F("\nStarting PWM_StepperControl on "));
  Serial.println(BOARD_NAME);
  Serial.println(RP2040_PWM_VERSION);
  
  // Create PWM object and passed just a random frequency of 500
  // The duty cycle is how you turn the motor on and off
  stepper = new RP2040_PWM(STEP_PIN, 500, 0);
}

void loop() 
{
  setSpeed(1000);
  delay(3000);

  // Stop before reversing
  setSpeed(0);
  delay(3000);

  // Reversing
  setSpeed(-500);
  delay(3000);

  // Stop before reversing
  setSpeed(0);
  delay(3000);
}

from rp2040_pwm.

khoih-prog avatar khoih-prog commented on August 16, 2024

Hi @dinther

Just add the example PWM_StepperControl, with your credit notes.

Credits of Paul van Dinther (https://github.com/dinther). Check https://github.com/khoih-prog/RP2040_PWM/issues/16

Please check, test and report / fix errors

Best,

from rp2040_pwm.

khoih-prog avatar khoih-prog commented on August 16, 2024

Please try this if OK, with stepper stops before reversing

// Use with Stepper-Motor driver, such as TMC2209

#define _PWM_LOGLEVEL_        1

#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || \
      defined(ARDUINO_GENERIC_RP2040) ) && defined(ARDUINO_ARCH_MBED)

  #if(_PWM_LOGLEVEL_>3)
    #warning USING_MBED_RP2040_PWM
  #endif

#elif ( defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || \
        defined(ARDUINO_GENERIC_RP2040) ) && !defined(ARDUINO_ARCH_MBED)

  #if(_PWM_LOGLEVEL_>3)
    #warning USING_RP2040_PWM
  #endif
#else
  #error This code is intended to run on the RP2040 mbed_nano, mbed_rp2040 or arduino-pico platform! Please check your Tools->Board setting.
#endif

#include <RP2040_PWM.h>

RP2040_PWM* stepper;
float frequency;
float dutyCycle;
#define STEP_PIN      8
#define DIR_PIN       9

void setSpeed(int speed)
{
  if (speed == 0)
  {
    // Use DC = 0 to stop stepper
    stepper->setPWM(STEP_PIN, 500, 0);
  }
  else
  {
    //  Set the frequency of the PWM output and a duty cycle of 50%
    digitalWrite(DIR_PIN, (speed < 0));
    stepper->setPWM(STEP_PIN, abs(speed), 50);
  }
}

void setup() 
{
  pinMode(DIR_PIN, OUTPUT);
  
  Serial.begin(115200);

  while (!Serial && millis() < 5000);

  delay(100);

  Serial.print(F("\nStarting PWM_StepperControl on "));
  Serial.println(BOARD_NAME);
  Serial.println(RP2040_PWM_VERSION);
  
  //  Create PWM object and passed just a random frequency of 500 in it
  //  The duty cycle is how you turn the motor on and off
  stepper = new RP2040_PWM(STEP_PIN, 500, 0);
}

void loop() 
{
  setSpeed(1000);
  delay(3000);
  setSpeed(0);
  delay(3000);
  setSpeed(-500);
  delay(3000);
}

from rp2040_pwm.

khoih-prog avatar khoih-prog commented on August 16, 2024

Hi @dinther

The new RP2040_PWM releases v1.4.1 has just been published. Your contribution is noted in Contributions and Thanks

Best Regards,


Releases v1.4.1

  1. Add example PWM_StepperControl to demo how to control Stepper Motor using PWM. Check Using PWM to step a stepper driver #16
  2. Use allman astyle and add utils

from rp2040_pwm.

dinther avatar dinther commented on August 16, 2024

Oh wow, I get to it as soon as I have a clear head. It's been quite the weekend ;-)
I just might have to send you some hardware to play with.

from rp2040_pwm.

khoih-prog avatar khoih-prog commented on August 16, 2024

Hi @dinther

Nice tests and videos.

As you know, the examples are just simple demo for basic way to use the libraries, and everybody has to test and adapt to the real-world use-case.

Your demo videos as well as comments here are so useful for interested users to start experimenting with Stepper-Motors using PWM.

I don't see any issue in changing the speed in smaller steps, as you demonstrate here, to smooth our the movements, and very simple to implement in the code.

Realizing the speed and capability of the Pico PIO I think it should be possible to move the most important features of the TMC2209 into the pico POI and replace the TCM2209 driver with basic power electronics in the form of a few mosfets. The resulting footprint of the pico and a few mosfets would be tiny.

It'd be good if you can improve, or even design a new simpler and cheaper chip (compared to TCM2209). But design new circuit is not so simple for many users. It'll be beneficial if you can post the final working simpler circuit (RP2040 + MOSFETs) to replace TCM2209.

Cheers

from rp2040_pwm.

khoih-prog avatar khoih-prog commented on August 16, 2024

Another note is that your idea of using PWM for Stepper-Motor has been spreading fast to the libraries of mines

  1. RP2040_PWM
  2. AVR_PWM
  3. megaAVR_PWM
  4. ESP32_FastPWM
  5. SAMD_PWM
  6. SAMDUE_PWM
  7. nRF52_PWM
  8. Teensy_PWM
  9. ATtiny_PWM
  10. Dx_PWM
  11. Portenta_H7_PWM
  12. MBED_RP2040_PWM
  13. nRF52_MBED_PWM
  14. STM32_PWM

from rp2040_pwm.

khoih-prog avatar khoih-prog commented on August 16, 2024

If you think it's beneficial, I can write and add some library's functions to smooth-out the Stepper movement, so that you can specify the acceleration rate, interval, acceleration-steps, etc.

from rp2040_pwm.

dinther avatar dinther commented on August 16, 2024

Most users would be using much cheaper stepper drivers such as the DRV8825 or A4988 They work the same way with a step and dir pin but with microstep capability of 16 steps for the A4988 and 32 steps for the DRV8825

However the TMC2209 can do 256 microsteps and for me more importantly it has a build in variable pulse generator. This made it possible to simply set the VACTUAL register in the chip to a value via the UART and that was it. The chip did all the work.

The reason I stopped using it is that the clock speeds between TMC2209 chips vary constantly due temperature. I need absolute synchronization. The chips do have an external clock option but I can not access that So I do it the old Step/Dir way.

from rp2040_pwm.

khoih-prog avatar khoih-prog commented on August 16, 2024

Hi @dinther

Also check the new ContinuousStepper_Generic library for your Contributions


Initial Releases v1.0.0

  1. Initial coding to use PWM to control continuous Stepper Motor. Check Using PWM to step a stepper driver #16
  2. Use allman astyle and add utils

from rp2040_pwm.

dinther avatar dinther commented on August 16, 2024

Oh wow super cool. I will try it in my pico project tomorrow. Thanks for the credit.

from rp2040_pwm.

khoih-prog avatar khoih-prog commented on August 16, 2024

Hi @dinther

Try this for 8.0Hz. You can go to 7.5+ Hz if CPU_F set to 125MHz, and 7.98Hz for 133MHz

Note: Must use float, such as 8.0f or 7.51f. The auto conversion is wrong if use only 8

#define _PWM_LOGLEVEL_        4
#include "RP2040_PWM.h"

//creates pwm instance
RP2040_PWM* PWM_Instance;

float frequency;
float dutyCycle;

#define pinToUse      19    //25

void printPWMInfo(RP2040_PWM* PWM_Instance)
{
  uint32_t div = PWM_Instance->get_DIV();
  uint32_t top = PWM_Instance->get_TOP();

  Serial.print("Actual PWM Frequency = ");
  Serial.println(PWM_Instance->getActualFreq());

  PWM_LOGDEBUG5("TOP =", top, ", DIV =", div, ", CPU_freq =", PWM_Instance->get_freq_CPU());
}

void setup()
{ 
  Serial.begin(115200);

  while (!Serial && millis() < 5000);

  delay(100);

  Serial.print(F("\nStarting PWM_Basic on "));
  Serial.println(BOARD_NAME);
  Serial.println(RP2040_PWM_VERSION);

  frequency = 200;
  
  //assigns pin 25 (built in LED), with frequency of 20 KHz and a duty cycle of 0%
  PWM_Instance = new RP2040_PWM(pinToUse, frequency, 0);

  frequency = 8.0f;
  dutyCycle = 50.0f;
  
  PWM_Instance->setPWM(pinToUse, frequency, dutyCycle);

  printPWMInfo(PWM_Instance);
}

void loop()
{
}

from rp2040_pwm.

khoih-prog avatar khoih-prog commented on August 16, 2024

Debug Terminal

freq = 8.0f @ 125MHz CPU_F
Starting PWM_Basic on RASPBERRY_PI_PICO
RP2040_PWM v1.6.0
[PWM] _PWM_config.top = 62499 , _actualFrequency = 200.00
[PWM] _PWM_config.top = 61273 , _actualFrequency = 8.00
[PWM] Changing PWM frequency to 8.00 and dutyCycle = 50.00
[PWM] pin =  19 , PWM_CHAN = 1
[PWM] PWM enabled, slice =  1 , _frequency =  8.00
Actual PWM Frequency = 8.00
[PWM] TOP = 61273 , DIV = 255 , CPU_freq = 125000000
freq = 7.55f @ 125MHz CPU_F
Starting PWM_Basic on RASPBERRY_PI_PICO
RP2040_PWM v1.6.0
[PWM] _PWM_config.top = 62499 , _actualFrequency = 200.00
[PWM] _PWM_config.top = 64925 , _actualFrequency = 7.00
[PWM] Changing PWM frequency to 7.55 and dutyCycle = 50.00
[PWM] pin =  19 , PWM_CHAN = 1
[PWM] PWM enabled, slice =  1 , _frequency =  7.55
Actual PWM Frequency = 7.00
[PWM] TOP = 64925 , DIV = 255 , CPU_freq = 125000000
freq = 8.0f @ 133MHz CPU_F
Starting PWM_Basic on RASPBERRY_PI_PICO
RP2040_PWM v1.6.0
[PWM] _PWM_config.top = 66499 , _actualFrequency = 200.00
[PWM] _PWM_config.top = 65195 , _actualFrequency = 8.00
[PWM] Changing PWM frequency to 8.00 and dutyCycle = 50.00
[PWM] pin =  19 , PWM_CHAN = 1
[PWM] PWM enabled, slice =  1 , _frequency =  8.00
Actual PWM Frequency = 8.00
[PWM] TOP = 65195 , DIV = 255 , CPU_freq = 133000000

from rp2040_pwm.

Related Issues (11)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.