luni64 / TeensyStep

Fast Stepper Motor Library for Teensy boards
https://luni64.github.io/TeensyStep/
MIT License
274 stars 56 forks source link

Closed Loop Steppers controlled by teensy #39

Closed dimisxls closed 5 years ago

dimisxls commented 5 years ago

hi luni64! Congratulations on the amazing work you have done. I have been using the teensy step library for some time to drive a boring machine with multiple drills (4). The selected drill lowers down with pneumatic valve and moves in three dimensions (XYZ) with nema 34 stepper motors (2 for X and 1 for each Y and Z). All these are guided by a teensy 3.5 plugged on a pcb board of my own design (5vTTL and optical isolated switches and relays) .

To have high precision in movements I only use 1.8 degree steps and I have set the drivers at 800 steps per round for smooth movement. So I use steps multiple of 4 to drive the motors (the same for home position). The problem is that I have a very low resolution on X and Y axes. With 31 teeth module1 pinion the resolution is 31 * 3,1415 / 200 = 0.48 mm for each step. An analysis of 0.1mm per step would be completely satisfactory and for this I'm thinking of using microstepping and closed loop motors controlled by teensy.

Do you think that tennsy can drive 3 motors simultaneously and read the 3 encoders at the same time? A second thought is to use 2 teensy, one for driving and one for reading, which will communicate once the drill reaches its target so that it can check if the coordinates (X and Y) are correct before z movement.

luni64 commented 5 years ago

Hi, glad that you like TeensyStep. Moving 3 motors at moderate speed and reading out 3 encoders will definitely not generate a significant load on a Teensy 3.2

Remarks: I don't think that you really need a closed loop system for that kind of application. I'd do a simple experiment and increase the microstepping to 16 (3200 steps / rev) and measure the precision.

If I understand correctly, you are using a rack/pinion drive? Couldn't you switch to a simple lead screw drive? At a pitch of 6mm you'd get a resolution of 6mm/800steps = 0.0075mm/step. Best

dimisxls commented 5 years ago

hi! I use rack/pinion drive because X and Y axis are quite long for lead screw. The table is 3000mm on X, 1300mm on Y and also I want it the machine to be fast. I ve noticed that with microstepping the machine looses stepps after a while becouse it is heavy and it moves fast. Probably drives can't hold the position betwin the 1.8 degrees angle of stepper motor poles.

That's why i am thinking of closed loop steppers with full control by microcontroler. Maybe that solution wouldn't prevent the deflection on axis position betwin the poles instantaneously (if that loss comes from the pressure exerted the moment the drill hits the surface of the panel and not from the rapid accelaration/decelaration) but that deflection would not be cummulative.

luni64 commented 5 years ago

Sorry for the late answer. Here a few comments:

I ve noticed that with microstepping the machine looses stepps after a while becouse it is heavy and it moves fast.

In principle microstepping has nothing to do with step losses. In fact a stepper can only loose multiples of 4 full steps. You can easily check that yourself if you reduce the motor current so that you can move the motor by hand. It will jump into fixed rast points every 7.2°. What are typical step frequencies in your application?

Achieving 0.1mm accuracy should be no problem at all, there are a lot of home brew cnc projects in that size out there which claim to have an accuracy better than 0.01mm. Maybe you can learn something from those projects.

and also I want it the machine to be fast.

That's the usual problem with steppers, in reality you can't move them much faster as some 500 rpm. Servos are much better in this respect.

Anyway, I just posted the following code in the PJRC forum. I think it can be adapted easily for a closed loop regulator. So this might be a good starting point for first feasibility experiments.

#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 accelerator 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 coordinates for display
  {
    outputTimer = 0;
    Serial.printf("%d\t%d\n", millis(), stepper.getPosition());
  }
}
dimisxls commented 5 years ago

Hi luni64,

