Stepper motor runaway at startup

Moderators: TomKerekes, dynomotion

jpbarad7
Posts: 15
Joined: Wed Dec 07, 2022 6:25 pm

Stepper motor runaway at startup

Post by jpbarad7 » Sun Nov 03, 2024 5:50 pm

I am using a KFLOP with the Kanalog expansion board to control 5 Applied Motion Step Servo Drives and motors and a VFD intalled on a SuperMax knee mill. I use the Watchdog FET switch (SWE output) on JP8 to close a contactor that energizes the motor drivers and VFD after the KFLOP boots. I am using a Dell PC loaded with Windows 11 to run the software.

All is working well, however, maybe one out of ten times, immediately after the motor drives energize, one of the stepper motors (usually Ch3, but sometimes Ch2) will start moving and continue moving until the stepper driver (not KFLOP) detects a position error and stops the motor. This occurs before any software (Kmotion or Mach3) is loaded. If I reset the 'misbehaving' drive, then load Mach3 (or Kmotion), everything works perfectly for the entire duration of use.

Although I am not certain of this, but I think it is happening only (or most often) when the PC has been left on after a previous work session, and the KFLOP/drives are turned back on.

To explain further:

This is how I usually startup the machine:
1) Turn on computer and load Windows 11
2) Turn on KFLOP, which subsequently actives the drives/motors thru the Watchdog FET wired to the contactor.
3) Load Mach3 (+/- KMotion - to have access to the console to display system information)

If I do it this way, everything works fine most of the time (always?)

Sometimes, if the PC has been left on since a previous session, I will do this:
1) Computer already on and Windows 11 already running
2) Turn on KFLOP, drives activate.....

then, SOMETIMES (1 out of 10 times ish) the motor attached to the knee (Ch3) or the motor attached to the Y axis (Ch1) starts up and drives the motor to an internal position error, requiring a reset of the motor driver (not KFLOP). None of the other motors move. Ch0, Ch2 and Ch4 have never
displayed this behavior

My question is this: How/why is the motor driver receiving motion stimuli? Is it coming from residual information stored in KFLOP then dumped after startup? Is it somehow being stored in a 'buffer?' somewhere within the PC, then dumped when KFLOP starts up? Could some position data be stored in the stepper motor driver circuitry and dumped on startup one out of ten times? (I contacted the drive manufacturer and they said this was not possible. They suspected information was being sent from KFLOP to the drive...)

Any thoughts as to what might be happening?

Thanks!

Jim

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

Re: Stepper motor runaway at startup

Post by TomKerekes » Sun Nov 03, 2024 6:48 pm

Hi Jim,

Please post a link to the Motor Drive specifications/manual. Are they Step/Dir Drives? Analog Drives?

How are the Axes Configured? Please post your Initialization C Program.

When KFLOP powers up it should remain unconfigured with all Axes Disabled. Also there should be no buffered motion in KFLOP. So there should be no motion. After a runaway you might run KMotion.exe and try to see why. Any Axis Configured? Any Axis Enabled? Moving?

Could you have flashed something to KFLOP such the configuration or User Program? To be sure KFLOP is in its default state re-Flash New Version.
Regards,

Tom Kerekes
Dynomotion, Inc.

jpbarad7
Posts: 15
Joined: Wed Dec 07, 2022 6:25 pm

Re: Stepper motor runaway at startup

Post by jpbarad7 » Sun Nov 03, 2024 10:41 pm

Here is the link to the motor driver:

https://www.applied-motion.com/s/produc ... Modbus-TCP

It can be configured to operate in either step/direction or analog input for Step-Servo operation. I have it set to digital input in CW/CCW pulse mode. I have attached a photo of the drive configuration screen:
Driver config screen.JPG
Here is my Initialization program:

Code: Select all

#include "KMotionDef.h"

// Defines KFLOP channels 0-4 as axes X-C
// Disables and Zeros all axes
// Defines axis parameters
// Enables all axes and sets positions to Zero
// Sets them as an XYZAC coordinate system for GCode

