spindle servo runs away over time/position

Moderators: TomKerekes, dynomotion

turbothis
Posts: 309
Joined: Fri Mar 15, 2019 4:07 pm
Location: southern oregon

spindle servo runs away over time/position

Post by turbothis » Thu Aug 15, 2019 12:54 am

i have been slowly cutting some parts on my lathe while learning and tuning in the settings on kmotioncnc. about every 3-4 cycles at random times in the cycle the spindle will start to hunt around or stop. kinda scary when it just rockets up in rpm.

i think i have a clue of what is happening here
in the axis tab in kmotion, it shows different numbers for destination and position. :?
if the spindle stopped it was because of the following error. i saw this in the console

the following error either stops the spindle or it will hunt CW and CCW all scary like!
it seems to be spot on the whole time and then some where it geeks out and loses a bunch of position?
i have run the spindle for like 15 minutes on its own to get this problem repeatable ( 1600 rpm )
i dont think this is a mechanical thing. nothing is hot or loose.
maybe i have the "ch2->invDistPerCycle=0.0003662109375;" is bad in my C code? (for the servo/spindle)
or maybe the "#define FACTOR (11832.8889/60.0)" is off in the H file

when the trouble starts while cutting, thats when i was trying to use the FEED HOLD button. however, it does not function well on the G95 mode. ( one of my other threads on here )
so when the scary high rpm stuff would start i would hit the STOP button.
1 if the spindle stopped by following error. i can type in a slow speed of S500 and the spindle would actually spins opposite of the command. i assume this is again because of the following error and the spindle reversing to get back in position?

2 when the scary high speed hunt would start i hit the STOP button. afterwards i would hit my master enable C code. once the enable C code was run then the spindle would act normal again.
i thought about a M100 in the G code at the end to reset the spindle position ( in a C code ) or something like that but i think there is a number issue to be resolved


Image

Moray
Posts: 282
Joined: Thu Apr 26, 2018 10:16 pm

Re: spindle servo runs away over time/position

Post by Moray » Thu Aug 15, 2019 9:56 am

Could describe your spindle setup (I.e. is it just a +/-10V control, or are there any on/direction relays involved?)?

Also, probably best if you can post the relevant C programs in this thread, so they're easier to reference.


But, it does sound like something in your C code needs a change.

turbothis
Posts: 309
Joined: Fri Mar 15, 2019 4:07 pm
Location: southern oregon

Re: spindle servo runs away over time/position

Post by turbothis » Thu Aug 15, 2019 5:50 pm

no relays or extra hardware

i start with my main enable code

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=200;   // set coil current amplitude DAC units
                double p0;
 
        // Z axis

	ch0->InputMode=ENCODER_MODE;
	ch0->OutputMode=NO_OUTPUT_MODE;
	ch0->Vel=600000;
	ch0->Accel=1e+08;
	ch0->Jerk=1e+09;
	ch0->P=3;
	ch0->I=0.0001;
	ch0->D=5;
	ch0->FFAccel=0;
	ch0->FFVel=0;
	ch0->MaxI=500;
	ch0->MaxErr=1e+06;
	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=0x100;
	ch0->LimitSwitchNegBit=0;
	ch0->LimitSwitchPosBit=0;
	ch0->SoftLimitPos=1e+30;
	ch0->SoftLimitNeg=-1e+30;
	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=10000;
	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;


        // X axis     

	ch1->InputMode=ENCODER_MODE;
	ch1->OutputMode=NO_OUTPUT_MODE;
	ch1->Vel=500000;
	ch1->Accel=1e+07;
	ch1->Jerk=2e+08;
	ch1->P=1;
	ch1->I=0.0001;
	ch1->D=2;
	ch1->FFAccel=0;
	ch1->FFVel=0;
	ch1->MaxI=500;
	ch1->MaxErr=1e+06;
	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=0x100;
	ch1->LimitSwitchNegBit=0;
	ch1->LimitSwitchPosBit=0;
	ch1->SoftLimitPos=1e+30;
	ch1->SoftLimitNeg=-1e+30;
	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=10000;
	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;

        // A  axis / spindle

	ch2->InputMode=ENCODER_MODE;
	ch2->OutputMode=NO_OUTPUT_MODE;
	ch2->Vel   =300000;
	ch2->Accel =80000;
	ch2->Jerk  =150000;
	ch2->P=10;
	ch2->I=0;
	ch2->D=10;
	ch2->FFAccel=0.005;
	ch2->FFVel=0.005;
	ch2->MaxI=0;
	ch2->MaxErr=1e+06;
	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=0x100;
	ch2->LimitSwitchNegBit=0;
	ch2->LimitSwitchPosBit=0;
	ch2->SoftLimitPos=1e+30;
	ch2->SoftLimitNeg=-1e+30;
	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 all 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 = 600;  // 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 = 225;  // 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
                

                EnableAxis(0);  // Enable servo    Z axis
                EnableAxis(1);  // Enable servo    X axis
                EnableAxis(2);  // Enable servo    A axis

                DefineCoordSystem(1,-1,0,-1); // 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()