Thank you for your answer. This conversation was enlightening to me, particularly after reading your topic to pjrc forum which I was not aware of it. I think you are right about closed loop stepper motors, they are complicated and not worth applying (code for encoders uses interrupt pins that maybe affect the program) . I will try to lower the acceleration in compination with microstepping and maybe I will implement a time belt/pulley to pinion drive in a way to increase mechanicaly the resolution.

There is something else also. When I noticed step losses teensy board was not completely optical isolated from relays and when spindle motors were toggling on or off there was an unusual behavor to the microcontroler, probably from inductive current. After optical isolation microcontroller works perfectly. So I have to test accuracy again

By the way, typical step frequencies are : PullInSpeed: 40 MaxSpeed: 3000 Accelaration: 6000

microstepping 1/4 Pinion resolution: 97.39mm per round (module:1, Z:31) Steppers: Nema34 1841oz/in, 5A

luni64 commented 5 years ago

Thanks for the info. Your speed and acceleration settings are very slow, On a T3.2, TeensyStep should not have any issues up to about 100kHz. Trying it with the optical isolators is a very good idea. Do you have some videos/photos of your machine? I'm always interested in what people are building with the library. Best

dimisxls commented 5 years ago

Good news!

I tested the machine without multiplying steps by 4 and there was no step loss so far. With 800 steps per revolution I have 0.12mm resolution witch is more than enough for my application.

Here is a video of the machine: https://youtu.be/B-9xlkEFI9I

and a photo of teensy: https://photos.app.goo.gl/2jwP19MeYxTDUE238

luni64 commented 5 years ago

Perfect, the machine looks really good. I like pragmatic ideas like the use of normal hand drill instead of expensive spindles. May I post a link to the video on the github page?

dimisxls commented 5 years ago

Yes sure you can post a link!

xoxota99 commented 5 years ago

The "overrideSpeed" method doesn't seem to actually exist in the released version. Can you release it?

EDIT: For that matter, the RotateControl class is also absent. Where is the code for this?

luni64 commented 5 years ago

The "overrideSpeed" method doesn't seem to actually exist in the released version. Can you release it? EDIT: For that matter, the RotateControl class is also absent. Where is the code for this?

Sorry, didn't see the last message. The code is still in the development branch. Just switch to develop here

image

to download or clone the library

luni64 commented 5 years ago

Yes sure you can post a link!

I finally found some time to setup a TeensyStep web page and added a link to your nice video: http://127.0.0.1:4000/TeensyStep/applications/cnc_drill/

Feel free to send me some more content if you like.

dimisxls commented 5 years ago

hello luni64,

I installed V2 and everything seems ok. There was an unusal behavor after the installation and the modifications according, but it may not mean anything.

Here is a part of code where the z axis pulls back (V1): .... motor_4.setTargetAbs(xyzz[5][i]); if (motor_4.getPosition() > xyzz[5][i]) { // axis Z speed motor_4.setMaxSpeed(8000); } else { motor_4.setMaxSpeed(12000); } controller1.moveAsync(motor_4); while (controller1.isRunning()) { .....

After the installation, z axis instead of going backwards, it was going forwards. I moved the .setTargetAbs after the .setMaxSpeed and it worked properly.

After: .... if (motor_4.getPosition() > xyzz[5][i]) { // axis Z speed motor_4.setMaxSpeed(8000); } else { motor_4.setMaxSpeed(12000); } motor_4.setTargetAbs(xyzz[5][i]); controller1.moveAsync(motor_4); while (controller1.isRunning()) { .....

luni64 commented 5 years ago

Thanks for testing.
Possible reason for your issue: Both, setTargetAbs and setMaxSpeed will set the direction pin according to their sign. If you have a negative target and call a "positive" setMaxSpeed later the direction will be overridden.

Did you have a look at the web page? https://luni64.github.io/TeensyStep/applications2/015_cnc_drill Posted a video of your machine. Feel free to add more info if you like. Best