Page 1 of 1

Axis set up

Posted: Tue Mar 05, 2024 5:22 am
by katiefangffs
Hi,
I'm currently working on a 5-axis and one spindle CNC project and have done testing each axis individually and now moving on to simultaneous axis control.

I am facing two technical issues:
1. Soft Limits Issue: Hardware limits correctly stop movement at boundaries and allow reverse direction movement. However, software-defined limits lock all movements once reached, even though the axis stays enabled, rendering jog and move commands ineffective.
2. Origin: I have sensors at each origin and I am not quite sure about the syntax to be used to set it up.

For you reference, this is the complete code I'm using to set-up all five axis:

Code: Select all

#include "KMotionDef.h"

//code for all axis motor set-up

int main() 
{
	InitAux();
	AddKonnect_Aux0(0, &VirtualBits, VirtualBitsEx);
	double T0, LastX=0, LastY=0, LastZ=0, LastA=0, Tau;

	FPGA(STEP_PULSE_LENGTH_ADD) = 63 + 0x80;  // set polarity and pulse length to 4us
	
	//ch0=x
	ch0->InputMode=NO_INPUT_MODE;
	ch0->OutputMode=STEP_DIR_MODE;
	ch0->Vel=40000;
	ch0->Accel=200000;
	ch0->Jerk=4e+006;
	ch0->P=0;
	ch0->I=0.01;
	ch0->D=0;
	ch0->FFAccel=0; //feed foward acceleration
	ch0->FFVel=0; //feed foward velocity
	ch0->MaxI=200;
	ch0->MaxErr=1e+006;
	ch0->MaxOutput=200;
	ch0->DeadBandGain=1;
	ch0->DeadBandRange=0;
	ch0->InputChan0=0;
	ch0->InputChan1=0;
	ch0->OutputChan0=8;
	ch0->OutputChan1=0;
	ch0->MasterAxis=-1;
	ch0->LimitSwitchOptions=0x110;
	ch0->LimitSwitchNegBit = 1025;
	ch0->LimitSwitchPosBit = 1024;
	ch0->SoftLimitPos = 56000; //TBT
	ch0->SoftLimitNeg = -56000; //TBT
	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=1;
	ch0->Lead=0;
	ch0->MaxFollowingError=1000000000;
	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.000769;
	ch0->iir[2].B1=0.001538;
	ch0->iir[2].B2=0.000769;
	ch0->iir[2].A1=1.92076;
	ch0->iir[2].A2=-0.923833;
    EnableAxisDest(0,0);

//similarly for the other 4 axis and spindle

//ENA pins, ClearBit()=low, SetBit()=high
	void SetBitDirection(56, 1);  // Set pin 56 as an output, xyzy'z' ENA
	ClearBit(56);            // Set pin 56 low ="turn off" the enable pin=motor start
	void SetBitDirection(55, 1);  // Set pin 55 as an output, polishing tool ENA
	ClearBit(55);            // Set pin 55 low ="turn off" the enable pin=motor start

	//Brake pins
	void SetBitDirection(52, 1); //Set pin 52 as an output, z brake
	SetBit(52); //"turn on" 52=high
	void SetBitDiretion(53, 1); //Set pin 53 as an output, polishing tool brake
	SetBit(53); //"turn on" 53=high


	//definecoordinate
 DefineCoordSystem6(0,1,4,-1,3,2); // define axis chan numbers to use as x,y,z,a,b,c (set -1 to disable)
	    return 0;
}


Thank you :)

Re: Axis set up

Posted: Tue Mar 05, 2024 4:48 pm
by TomKerekes
Hi Katie,

I'm not sure what you are trying to do with the "origin" stuff. Wait for a bit to zero. What would cause the bit to change?

For homing you might read this.

What do you mean limits "lock". Please post your entire Initialization file and explain what you are doing. What Version are you using?

Why do you refer to the b and c axes as y' and x'

Re: Axis set up

Posted: Wed Mar 06, 2024 1:57 am
by katiefangffs
Hi Tom,
so for the origin stuff, I have sensors at each axis where I want it to be set as the origin. This is my current code section for this, which jogs at the maximum speed for each motor and then zeros the axis when the IO pin is reached:

