Spindle pulley ratio and PWM control

More
23 Nov 2010 18:49 #5569 by Ivan
How to make closed loop spindle speed control with a change pulley ratio, like in Mach3?

Please Log in or Create an account to join the conversation.

More
23 Nov 2010 21:38 #5576 by andypugh
Do you want the system to automatically change gear to suit the selected speed?

Please Log in or Create an account to join the conversation.

More
24 Nov 2010 04:06 #5580 by Ivan
andypugh wrote:

Do you want the system to automatically change gear to suit the selected speed?

No.
Pulley ratio coefficient need to calculate the correct PWM to control the spindle motor.

Please Log in or Create an account to join the conversation.

More
24 Nov 2010 10:06 #5583 by andypugh
You mention closed-loop. If your spindle speed control is closed loop (with a speed feedback into EMC2) then it doesn't matter what the pulley ratio is (I have such a system on my 2-speed milling machine).
wiki.linuxcnc.org/cgi-bin/emcinfo.pl?Clo...pindle_Speed_Control

There is also a HAL component called gearchange, but I am not completely clear what it does:
www.linuxcnc.org/docview/html//man/man9/gearchange.9.html

To do what I think you want to do you can use the mux8 (or mux4, mux2, mux16, depending on how many gears you have)
www.linuxcnc.org/docview/html//man/man9/mux8.9.html

You will need to add lines to the HAL file (probably the custom.hal file) with entries like

loadrt mux8
loadrt mult2

addf mux8.0 servo-thread
addf mult2.0 servo-thread

net speed-cmd motion.spindle-speed-out => mult2.in0
net speed_scale mux8.0.out => mult2.0.in1
net speed-out mult2.0.out => {You will need to put the PWM or whatever you are controlling spindle speed with here}

setp mult2.in0 10
setp mult2.in1 20
setp mult2.in3 30
setp mult2.in4 40

(etc)

You also need to connect up the mux8.0.sel0, sel1 and sel2 pins. These would normally be connected to switches on the gearbox shafts which encode the gearchange position. The details of that are rather application-specific.

Please Log in or Create an account to join the conversation.

More
24 Nov 2010 16:45 #5589 by Ivan
Many thanks andypugh, very useful information. I will experiment with a component gearchange.

Please Log in or Create an account to join the conversation.

More
26 Nov 2010 21:41 - 26 Nov 2010 21:42 #5650 by Ivan
Experiment with the component gearchange perfectly turned out.
I modified the standard component gearchange, this work test code:
pin in bit sel1 "Gear range 1 selection input";
pin in bit sel2 "Gear range 2 selection input";
pin in bit sel3 "Gear range 3 selection input";
pin in float speed_in "Speed command input";
pin out float speed_out "Speed command to DAC/PWM";
param rw float min1 = 0 "Minimum allowed speed in gear range 1";
param rw float max1 = 100000 "Maximum allowed speed in gear range 1";
param rw float min2 = 0 "Minimum allowed speed in gear range 2";
param rw float max2 = 100000 "Maximum allowed speed in gear range 2";
param rw float min3 = 0 "Minimum allowed speed in gear range 3";
param rw float max3 = 100000 "Maximum allowed speed in gear range 3";
param rw float scale1 = 1.0 "Ratio in gear range 1";
param rw float scale2 = 1.0 "Ratio in gear range 2";
param rw float scale3 = 1.0 "Ratio in gear range 3";

function _;
license "GPL";
;;
FUNCTION(_) {
    hal_float_t temp_in = speed_in;
    if (temp_in < 0) temp_in = -temp_in;
    if(sel1){ /*first gear range*/
       	   if (scale1 <= 0){
       	      if (scale1 < 0) scale1 = -scale1;
    	         else if (scale1 == 0) scale1 = 1;
    	      }
    	   if (temp_in < min1) temp_in = min1;
    	   else if (temp_in > max1) temp_in = max1;
           temp_in *= scale1;		/* scale up to first gear output range */
    }
    if(sel2){ /*second gear range*/
       	   if (scale2 <= 0){
       	      if (scale2 < 0) scale2 = -scale2;
    	         else if (scale2 == 0) scale2 = 1;
    	      }
    	   if (temp_in < min2) temp_in = min2;
    	   else if (temp_in > max2) temp_in = max2;
    	   temp_in *= scale2;		/* scale up to second gear output range */
    }
    if(sel3){ /*third gear range*/
       	   if (scale3 <= 0){
       	      if (scale3 < 0) scale3 = -scale3;
    	         else if (scale3 == 0) scale3 = 1;
    	      }
    	   if (temp_in < min3) temp_in = min3;
    	   else if (temp_in > max3) temp_in = max3;
    	   temp_in *= scale3;		/* scale up to third gear output range */
    }
    speed_out = temp_in;
}
Hal:
...
loadrt gearchange
addf gearchange.0 servo-thread

setp gearchange.0.min1 65
setp gearchange.0.min2 150
setp gearchange.0.min3 330
setp gearchange.0.max1 650
setp gearchange.0.max2 1500
setp gearchange.0.max3 3300
setp gearchange.0.scale1 5.076923077
setp gearchange.0.scale2 2.2
setp gearchange.0.scale3 1

net spindle-cmd-ns <= motion.spindle-speed-out => gearchange.0.speed-in
net spindle-cmd <= gearchange.0.speed-out => pwmgen.0.value
...