and then after that i use my turning code

Code: Select all

#include "KMotionDef.h"
#include "MySpindleDefs.h"

void main()
{
	// CH2 - spindle

	ch2->InputMode=ENCODER_MODE;
	ch2->OutputMode=NO_OUTPUT_MODE;
	ch2->Vel  =300000;
	ch2->Accel=80000;
	ch2->Jerk =150000;
	ch2->P=10;
	ch2->I=0;
	ch2->D=10;
	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;
	
     EnableAxis(0);  // Enable servo    Z axis
     EnableAxis(1);  // Enable servo    X axis 
	DefineCoordSystem(1,-1,0,-1);  // define the coordinate system
}
CCW jog

Code: Select all

#include "KMotionDef.h"
#include "MySpindleDefs.h"

int   *css_mode = &persist.UserData[PC_COMM_CSS_MODE];			// Mode 1=Normal RPM mode. 2=CSS

// desired speed is passed from KMotionCNC in variable KMVAR
// save in user variable STATEVAR whether it was off, CW, or CCW (0,1,-1)
// save in user variable SPEEDVAR the last desired speed

main()
{
	if (!chan[SPINDLEAXIS].Enable) EnableAxis(SPINDLEAXIS);
	float speed = *(float *)&persist.UserData[SPEEDVAR];  // value stored is actually a float 
	float LastState = persist.UserData[STATEVAR];  // get last state 
	
	if (LastState==1)  
	{
		// if spindle was CW now we want CCW 
		// spin down
		
		ClearBit(SPINDLECW_BIT);
		ClearBit(SPINDLECCW_BIT);
		Jog(SPINDLEAXIS,0);
		while (!CheckDone(SPINDLEAXIS)) ;
	}
	
	// turn spindle on CCW and ramp to new speed
	SetBit(SPINDLECCW_BIT);
	
	LastState = -1;
	
	if (*css_mode != 2)
	{
		// spindle is already on, so ramp to new speed
		if (USE_POS_NEG_VOLTAGE)
			Jog(SPINDLEAXIS,speed * FACTOR * LastState);
		else
			Jog(SPINDLEAXIS,speed * FACTOR);
		
		printf("Jogging Spindle %f counts/sec\n",speed * FACTOR);
	}	
	persist.UserData[STATEVAR] = -1;  // remember we are CCW
}

spindle jog for speed

Code: Select all

#include "KMotionDef.h"
#include "MySpindleDefs.h"


int   *css_mode = &persist.UserData[PC_COMM_CSS_MODE];			// Mode 1=Normal RPM mode. 2=CSS

// desired speed is passed from KMotionCNC in variable KMVAR
// save in user variable STATEVAR whether it was off, CW, or CCW (0,1,-1)
// save in user variable SPEEDVAR the last desired speed

main()
{
	float speed = *(float *)&persist.UserData[KMVAR];  // value stored is actually a float 
	float LastState = persist.UserData[STATEVAR];  // get last state 
	
	persist.UserData[SPEEDVAR] = persist.UserData[KMVAR];  // Always save the last desired speed 
	
	if (LastState==0 || *css_mode == 2)  
	{
		// if spindle is off (or CSS mode) and User Changes the speed 
		// just save the desired speed
		
		return 0;
	}
	
	// spindle is already on, so ramp to new speed
	if (USE_POS_NEG_VOLTAGE)
		Jog(SPINDLEAXIS,speed * FACTOR * LastState);
	else
		Jog(SPINDLEAXIS,speed * FACTOR);
		
	printf("Jogging Spindle %f counts/sec\n",speed * FACTOR);
}
and spindle def's

Code: Select all

#define SPINDLEAXIS 2			// Axis Channel to Jog to rotate Spindle
#define FACTOR (11832.8889/60.0)  	// to convert RPM to counts/sec (counts/rev / 60.0sec)
#define SPINDLECW_BIT 154
#define SPINDLECCW_BIT 155
#define SPEEDVAR 99				// global persistant variable to store latest speed
#define STATEVAR 98				// global persistant variable to store latest state (-1=CCW,0=off,1=CW)
#define KMVAR  PC_COMM_CSS_S  	// variable KMotionCNC will pass speed parameter (113)
#define USE_POS_NEG_VOLTAGE 1 	// 0 = output Magnitude, 1 = output positive and negative speed 

Moray
Posts: 282
Joined: Thu Apr 26, 2018 10:16 pm

Re: spindle servo runs away over time/position

Post by Moray » Thu Aug 15, 2019 11:04 pm

Nothing major stands out. Max output could possibly be increased slightly to the max value of 2047.

What speed is your spindle physically capable of?

I'm wondering if the axis is disabling due to following error, as I'm assuming you've got nothing to handle is any axis disables, which then causes the output to then stay as last commanded, giving the impression all is still OK. Then the problem only becomes apparent once the axis is re-enabled, at which point the output value starts updating again and it tries to handle the huge position error.

Tom, what happens to the channel output when an axis disables?