#define X 0
#define Y 1
#define Z 2		// Quill
#define C 3		// Knee
#define A 4		// Rotary

int main() 
{

	DisableAxis(X);
	Zero(X);

	DisableAxis(Y);
	Zero(Y);

	DisableAxis(Z);
	Zero(Z);

	DisableAxis(C);
	Zero(C);

	DisableAxis(A);
	Zero(A);	

FPGA(STEP_PULSE_LENGTH_ADD)=32 + 0x40 + 0x80;	

	ch0->InputMode=ENCODER_MODE;
	ch0->OutputMode=CL_STEP_DIR_MODE;
	ch0->Vel=200000;
	ch0->Accel=1e+06;
	ch0->Jerk=1e+07;
	ch0->P=0;
	ch0->I=0.002;
	ch0->D=0;
	ch0->FFAccel=0;
	ch0->FFVel=0;
	ch0->MaxI=1e+06;
	ch0->MaxErr=1e+09;
	ch0->MaxOutput=1e+06;
	ch0->DeadBandGain=1;
	ch0->DeadBandRange=0;
	ch0->InputChan0=0;
	ch0->InputChan1=0;
	ch0->OutputChan0=56;
	ch0->OutputChan1=0;
	ch0->MasterAxis=-1;
	ch0->LimitSwitchOptions=0x12f;
	ch0->LimitSwitchNegBit=136;
	ch0->LimitSwitchPosBit=136;
	ch0->SoftLimitPos=1e+09;
	ch0->SoftLimitNeg=-1e+09;
	ch0->InputGain0=-46;
	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=1;
	ch0->Lead=0;
	ch0->MaxFollowingError=5000;
	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=0.00075647;
	ch0->iir[2].B1=0.00151294;
	ch0->iir[2].B2=0.00075647;
	ch0->iir[2].A1=1.88998;
	ch0->iir[2].A2=-0.89301;
	


	ch1->InputMode=ENCODER_MODE;
	ch1->OutputMode=CL_STEP_DIR_MODE;
	ch1->Vel=200000;
	ch1->Accel=1e+06;
	ch1->Jerk=1e+07;
	ch1->P=0;
	ch1->I=0.001;
	ch1->D=0;
	ch1->FFAccel=0;
	ch1->FFVel=0;
	ch1->MaxI=1e+06;
	ch1->MaxErr=1e+09;
	ch1->MaxOutput=1e+06;
	ch1->DeadBandGain=1;
	ch1->DeadBandRange=0;
	ch1->InputChan0=1;
	ch1->InputChan1=0;
	ch1->OutputChan0=57;
	ch1->OutputChan1=0;
	ch1->MasterAxis=-1;
	ch1->LimitSwitchOptions=0x12f;
	ch1->LimitSwitchNegBit=137;
	ch1->LimitSwitchPosBit=137;
	ch1->SoftLimitPos=1e+09;
	ch1->SoftLimitNeg=-1e+09;
	ch1->InputGain0=46;
	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=1;
	ch1->Lead=0;
	ch1->MaxFollowingError=2500;
	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=0.779671;
	ch1->iir[2].B1=-1.55685;
	ch1->iir[2].B2=0.779671;
	ch1->iir[2].A1=1.55685;
	ch1->iir[2].A2=-0.559341;



	ch2->InputMode=ENCODER_MODE;
	ch2->OutputMode=CL_STEP_DIR_MODE;
	ch2->Vel=200000;
	ch2->Accel=1e+06;
	ch2->Jerk=1e+06;
	ch2->P=0;
	ch2->I=0.006;
	ch2->D=0;
	ch2->FFAccel=0;
	ch2->FFVel=0;
	ch2->MaxI=1e+06;
	ch2->MaxErr=1e+09;
	ch2->MaxOutput=1e+06;
	ch2->DeadBandGain=1;
	ch2->DeadBandRange=0;
	ch2->InputChan0=2;
	ch2->InputChan1=0;
	ch2->OutputChan0=58;
	ch2->OutputChan1=0;
	ch2->MasterAxis=-1;
	ch2->LimitSwitchOptions=0x12f;
	ch2->LimitSwitchNegBit=138;
	ch2->LimitSwitchPosBit=138;
	ch2->SoftLimitPos=1e+09;
	ch2->SoftLimitNeg=-1e+09;
	ch2->InputGain0=-35.45;
	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=1;
	ch2->Lead=0;
	ch2->MaxFollowingError=2000;
	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=0.000768809;
	ch2->iir[2].B1=0.00153762;
	ch2->iir[2].B2=0.000768809;
	ch2->iir[2].A1=1.92081;
	ch2->iir[2].A2=-0.923885;
	


	ch3->InputMode=ENCODER_MODE;
	ch3->OutputMode=CL_STEP_DIR_MODE;
	ch3->Vel=100000;
	ch3->Accel=75000;
	ch3->Jerk=1e+06;
	ch3->P=0;
	ch3->I=0.001;
	ch3->D=0;
	ch3->FFAccel=0;
	ch3->FFVel=0;
	ch3->MaxI=1e+06;
	ch3->MaxErr=1e+09;
	ch3->MaxOutput=1e+06;
	ch3->DeadBandGain=1;
	ch3->DeadBandRange=0;
	ch3->InputChan0=3;
	ch3->InputChan1=0;
	ch3->OutputChan0=59;
	ch3->OutputChan1=0;
	ch3->MasterAxis=-1;
	ch3->LimitSwitchOptions=0x12f;
	ch3->LimitSwitchNegBit=139;
	ch3->LimitSwitchPosBit=139;
	ch3->SoftLimitPos=1e+09;
	ch3->SoftLimitNeg=-1e+09;
	ch3->InputGain0=-85.3;
	ch3->InputGain1=1;
	ch3->InputOffset0=0;
	ch3->InputOffset1=0;
	ch3->OutputGain=-1;
	ch3->OutputOffset=0;
	ch3->SlaveGain=1;
	ch3->BacklashMode=BACKLASH_OFF;
	ch3->BacklashAmount=0;
	ch3->BacklashRate=0;
	ch3->invDistPerCycle=1;
	ch3->Lead=0;
	ch3->MaxFollowingError=10000;
	ch3->StepperAmplitude=20;

	ch3->iir[0].B0=1;
	ch3->iir[0].B1=0;
	ch3->iir[0].B2=0;
	ch3->iir[0].A1=0;
	ch3->iir[0].A2=0;

	ch3->iir[1].B0=1;
	ch3->iir[1].B1=0;
	ch3->iir[1].B2=0;
	ch3->iir[1].A1=0;
	ch3->iir[1].A2=0;

	ch3->iir[2].B0=0.000768809;
	ch3->iir[2].B1=0.00153762;
	ch3->iir[2].B2=0.000768809;
	ch3->iir[2].A1=1.92081;
	ch3->iir[2].A2=-0.923885;
	

	
	ch4->InputMode=NO_INPUT_MODE;
	ch4->OutputMode=STEP_DIR_MODE;
	ch4->Vel=40000;
	ch4->Accel=400000;
	ch4->Jerk=4e+06;
	ch4->P=0.2;
	ch4->I=0;
	ch4->D=0;
	ch4->FFAccel=0;
	ch4->FFVel=0;
	ch4->MaxI=200;
	ch4->MaxErr=200;
	ch4->MaxOutput=200;
	ch4->DeadBandGain=1;
	ch4->DeadBandRange=0;
	ch4->InputChan0=4;
	ch4->InputChan1=1;
	ch4->OutputChan0=63;
	ch4->OutputChan1=1;
	ch4->MasterAxis=-1;
	ch4->LimitSwitchOptions=0x120;
	ch4->LimitSwitchNegBit=0;
	ch4->LimitSwitchPosBit=0;
	ch4->SoftLimitPos=1e+09;
	ch4->SoftLimitNeg=-1e+09;
	ch4->InputGain0=0;
	ch4->InputGain1=1;
	ch4->InputOffset0=0;
	ch4->InputOffset1=0;
	ch4->OutputGain=1;
	ch4->OutputOffset=0;
	ch4->SlaveGain=1;
	ch4->BacklashMode=BACKLASH_OFF;
	ch4->BacklashAmount=0;
	ch4->BacklashRate=0;
	ch4->invDistPerCycle=1;
	ch4->Lead=0;
	ch4->MaxFollowingError=1000000000;
	ch4->StepperAmplitude=250;

	ch4->iir[0].B0=1;
	ch4->iir[0].B1=0;
	ch4->iir[0].B2=0;
	ch4->iir[0].A1=0;
	ch4->iir[0].A2=0;

	ch4->iir[1].B0=1;
	ch4->iir[1].B1=0;
	ch4->iir[1].B2=0;
	ch4->iir[1].A1=0;
	ch4->iir[1].A2=0;

	ch4->iir[2].B0=1;
	ch4->iir[2].B1=0;
	ch4->iir[2].B2=0;
	ch4->iir[2].A1=0;
	ch4->iir[2].A2=0;
	

	EnableAxisDest(X,0);
	EnableAxisDest(Y,0);
	EnableAxisDest(Z,0);
	EnableAxisDest(C,0);
	EnableAxisDest(A,0);
	
	DefineCoordSystem6(0,1,2,4,-1,3);

    return 0;
}
/code]

