RoseFunctionFollower.ino 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include "Arduino.h"
  2. #include "TeensyStep.h"
  3. //spindle settings
  4. constexpr unsigned rpm = 15;
  5. constexpr unsigned spindleSPR = 6400; // stp per rev
  6. constexpr unsigned spindleSpeed = rpm * spindleSPR / 60; // stp/sec
  7. constexpr unsigned spindleStepPin = 1;
  8. constexpr unsigned spindleDirPin = 2;
  9. //slide settings
  10. constexpr unsigned slideAmplitude = 10000; // stp
  11. constexpr unsigned slideSpeed = 35000; //stp/sec
  12. constexpr unsigned slideStepPin = 3;
  13. constexpr unsigned slideDirPin = 4;
  14. //accuracy
  15. IntervalTimer tickTimer;
  16. constexpr unsigned recalcPeriod = 25'000; //µs period for calculation of new target points. Straight lines between those points.
  17. constexpr float dt = recalcPeriod / 1E6; // seconds
  18. // rose fuction
  19. constexpr int n = 5;
  20. constexpr int d = 8;
  21. constexpr float k = (float)n / d;
  22. float slideFunc(float spindleAngle)
  23. {
  24. float phi = fmodf(spindleAngle * k, TWO_PI);
  25. return slideAmplitude * cosf(phi);
  26. }
  27. // TeensyStep
  28. RotateControl slideController;
  29. RotateControl spindleController;
  30. Stepper spindle(spindleStepPin, spindleDirPin);
  31. Stepper slide(slideStepPin, slideDirPin);
  32. //------------------------------------------------------------------------------------
  33. // tick()
  34. //
  35. // This function is called periodically with period recalcPeriod.
  36. // It calculates
  37. // 1) a new target value for the slide depending on the spindle angle
  38. // 2) the new speed for the spindle so that it will reach the target until it is called again
  39. void tick()
  40. {
  41. float spindleAngle = spindle.getPosition() * (TWO_PI / spindleSPR); //convert steps to angle
  42. float slidePosition = slide.getPosition();
  43. float slideTarget = slideFunc(spindleAngle);
  44. float newSpeed = (slideTarget - slidePosition) / dt; // speed to reach target in given delta t (neglecting acceleration)
  45. float speedFac = newSpeed / slideSpeed; // transform in relative factor (-1.0 .. 1.0)
  46. slideController.overrideSpeed(speedFac); // set new speed
  47. }
  48. void setup()
  49. {
  50. pinMode(LED_BUILTIN, OUTPUT);
  51. while (!Serial && millis() < 1000);
  52. spindle
  53. .setMaxSpeed(spindleSpeed)
  54. .setAcceleration(50000);
  55. slide
  56. .setMaxSpeed(slideSpeed)
  57. .setAcceleration(150000)
  58. .setPosition(slideFunc(0)); // set start position of counter
  59. spindleController.rotateAsync(spindle); // let the spindle run with constant speed
  60. slideController.rotateAsync(slide);
  61. slideController.overrideSpeed(0); // start with stopped slide
  62. tick();
  63. // use a timer to periodically calculate new targets for the slide
  64. tickTimer.priority(255); // lowest priority, potentially long caclulations need to be interruptable by TeensyStep
  65. tickTimer.begin(tick, recalcPeriod);
  66. }
  67. void loop()
  68. {
  69. digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
  70. // print current values of spindle angle [rad] and slide position [steps]
  71. float phi = spindle.getPosition() * (TWO_PI / spindleSPR);
  72. int32_t r = slide.getPosition();
  73. Serial.printf("%f\t%d\n", phi, r);
  74. delay(20);
  75. }