turbothis
Posts: 309
Joined: Fri Mar 15, 2019 4:07 pm
Location: southern oregon

Re: spindle servo runs away over time/position

Post by turbothis » Fri Aug 16, 2019 3:09 am

The servo is rated for 4000 which would be super scary. My G code runs at 2200 rpm for about 5 minute cycle

User avatar
TomKerekes
Posts: 2527
Joined: Mon Dec 04, 2017 1:49 am

Re: spindle servo runs away over time/position

Post by TomKerekes » Fri Aug 16, 2019 5:13 pm

Hi turbothis,

It sounds to me like the commutation for the Spindle motor is drifting off over time which results in bad commutation.

Your motors are brushless with Drives driven by 2 DAC signals where KFLOP does the motor commutation based on encoder position. The commutation is basically what tells the motor Drive which coils to use to generate maximum torque. If the commutation is wrong the motor will generate torque poorly and its even possible to generate torque in the wrong direction which can cause a runaway as errors are driven larger rather than smaller.

The first thing to do would be to reduce your Max Following Error so that if any such problem occurs the motor will immediately fault with a following error, disable, and stop. This line:

ch2->MaxFollowingError=1000000;

allows a rather large following error. 1000000/8192 = 122 motor revolutions.
what happens to the channel output when an axis disables?
This code in the forever loop sets the DACs to zero whenever the axis is disabled:

Code: Select all

    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);

The next step would be to figure out if/how the commutation is being changed. This is much like the single pass Threading problem where KFLOP must be able to precisely determine the shaft angle after many revolutions without drift. Except motor shaft angle is what is needed instead of the spindle shaft angle. Also the angle must be precise forever not just long enough to cut a Thread.

I believe the motor has an encoder with 8192 counts and 3 cycles/rev (6 pole motor).

The inverse of 8192/3 is
ch2->invDistPerCycle=0.0003662109375;

This is an exact number and KFLOP performs the commutation with double precision (17 significant digits) so it should take thousands of years of spinning thousands of RPMs to result in a single degree of error. So I would expect it to work correctly with negligible drift.

I would perform a similar test as we did with the Spindle to check for drift error.

#1 - mark the Spindle Motor's shaft angle (motor not Spindle)
#2 - zero the Encoder Position Count
#3 - run the motor for a long time until you think it might be ready to fail
#4 - position the motor shaft to the same angle
#5 - record the encoder Position
#6 - divide the position by 8192 and check if the fractional part is very close to zero
Regards,

Tom Kerekes
Dynomotion, Inc.

turbothis
Posts: 309
Joined: Fri Mar 15, 2019 4:07 pm
Location: southern oregon

Re: spindle servo runs away over time/position

Post by turbothis » Fri Aug 16, 2019 5:32 pm

GREAT
I WILL GET BACK TO YOU ASAP!!!!!!!!!!!!!

turbothis
Posts: 309
Joined: Fri Mar 15, 2019 4:07 pm
Location: southern oregon

Re: spindle servo runs away over time/position

Post by turbothis » Mon Aug 19, 2019 7:06 pm

ok i swear something is cursed
i made some cuts on the lathe with the original working but eventually runs away set up. (the exact one from 1st post)

i changed the follow error down on the CH2 spindle and commented out the DAC to set zero thinking that might be what to do so the encoder position never changes.

ch2->MaxFollowingError=100000;

Code: Select all

     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); 
this kept the C program from enabling the channels so i just un commented the 3 lines from above
now with the same working code that cut this morning kmotioncnc will still not enable the channels?
what even better is it is jogging the "Y" axis to commute?!?!?!? in kmotioncnc
i absolutely feel there is a phantom code running in the back round or something.
in kmotion i hit STOP but there is still AXIS DAC commands. would this not stop all actions?
sorry for the side track on the spindle commutation test but this is the strange things i have going all the time

turbothis
Posts: 309
Joined: Fri Mar 15, 2019 4:07 pm
Location: southern oregon

Re: spindle servo runs away over time/position

Post by turbothis » Mon Aug 19, 2019 7:28 pm

holy cow! after about 15 minutes of just looking at files and double checking stuff it magically works again! :cry:
this is with zero/0/none changes
is there some chance that the C program is slow to actually load and start working?

turbothis
Posts: 309
Joined: Fri Mar 15, 2019 4:07 pm
Location: southern oregon

Re: spindle servo runs away over time/position

Post by turbothis » Tue Aug 20, 2019 12:32 am

#1 - mark the Spindle Motor's shaft angle (motor not Spindle)
#2 - zero the Encoder Position Count
#3 - run the motor for a long time until you think it might be ready to fail
#4 - position the motor shaft to the same angle
#5 - record the encoder Position
#6 - divide the position by 8192 and check if the fractional part is very close to zero

i have done this a couple times and it does look accurate for the close to zero on the decimal
the spindle of course wont do its little failure dance now that i am watching it more closely.
maybe the encoder just skips a beat at times?

https://www.cui.com/product/resource/amt10.pdf
Image

Post Reply