I have loaded KMotion immediately after this happens but see nothing except the position (encoder) pulse counts, without destination pulses counts, on the Axis screen.  All axes are disabled. There is nothing displayed in the console window, except the normal startup message. I suspect this is because it only displays what happens AFTER the software is loaded.

Interestingly, when I turned it on just now to double check the names of the column titles on the axis screen, the Z axis motor (Ch2) turned on and ran until hitting the limit switch.  This is the first time (that I can remember) that this axis was involved.  Again, it's most often Ch1 and Ch3.

I am not sure if I flashed something to KFLOP inadvertently.....anything is possible.  I will reflash the New Version now.

Thank you

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

Re: Stepper motor runaway at startup

Post by TomKerekes » Mon Nov 04, 2024 4:58 pm

Hi Jim,

I'm not familiar with those drives, but I would think since they are closed loop if they somehow though they were supposed to be at some destination but the encoder position was somewhere else they would try to move to reduce the difference when enabled.

How are the CW CCW signals wired? Until the axes are configured these outputs would be floating so potentially could pick up noise to cause the Drives to step. I think this is unlikely but ideally the Drive enables would be interfaced to KFLOP. That way KFLOP could enable the drives only after everything is configured.
the Z axis motor (Ch2) turned on and ran until hitting the limit switch.
Do you have limits interfaced directly to the drives?
but see nothing except the position (encoder) pulse counts, without destination pulses counts, on the Axis screen. All axes are disabled.
You might have checked if the Axis were configured as default 'No Output' or something else.
I am not sure if I flashed something to KFLOP inadvertently.....anything is possible. I will reflash the New Version now.
Yes please re-Flash
Regards,

