I have my (+) and (-) limit switches on each axis wired in series and connected to opto-inputs on KFLOP.
The limit switch option selected is 'Stop movement'
I am using Mach3 and an iMach pendant to move the axes.
When the X axis is driven into the (+) motion limit switch, the axis stops immediately and the KMotion console reports 'Pos Limit Stop Axis:0'. If I jog the pendant rotary encoder dial in the (-) direction, the axis does not move, but the console reports 'Neg Limit Stop Axis:0'.
Reaching the limit switches on the other axes results in the same action.
The Manual says that pressing the 'Feed Hold' button should allow motion to resume however, pressing the 'Feed hold' button does nothing in Mach3, KMotion, or KMotionCNC (which I also used to drive the axis into the same limit switch).
All axes remain enabled, eventhough they don't move.
Any idea what might be going on?
Am I supposed to configure Mach3's input signals to align with KFLOP's limit switch connections?
Initialization code posted below.
Thanks
Jim
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
// Watchenable loop turns servos ON/OFF when axes are ENABLED/DISABLED
void ServiceWatchdogStatus(void);
void WatchdogTripped(void);
void WatchdogOK(void);
#define X 0
#define Y 1
#define Z 2 // Quill
#define C 3 // Knee
#define A 4 // Rotary
#define WATCHDOG_DELAY 5.0 // Script to disable drives if/when Mach3 program is closed
int Mach3Active = 1;
int DrivePower = 0;
int CycledOFF = 0;
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);
for (;;) // loop forever
{
WaitNextTimeSlice();
ServiceWatchdogStatus();
DrivePower = ReadBit(142);
if ((Mach3Active && // Mach3 must be loaded for Mach3Active = 1
DrivePower &&
!CycledOFF) &&
(ch0->Enable) &&
(ch1->Enable) &&
(ch2->Enable) &&
(ch3->Enable) &&
(ch4->Enable)) // Turns drives 'ON' IF ALL axes are enabled
SetBit(155);
else
ClearBit(155); // Turns drives 'OFF' if ANY axis is disabled
if (!DrivePower)
{
CycledOFF = 1;
}
}
return 0;
}
void ServiceWatchdogStatus(void)
{
static int Alive=FALSE;
static int PrevStatusRequestCounter=-1;
static double WatchdogTime=0;
double T=Time_sec();
DrivePower = ReadBit(142);
// check if Host is requesting Status
if (StatusRequestCounter != PrevStatusRequestCounter)
{
// yes, save time
WatchdogTime = T + WATCHDOG_DELAY;
PrevStatusRequestCounter=StatusRequestCounter;
if (!Alive) WatchdogOK();
Alive=TRUE;
}
else
{
if (T > WatchdogTime) // time to trigger?
{
if (Alive) WatchdogTripped();
Alive=FALSE;
}
}
}
void WatchdogOK(void) // Trips when Mach3/KMotionCNC is open
{
ClearBit(47); // KFLOP LED off
Delay_sec(1);
SetBit(47);
Delay_sec(1);
}
void WatchdogTripped(void) // Trips when Mach3/KMotionCNC is closed
{
ClearBit(46); // KFLOP LED off
Delay_sec(1);
SetBit(46);
Delay_sec(1);
Mach3Active = 0; // Keeps forever loop from re-enabling drives
// with 'SetBit(155)'
ClearBit(155); // Disables drives when Mach3 Program Closes
}
/code]