Who thinks about this component?
Attachments:
Last edit: 26 Nov 2010 21:42 by Ivan.

Please Log in or Create an account to join the conversation.

More
26 Nov 2010 21:54 #5651 by andypugh
Ivan wrote:

Who thinks about this component?


It would be nice to make it as a component with "personality" which could have a configurable number of gears.

Please Log in or Create an account to join the conversation.

More
26 Nov 2010 22:11 #5652 by Ivan

andypugh wrote:
It would be nice to make it as a component with "personality" which could have a configurable number of gears.

Even now, this component is not difficult to modify for the required number of gears.
Or you can add the maximum amount of gear (10-15), and the required amount set in the hal file?

Please Log in or Create an account to join the conversation.

More
27 Nov 2010 13:15 #5660 by Ivan
Finally completed the component gearchange:
pin in bit sel1 "Gear range 1 selection input";
pin in bit sel2 "Gear range 2 selection input";
pin in bit sel3 "Gear range 3 selection input";
pin in float speed_in "Speed command input";
pin out float speed_filtred "Speed command to display";
pin out float speed_out "Speed command to DAC/PWM";
param rw float min1 = 0 "Minimum allowed speed in gear range 1";
param rw float max1 = 100000 "Maximum allowed speed in gear range 1";
param rw float min2 = 0 "Minimum allowed speed in gear range 2";
param rw float max2 = 100000 "Maximum allowed speed in gear range 2";
param rw float min3 = 0 "Minimum allowed speed in gear range 3";
param rw float max3 = 100000 "Maximum allowed speed in gear range 3";
param rw float scale1 = 1.0 "Ratio in gear range 1";
param rw float scale2 = 1.0 "Ratio in gear range 2";
param rw float scale3 = 1.0 "Ratio in gear range 3";

function _;
license "GPL";
;;
FUNCTION(_) {
  hal_float_t temp_in = speed_in;
  if (temp_in != 0){
    if (temp_in < 0) temp_in = -temp_in;
    if(sel1){ /*first gear range*/
       	   if (scale1 <= 0){
       	      if (scale1 < 0) scale1 = -scale1;
    	         else if (scale1 == 0) scale1 = 1;
    	      }
    	   if (temp_in < min1) temp_in = min1;
    	   else if (temp_in > max1) temp_in = max1;
    	   speed_filtred = temp_in;
           temp_in *= scale1;		/* scale up to first gear output range */
    }
    if(sel2){ /*second gear range*/
       	   if (scale2 <= 0){
       	      if (scale2 < 0) scale2 = -scale2;
    	         else if (scale2 == 0) scale2 = 1;
    	      }
    	   if (temp_in < min2) temp_in = min2;
    	   else if (temp_in > max2) temp_in = max2;
    	   speed_filtred = temp_in;
    	   temp_in *= scale2;		/* scale up to second gear output range */
    }
    if(sel3){ /*third gear range*/
       	   if (scale3 <= 0){
       	      if (scale3 < 0) scale3 = -scale3;
    	         else if (scale3 == 0) scale3 = 1;
    	      }
    	   if (temp_in < min3) temp_in = min3;
    	   else if (temp_in > max3) temp_in = max3;
    	   speed_filtred = temp_in;
    	   temp_in *= scale3;		/* scale up to third gear output range */
    }
    speed_out = temp_in;
  }else{
    speed_filtred = 0;
    speed_out = 0;
  }

}

File Attachment:

File Name: gearchange.gz
File Size:1 KB

I accept any comments and ideas on this component.
Attachments:

Please Log in or Create an account to join the conversation.

More
29 Nov 2010 15:44 - 29 Nov 2010 15:48 #5730 by andypugh
Here's my version, completely untested, written in notepad with no reference to a C compiler, nor EMC2, nor even Linux.

This should work for up to 32 gears using:
loadrt gearchange count=2 personality=5,6
It accepts negative speeds, negative outputs and negative scales to allow for gear ranges that reverse the motion.

pin in bit sel-## [32 : personality+1] "Gear range N selection input";
pin in unsigned gear-number "Gear selection as a numeric"
pin in float speed_in "Speed command input";
pin out float speed_filtered "Speed command to display";
pin out float speed_out "Speed command to DAC/PWM";
param rw float min-##[32: personality+1] = 0 "Minimum allowed speed in gear range N";
param rw float max-##[32:personality+1] = 100000 "Maximum allowed speed in gear range N";
param rw float scale-##[32:personality+1] = 1.0 "Ratio in gear range 1";

function _;
license "GPL";
;;
#include <rtapi_math.h>
FUNCTION(_) {
int gear;
if (gear_number) gear = gear_number;
else for (gear = personality ; sel_(gear) || gear=0 ; gear--) {}
speed_filtered = fabs(speed_in);
speed_out = speed in * (scale_(gear) != 0)? scale_(gear) : 1;
if (speed_filtered > max_(gear)) speed_out = max_(gear) * (speed_out/speed_filtered); // no "sign" function in rtapi maths
elseif ((speed_filtered < min_(gear)) speed_out = min_(gear) * (speed_out/speed_filtered) ;
}
Last edit: 29 Nov 2010 15:48 by andypugh.

Please Log in or Create an account to join the conversation.

Time to create page: 0.083 seconds
Powered by Kunena Forum