Tom Kerekes
Dynomotion, Inc.

jpbarad7
Posts: 15
Joined: Wed Dec 07, 2022 6:25 pm

Re: Stepper motor runaway at startup

Post by jpbarad7 » Tue Nov 05, 2024 4:59 pm

The CW CWW inputs to the drives are wired directly to the KFLOP outputs for each axes. Your thought that they may be 'floating' and picking up interference is a great one. Having the drives enabled by KFLOP is a also a very good idea and I think the hardware/wiring part would be easy, as I have already routed each drives' 'servo on' wiring to a central location.

How would I go about this within the KFLOP software? Is there a way to insert a command into KFLOP's initialization program to send a signal to one of the SW pins on the Kanalog board? I already have SW3 connected to an unused relay that could easly be used to enable the drives....

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

Re: Stepper motor runaway at startup

Post by TomKerekes » Tue Nov 05, 2024 6:09 pm

Hi Jim,

SetBit() and ClearBit can be used to control Outputs.

Code: Select all

SetBit(152);  // activate Kanalog FET Switch #0
Often a forever loop is used to monitor the axis enable and if it is disabled then the Drive is also disabled. See the 'watchenable.c' example.

HTH
Regards,

Tom Kerekes
Dynomotion, Inc.

jpbarad7
Posts: 15
Joined: Wed Dec 07, 2022 6:25 pm