Code: Select all

  
    // Home each axis to its origin
    HomeAxis(0, 6000, 1026); // Home X axis
    HomeAxis(1, 200, 1029); // Home Y axis
    HomeAxis(4, 500, 1034); // Home Z axis
    HomeAxis(3, 450, 1037); // Home Y' axis
    HomeAxis(2, 370, 1040); // Home Z' axis

    return 0;
}

//function for defining origin
void HomeAxis(int axis, float jogSpeed, int originBit) {
	//disable limit switch if needed
    Jog(axis, jogSpeed); //jog until it sees the limit, jog speed TBT
    while (ReadBit(originBit) == 1); // Wait until the origin is found
    Jog(axis, 0); // Stop the axis
    while (!CheckDone(axis)); // Ensure the axis has fully stopped
    Zero(axis); // Zero the axis at the origin position
}
As for the limit switch, I am currently using the "Disallow drive into limit" option. According to the kflop manual, it should " allow a move away from the limit". However, once the soft limit is reached, the motor cannot be moved by any code and requires a reboot on the board to restart it. This is the compelte initializing code:

Code: Select all

#include "KMotionDef.h"

//code for all axis motor set-up

int main() 
{
	InitAux();
	AddKonnect_Aux0(0, &VirtualBits, VirtualBitsEx);
	extern int VirtualBitsEx[N_VIRTUAL_BITS_EX/32];	// 1024 Expanded Virtual Bits (1024-2047)

	FPGA(STEP_PULSE_LENGTH_ADD) = 63 + 0x80;  // set polarity and pulse length to 4us
	
	//ch0=x
	ch0->InputMode=NO_INPUT_MODE;
	ch0->OutputMode=STEP_DIR_MODE;
	ch0->Vel=40000;
	ch0->Accel=200000;
	ch0->Jerk=4e+006;
	ch0->P=0;
	ch0->I=0.01;
	ch0->D=0;
	ch0->FFAccel=0; //feed foward acceleration
	ch0->FFVel=0; //feed foward velocity
	ch0->MaxI=200;
	ch0->MaxErr=1e+006;
	ch0->MaxOutput=200;
	ch0->DeadBandGain=1;
	ch0->DeadBandRange=0;
	ch0->InputChan0=0;
	ch0->InputChan1=0;
	ch0->OutputChan0=8;
	ch0->OutputChan1=0;
	ch0->MasterAxis=-1;
	ch0->LimitSwitchOptions=0x110;
	ch0->LimitSwitchNegBit = 1025;
	ch0->LimitSwitchPosBit = 1024;
	ch0->SoftLimitPos = 56000; //TBT
	ch0->SoftLimitNeg = -56000; //TBT
	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=1;
	ch0->Lead=0;
	ch0->MaxFollowingError=1000000000;
	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.000769;
	ch0->iir[2].B1=0.001538;
	ch0->iir[2].B2=0.000769;
	ch0->iir[2].A1=1.92076;
	ch0->iir[2].A2=-0.923833;
    EnableAxisDest(0,0);

	//ch1=y axis
	ch1->InputMode=NO_INPUT_MODE;
	ch1->OutputMode=STEP_DIR_MODE;
	ch1->Vel=40000;
	ch1->Accel=200000;
	ch1->Jerk=4e+006;
	ch1->P=0;
	ch1->I=0.01;
	ch1->D=0;
	ch1->FFAccel=0;
	ch1->FFVel=0;
	ch1->MaxI=200;
	ch1->MaxErr=1e+006;
	ch1->MaxOutput=200;
	ch1->DeadBandGain=1;
	ch1->DeadBandRange=0;
	ch1->InputChan0=0;
	ch1->InputChan1=0;
	ch1->OutputChan0=9;
	ch1->OutputChan1=0;
	ch1->MasterAxis=-1;
	ch1->LimitSwitchOptions=0x110;
	ch1->LimitSwitchNegBit = 1028;
	ch1->LimitSwitchPosBit = 1027;
	ch1->SoftLimitPos=13000; //TBT
	ch1->SoftLimitNeg=-13000; //TBT
	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=1;
	ch1->Lead=0;
	ch1->MaxFollowingError=1000000000;
	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.000769;
	ch1->iir[2].B1=0.001538;
	ch1->iir[2].B2=0.000769;
	ch1->iir[2].A1=1.92076;
	ch1->iir[2].A2=-0.923833;
    EnableAxisDest(1,0);

	//ch2=Z' axis
	ch2->InputMode=NO_INPUT_MODE;
	ch2->OutputMode=STEP_DIR_MODE;
	ch2->Vel=40000;
	ch2->Accel=200000;
	ch2->Jerk=4e+006;
	ch2->P=0;
	ch2->I=0.01;
	ch2->D=0;
	ch2->FFAccel=40;
	ch2->FFVel=100;
	ch2->MaxI=200;
	ch2->MaxErr=1e+006;
	ch2->MaxOutput=200;
	ch2->DeadBandGain=1;
	ch2->DeadBandRange=0;
	ch2->InputChan0=0;
	ch2->InputChan1=0;
	ch2->OutputChan0=10;
	ch2->OutputChan1=0;
	ch2->MasterAxis=-1;
	ch2->LimitSwitchOptions=0x0;//no hardware limit
	ch2->SoftLimitPos=1e+009; //no limit
	ch2->SoftLimitNeg=-1e+009; //no limit
	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=1;
	ch2->Lead=0;
	ch2->MaxFollowingError=1000000000;
	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;
	EnableAxisDest(2,0);

	//ch3=Y' axis
	ch3->InputMode=NO_INPUT_MODE;
	ch3->OutputMode=STEP_DIR_MODE;
	ch3->Vel=40000;
	ch3->Accel=200000;
	ch3->Jerk=4e+006;
	ch3->P=0;
	ch3->I=0.01;
	ch3->D=0;
	ch3->FFAccel=0;
	ch3->FFVel=0;
	ch3->MaxI=200;
	ch3->MaxErr=1e+006;
	ch3->MaxOutput=200;
	ch3->DeadBandGain=1;
	ch3->DeadBandRange=0;
	ch3->InputChan0=0;
	ch3->InputChan1=0;
	ch3->OutputChan0=11;
	ch3->OutputChan1=0;
	ch3->MasterAxis=-1;
	ch3->LimitSwitchOptions = 0x110;
	ch3->LimitSwitchNegBit = 1036;
	ch3->LimitSwitchPosBit = 1035;
	ch3->SoftLimitPos = 47222.22222; //TBT
	ch3->SoftLimitNeg = -47222.22222; //TBT
	ch3->InputGain0=1;
	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=1000000000;
	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=1;
	ch3->iir[2].B1=0;
	ch3->iir[2].B2=0;
	ch3->iir[2].A1=0;
	ch3->iir[2].A2=0;
	EnableAxisDest(3,0);

	//ch4=Z axis
	ch4->InputMode=NO_INPUT_MODE;
	ch4->OutputMode=STEP_DIR_MODE;
	ch4->Vel=4000;
	ch4->Accel=40000;
	ch4->Jerk=4e+006;
	ch4->P=0;
	ch4->I=0.01;
	ch4->D=0;
	ch4->FFAccel=0;
	ch4->FFVel=0;
	ch4->MaxI=200;
	ch4->MaxErr=1e+006;
	ch4->MaxOutput=200;
	ch4->DeadBandGain=1;
	ch4->DeadBandRange=0;
	ch4->InputChan0=4;
	ch4->InputChan1=0;
	ch4->OutputChan0=12;
	ch4->OutputChan1=0;
	ch4->MasterAxis=-1;
	ch4->LimitSwitchOptions=0x110;
	ch4->LimitSwitchNegBit = 1033;
	ch4->LimitSwitchPosBit = 1032;
	ch4->SoftLimitPos = 15625; //TBT
	ch4->SoftLimitNeg = -15625; //TBT
	ch4->InputGain0=-1;
	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=20;

	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=0.000769;
	ch4->iir[2].B1=0.001538;
	ch4->iir[2].B2=0.000769;
	ch4->iir[2].A1=1.92076;
	ch4->iir[2].A2=-0.923833;
	EnableAxisDest(4,0);
	
	//ch5=polishing tool
	ch5->InputMode=NO_INPUT_MODE;
	ch5->OutputMode=STEP_DIR_MODE;
	ch5->Vel=40000;
	ch5->Accel=400000;
	ch5->Jerk=4e+06;
	ch5->P=0;
	ch5->I=0.01;
	ch5->D=0;
	ch5->FFAccel=0;
	ch5->FFVel=0;
	ch5->MaxI=200;
	ch5->MaxErr=1e+06;
	ch5->MaxOutput=200;
	ch5->DeadBandGain=0;
	ch5->DeadBandRange=0;
	ch5->InputChan0=0;
	ch5->InputChan1=0;
	ch5->OutputChan0=5;
	ch5->OutputChan1=0;
	ch5->MasterAxis=-1;
	ch5->LimitSwitchOptions=0x110;
	ch5->LimitSwitchNegBit=0; //no hardware limit
	ch5->LimitSwitchPosBit=0;
	ch5->SoftLimitPos=1e+09;
	ch5->SoftLimitNeg=-1e+09; //no limit
	ch5->InputGain0=1;
	ch5->InputGain1=1;
	ch5->InputOffset0=0;
	ch5->InputOffset1=0;
	ch5->OutputGain=-1;
	ch5->OutputOffset=0;
	ch5->SlaveGain=1;
	ch5->BacklashMode=BACKLASH_OFF;
	ch5->BacklashAmount=0;
	ch5->BacklashRate=0;
	ch5->invDistPerCycle=1;
	ch5->Lead=0;
	ch5->MaxFollowingError=1000000000;
	ch5->StepperAmplitude=20;

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

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

	ch5->iir[2].B0=0.000769;
	ch5->iir[2].B1=0.001538;
	ch5->iir[2].B2=0.000769;
	ch5->iir[2].A1=1.92076;
	ch5->iir[2].A2=-0.923833;
	EnableAxisDest(5,0);

	//definecoordinate
	DefineCoordSystem6(0,1,4,-1,3,2); // define axis chan numbers to use as x,y,z,a,b,c (set -1 to disable)
	
	//ENA pins, release to start moving, function: ClearBit()=low, SetBit()=high
	void SetBitDirection(56, 1);  // Set pin 56 as an output, xyzy'z' ENA
	ClearBit(56);            // Set pin 56 low ="turn off" the enable pin=motor start
	void SetBitDirection(55, 1);  // Set pin 55 as an output, polishing tool ENA
	ClearBit(55);            // Set pin 55 low ="turn off" the enable pin=motor start

	//Brake pins
	void SetBitDirection(52, 1); //Set pin 52 as an output, z brake
	SetBit(52); //"turn on" 52=high
	void SetBitDiretion(53, 1); //Set pin 53 as an output, polishing tool brake
	SetBit(53); //"turn on" 53=high

    
    // Home each axis to its origin
    HomeAxis(0, 6000, 1026); // Home X axis
    HomeAxis(1, 200, 1029); // Home Y axis
    HomeAxis(4, 500, 1034); // Home Z axis
    HomeAxis(3, 450, 1037); // Home Y' axis
    HomeAxis(2, 370, 1040); // Home Z' axis

    return 0;
}

//function for defining origin
void HomeAxis(int axis, float jogSpeed, int originBit) {
	//disable limit switch if needed
    Jog(axis, jogSpeed); //jog until it sees the limit, jog speed TBT
    while (ReadBit(originBit) == 1); // Wait until the origin is found
    Jog(axis, 0); // Stop the axis
    while (!CheckDone(axis)); // Ensure the axis has fully stopped
    Zero(axis); // Zero the axis at the origin position
}



Re: Axis set up

Posted: Wed Mar 06, 2024 10:30 pm
by TomKerekes
Hi Katie,
I am currently using the "Disallow drive into limit" option. According to the kflop manual, it should " allow a move away from the limit". However, once the soft limit is reached, the motor cannot be moved
The Limit Switch Action has to do with Limit Switches not Soft Limits.

Soft Limits stop using a Feed Hold to come to a controlled coordinated stop. If Feed Hold is released you should be able to move out of the Soft Limit.

HTH