SPINDLE SERVO SPECS
Moderators: TomKerekes, dynomotion
SPINDLE SERVO SPECS
SO TRYING TO FIGURE OUT SOME SPINDLE SPECS FOR TOP SPEED (RPM)
i got 8192 count servo
servo drives a large pulley at 0.69 ratio
so 11872.46 counts per revolution
i would like to limit lathe spindle to 1500 rpm
so in the C program the Velocity number would be reading just encoder count right? per second or something?
so 1500 rpm is 25 per second
so 25 x 11872.46 is 296811 velocity?
i got 8192 count servo
servo drives a large pulley at 0.69 ratio
so 11872.46 counts per revolution
i would like to limit lathe spindle to 1500 rpm
so in the C program the Velocity number would be reading just encoder count right? per second or something?
so 1500 rpm is 25 per second
so 25 x 11872.46 is 296811 velocity?
Re: SPINDLE SERVO SPECS
That figure looks good to me, although you want to try and keep as much accuracy as possible and not round the number - 296811.5942028985507246
Re: SPINDLE SERVO SPECS
my calculator just saidxxxxx.59 lol
- TomKerekes
- Posts: 2676
- Joined: Mon Dec 04, 2017 1:49 am
Re: SPINDLE SERVO SPECS
Hi turbothis,
Normally speed is limited by simply limiting what the Spindle can be commanded to do.
What are you trying to do? Allow a higher speed to be commanded, then detect when the speed is actually too high, then kill it?
Normally speed is limited by simply limiting what the Spindle can be commanded to do.
What are you trying to do? Allow a higher speed to be commanded, then detect when the speed is actually too high, then kill it?
Regards,
Tom Kerekes
Dynomotion, Inc.
Tom Kerekes
Dynomotion, Inc.
Re: SPINDLE SERVO SPECS
yes sorry
i want to limit what the Spindle can be commanded to do
this is the velocity value in the C program yes?
i want to limit what the Spindle can be commanded to do
this is the velocity value in the C program yes?
- TomKerekes
- Posts: 2676
- Joined: Mon Dec 04, 2017 1:49 am
Re: SPINDLE SERVO SPECS
Hi turbothis,
Post your spindle programs you are using.
Post your spindle programs you are using.
Regards,
Tom Kerekes
Dynomotion, Inc.
Tom Kerekes
Dynomotion, Inc.
Re: SPINDLE SERVO SPECS
i have not added in any spindle details as that was step 2 of getting the main program running
i have the Z axis disabled for now too
i have the Z axis disabled for now too
Code: Select all
#include "KMotionDef.h"
// Home and set the commutation for a 3 phase brushless motor // that is driven using two DAC Outputs // // Phase rotates until index mark is located and Encoder Zeroed
// Function definitions
// x must be in the range 0->1 returns sin(x) and sin(x+120 degrees)
float Sine3PH (float x, float *sin2);
// put a voltage v on a 3 Phase motor at specified commutation angle
void Write3PH_DACs(CHAN *chx, float v, double angle_in_cycles);
// return fractional part of a huge number accurately
float fractionf(double v);
// Main function entry point
void main()
{
float k=0,A=500; // set coil current amplitude DAC units
double p0;
ch0->InputMode=ENCODER_MODE;
ch0->OutputMode=NO_OUTPUT_MODE;
ch0->Vel=5000;
ch0->Accel=5000000;
ch0->Jerk=30000000;
ch0->P=3;
ch0->I=0;
ch0->D=20;
ch0->FFAccel=0;
ch0->FFVel=0;
ch0->MaxI=200;
ch0->MaxErr=1e+006;
ch0->MaxOutput=2000;
ch0->DeadBandGain=1;
ch0->DeadBandRange=0;
ch0->InputChan0=0;
ch0->InputChan1=0;
ch0->OutputChan0=1;
ch0->OutputChan1=0;
ch0->MasterAxis=-1;
ch0->LimitSwitchOptions=0x0;
ch0->SoftLimitPos=1e+030;
ch0->SoftLimitNeg=-1e+030;
ch0->InputGain0=-1;
ch0->InputGain1=1;
ch0->InputOffset0=0;
ch0->InputOffset1=0;
ch0->OutputGain=1;
ch0->OutputOffset=0;
ch0->SlaveGain=1;
ch0->BacklashMode=BACKLASH_OFF;
ch0->BacklashAmount=0;
ch0->BacklashRate=0;
ch0->invDistPerCycle=0.0004;
ch0->Lead=0;
ch0->MaxFollowingError=1000000;
ch0->StepperAmplitude=20;
ch0->iir[0].B0=1;
ch0->iir[0].B1=0;
ch0->iir[0].B2=0;
ch0->iir[0].A1=0;
ch0->iir[0].A2=0;
ch0->iir[1].B0=1;
ch0->iir[1].B1=0;
ch0->iir[1].B2=0;
ch0->iir[1].A1=0;
ch0->iir[1].A2=0;
ch0->iir[2].B0=1;
ch0->iir[2].B1=0;
ch0->iir[2].B2=0;
ch0->iir[2].A1=0;
ch0->iir[2].A2=0;
ch1->InputMode=ENCODER_MODE;
ch1->OutputMode=NO_OUTPUT_MODE;
ch1->Vel=5000;
ch1->Accel=5000000;
ch1->Jerk=30000000;
ch1->P=4;
ch1->I=0;
ch1->D=30;
ch1->FFAccel=0;
ch1->FFVel=0;
ch1->MaxI=200;
ch1->MaxErr=1e+006;
ch1->MaxOutput=2000;
ch1->DeadBandGain=1;
ch1->DeadBandRange=0;
ch1->InputChan0=1;
ch1->InputChan1=1;
ch1->OutputChan0=2;
ch1->OutputChan1=3;
ch1->MasterAxis=-1;
ch1->LimitSwitchOptions=0x0;
ch1->SoftLimitPos=1e+030;
ch1->SoftLimitNeg=-1e+030;
ch1->InputGain0=-1;
ch1->InputGain1=1;
ch1->InputOffset0=0;
ch1->InputOffset1=0;
ch1->OutputGain=1;
ch1->OutputOffset=0;
ch1->SlaveGain=1;
ch1->BacklashMode=BACKLASH_OFF;
ch1->BacklashAmount=0;
ch1->BacklashRate=0;
ch1->invDistPerCycle=0.0004;
ch1->Lead=0;
ch1->MaxFollowingError=1000000;
ch1->StepperAmplitude=20;
ch1->iir[0].B0=1;
ch1->iir[0].B1=0;
ch1->iir[0].B2=0;
ch1->iir[0].A1=0;
ch1->iir[0].A2=0;
ch1->iir[1].B0=1;
ch1->iir[1].B1=0;
ch1->iir[1].B2=0;
ch1->iir[1].A1=0;
ch1->iir[1].A2=0;
ch1->iir[2].B0=1;
ch1->iir[2].B1=0;
ch1->iir[2].B2=0;
ch1->iir[2].A1=0;
ch1->iir[2].A2=0;
ch2->InputMode=ENCODER_MODE;
ch2->OutputMode=NO_OUTPUT_MODE;
ch2->Vel= 296811.5942028985507246;
ch2->Accel=5000000;
ch2->Jerk= 5000000;
ch2->P=15;
ch2->I=0;
ch2->D=20;
ch2->FFAccel=0;
ch2->FFVel=0;
ch2->MaxI=200;
ch2->MaxErr=1e+006;
ch2->MaxOutput=2000;
ch2->DeadBandGain=1;
ch2->DeadBandRange=0;
ch2->InputChan0=2;
ch2->InputChan1=2;
ch2->OutputChan0=5;
ch2->OutputChan1=4;
ch2->MasterAxis=-1;
ch2->LimitSwitchOptions=0x0;
ch2->SoftLimitPos=1e+030;
ch2->SoftLimitNeg=-1e+030;
ch2->InputGain0=-1;
ch2->InputGain1=1;
ch2->InputOffset0=0;
ch2->InputOffset1=0;
ch2->OutputGain=1;
ch2->OutputOffset=0;
ch2->SlaveGain=1;
ch2->BacklashMode=BACKLASH_OFF;
ch2->BacklashAmount=0;
ch2->BacklashRate=0;
ch2->invDistPerCycle=0.0003662109375;
ch2->Lead=0;
ch2->MaxFollowingError=1000000;
ch2->StepperAmplitude=20;
ch2->iir[0].B0=1;
ch2->iir[0].B1=0;
ch2->iir[0].B2=0;
ch2->iir[0].A1=0;
ch2->iir[0].A2=0;
ch2->iir[1].B0=1;
ch2->iir[1].B1=0;
ch2->iir[1].B2=0;
ch2->iir[1].A1=0;
ch2->iir[1].A2=0;
ch2->iir[2].B0=1;
ch2->iir[2].B1=0;
ch2->iir[2].B2=0;
ch2->iir[2].A1=0;
ch2->iir[2].A2=0;
// rotate until we find the index mark
// Use f0 and f1 and f2 to flag when index found for ch0 and ch1 and ch2->
// Break out when both indexes found (f0=1 and f1=1 and f2=1)
ch0->Enable=FALSE;
ch1->Enable=FALSE;
ch2->Enable=FALSE;
int f0,f1,f2; // Index found flags
f0=0;f1=0;f2=0; // Set all to index not found
for (;;) //Indefinite loop
{
if (f0==1 && f1==1 && f2==1) break; // Done if all indexes found
//
if (f0==0) // If Ch0 index not found
{
WaitNextTimeSlice();
Write3PH_DACs(ch0,A, ++k/10000.0); // move the pole
if (ReadBit(36)) // check for index mark ch0
{
p0=ch0->Position; // Index found so save position
ch0->Position=0; // set current position to Zero
ch0->CommutationOffset = 658; // from auto phase find
printf("Position ch0 = %f\n",p0);
f0=1; // Mark as ch0 index found
} // End readbit
} // End if f0=0
//
if (f1==0) // If Ch1 index not found
{
WaitNextTimeSlice();
Write3PH_DACs(ch1,A, ++k/10000.0); // move the pole
if (ReadBit(37)) // check for index mark ch1
{
p0=ch1->Position; // Index found so save position
ch1->Position=0; // set current position to Zero
ch1->CommutationOffset = 658; // from auto phase find
printf("Position ch1 = %f\n",p0);
f1=1; // Mark as ch1 index found
} // End readbit
} // End f1=0
//
if (f2==0) // If Ch2 index not found
{
WaitNextTimeSlice();
Write3PH_DACs(ch2,A, ++k/10000.0); // move the pole
if (ReadBit(38)) // check for index mark ch2
{
p0=ch2->Position; // Index found so save position
ch2->Position=0; // set current position to Zero
ch2->CommutationOffset = 1920; // from auto phase find
printf("Position ch2 = %f\n",p0);
f2=1; // Mark as ch2 index found
} // End readbit
} // End f2=0
} // End for loop
EnableAxisDest(0,0.0f); // Enable servo at destination of 0 X axis
// EnableAxisDest(1,0.0f); // Enable servo at destination of 0 Z axis
EnableAxisDest(2,0.0f); // Enable servo at destination of 0 A axis
DefineCoordSystem(0,-1,-1,2); // define which axes are in use
// Loop forever outputting Servo output to dual DAC_SERVO_MODE
for (;;)
{
WaitNextTimeSlice();
if (ch0->Enable) // if axis enabled commutate and output else command zero to DACs
Write3PH_DACs(ch0,ch0->Output, (ch0->Position + ch0->CommutationOffset) * ch0->invDistPerCycle);
else
Write3PH_DACs(ch0, 0.0,0.0);
if (ch1->Enable) // if axis enabled commutate and output else command zero to DACs
Write3PH_DACs(ch1,ch1->Output, (ch1->Position + ch1->CommutationOffset) * ch1->invDistPerCycle);
else
Write3PH_DACs(ch1, 0.0,0.0);
if (ch2->Enable) // if axis enabled commutate and output else command zero to DACs
Write3PH_DACs(ch2,ch2->Output, (ch2->Position + ch2->CommutationOffset) * ch2->invDistPerCycle);
else
Write3PH_DACs(ch2, 0.0,0.0);
} // End for loop
} // End main()
// put a voltage v on a 3 Phase motor at specified commutation angle
void Write3PH_DACs(CHAN *chx, float v, double angle_in_cycles)
{
float theta,sin1f;
if (angle_in_cycles<0)
theta = 1.0f-fractionf(-angle_in_cycles);
else
theta = fractionf(angle_in_cycles);
DAC(chx->OutputChan0, (int)(v * Sine3PH(theta,&sin1f)));
DAC(chx->OutputChan1, (int)(v * sin1f));
} // End Write3PH()
- TomKerekes
- Posts: 2676
- Joined: Mon Dec 04, 2017 1:49 am
Re: SPINDLE SERVO SPECS
Hi turbothis,
You will need to figure out what kind of Spindle you have and how it will be interfaced before we can help you.
You might see this.
You will need to figure out what kind of Spindle you have and how it will be interfaced before we can help you.
You might see this.
Regards,
Tom Kerekes
Dynomotion, Inc.
Tom Kerekes
Dynomotion, Inc.
Re: SPINDLE SERVO SPECS
well i am running my A axis servo/spindle with the dual DAC outputs
it has 11872.46 counts per rev
so i am thinking this program
with this being run with dual DAC's does the jog program need to be in the axis enable program?
and i am thinking to just have M5 zero output to the DAC's?
it has 11872.46 counts per rev
so i am thinking this program
Code: Select all
#include "KMotionDef.h"
#define SPINDLEAXIS 4
#define FACTOR (1187246.0/6000) // counts per second = RPM
// desired speed is passed in variable 1
// save in user variable 99 the last speed setting
// save in user variable 98 whether it was off, CW, or CCW (0,1,-1)
// save in user variable 97 the last desired speed
main()
{
float speed = *(float *)&persist.UserData[1]; // value stored is actually a float
float LastSpeed = *(float *)&persist.UserData[99]; // get last speed setting
float LastState = persist.UserData[98]; // get last state
if (LastState==0)
{
// if spindle is off and User Changes the speed
// just save the desired speed
persist.UserData[97] = persist.UserData[1];
return 0;
}
// spindle is already on, so ramp to new speed
if (LastSpeed != speed)
{
LastSpeed = speed;
Jog(4,LastSpeed * FACTOR);
}
*(float *)&persist.UserData[99] = LastSpeed;
}
and i am thinking to just have M5 zero output to the DAC's?
Code: Select all
#include "KMotionDef.h"
main()
{
DAC(4, 0);
DAC(5, 0);
}
- TomKerekes
- Posts: 2676
- Joined: Mon Dec 04, 2017 1:49 am
Re: SPINDLE SERVO SPECS
Hi turbothis,
Since your spindle can be operated as an axis I'd recommend you base your code on the newer \SpindleUsingJogs\SpindleOnCWJogV2.c.
To stop the Spindle (M5) use \SpindleUsingJogs\SpindleOffJogV2.c. This will permit a decelerated and controlled stop. Writing to the DACs wouldn't work as your Dual DAC code would immediately overwrite the DAC with new values as it is writing continuously.
You can then add an if condition to limit the speed value.
Since your spindle can be operated as an axis I'd recommend you base your code on the newer \SpindleUsingJogs\SpindleOnCWJogV2.c.
To stop the Spindle (M5) use \SpindleUsingJogs\SpindleOffJogV2.c. This will permit a decelerated and controlled stop. Writing to the DACs wouldn't work as your Dual DAC code would immediately overwrite the DAC with new values as it is writing continuously.
You can then add an if condition to limit the speed value.
Regards,
Tom Kerekes
Dynomotion, Inc.
Tom Kerekes
Dynomotion, Inc.