Re: Stepper motor runaway at startup

Post by jpbarad7 » Wed Nov 06, 2024 1:16 am

Thank you Tom.

I made some simple wiring changes and now all of the drives can be enabled using SetBit(155);

I looked at the watchenable.c script and can see how it would be very useful.

How is the program called?

Is it added to the initialization program?

Jim

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

Re: Stepper motor runaway at startup

Post by TomKerekes » Wed Nov 06, 2024 4:40 pm

Hi Jim,

Yes. It can be added to the end of the Initialization C Program so that after KFLOP is initialized the loop is executed continuously. See here.
Regards,

Tom Kerekes
Dynomotion, Inc.

jpbarad7
Posts: 15
Joined: Wed Dec 07, 2022 6:25 pm

Re: Stepper motor runaway at startup

Post by jpbarad7 » Sat Nov 09, 2024 3:29 pm

Hello Tom,

Everything now is working as expected. The startup runaway problem was solved by having KFLOP enable the drives - Thanks again!

Is there a way to have the KFLOP also disable the drives when KMotion or Mach3 is closed, rather than when the KFLOP board is rebooted or powered down?

The way I have it set up now is that the drives are enabled/disabled within the initialization program, using the watchenable program, whenever any axis is enabled/disabled. I've noticed that if I cut power to the drive/VFD circuit, and KFLOP is still powered, the SetBit activated relay that enables/disables the drives remains in the 'ON' position - it only resets to 'OFF' when KFLOP loses power or is reset.

It is rare that, when the CNC machine is being used, that KFLOP might remain 'ON' while the drive power circuit is 'OFF', but it could happen. If it did, the drives would power-up 'enabled' rather than 'disabled' and the runaway problem might rear its ugly head again.

Didn't know if there was also another software failsafe fix to this avoid this potential hardware occurrence.

Thanks,

Jim

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

Re: Stepper motor runaway at startup

Post by TomKerekes » Sat Nov 09, 2024 5:48 pm

Hi Jim,
Is there a way to have the KFLOP also disable the drives when KMotion or Mach3 is closed, rather than when the KFLOP board is rebooted or powered down?
Whenever Mach3, KMotionCNC, or, KMotion is running status is continuously being polled from KFLOP. KFLOP maintains a counter of the number of status requests that have been made. StatusRequestCounter. When al the PC apps are terminated, or the PC is turned off, the status requests will stop and this can be detected and used to do whatever you wish. See the WatchdogStatusRequests.c example.
The way I have it set up now is that the drives are enabled/disabled within the initialization program, using the watchenable program, whenever any axis is enabled/disabled. I've noticed that if I cut power to the drive/VFD circuit, and KFLOP is still powered, the SetBit activated relay that enables/disables the drives remains in the 'ON' position - it only resets to 'OFF' when KFLOP loses power or is reset.
Well I don't think KFLOP has any way of knowing that Drive Power has been turned off. Is there a Drive Ready signal or something that could be interfaced to KFLOP so it can be aware of this? If so KFLOP could detect loss of Ready and disable all the Axes and Drives.
It is rare that, when the CNC machine is being used, that KFLOP might remain 'ON' while the drive power circuit is 'OFF', but it could happen. If it did, the drives would power-up 'enabled' rather than 'disabled' and the runaway problem might rear its ugly head again.
I don't think watching for the Apps being closed solves this problem. The Apps might remain open but power to the Drives switched off and back on. In this case KFLOP remains configured so the Step/Direction Outputs would remain driven (not floating), so maybe that solves the runaway problem. It seems we never determined why the drives were running away.

HTH
Regards,

Tom Kerekes
Dynomotion, Inc.

Post Reply