JOG Axis , and stop mmediately

Moderators: TomKerekes, dynomotion

Post Reply
REGENS
Posts: 8
Joined: Wed Mar 18, 2020 3:27 pm

JOG Axis , and stop mmediately

Post by REGENS » Mon Jul 20, 2020 12:46 pm

Dear Dynomotion Professionals,

I tried to use the jog function through external inputs push buttons, the jog works ok, but the problem is stopping the jog, it does not stop immediately.

I attach a video here showing the problem, also I attach the C code to check.



Help please


C CODE:

"#include "KMotionDef.h"

#define XAXIS 4
#define YAXIS 5
#define ZAXIS 6

#define XPLUS 1040
#define XMINUS 1041
#define YPLUS 1042
#define YMINUS 1043
#define ZPLUS 1045
#define ZMINUS 1044

#define MAX_SPEED_X 49500
#define MAX_SPEED_Y 8000
#define MAX_SPEED_Z 5000
//2500,3000,3000

void DoSpeedAxis(int ch, int Plus, int Minus, double *LastSpeed, double Speed);

double T0=0.0,T1;

main()
{
void DoSpeedAxis(int ch, int Plus, int Minus, double *LastSpeed, double Speed);
double Pot,LastSpeed_X=0.0,LastSpeed_Y=0.0,LastSpeed_Z=0.0;

printf("%f\n",KANALOG_CONVERT_ADC_TO_VOLTS(ADC(0)));

for (;;)
{
int Check_X=1;
T1=WaitNextTimeSlice();


if (!ReadBit(XPLUS)&&!ReadBit(XMINUS)) // Watch an external input switch
{

DAC(4,0);
EnableAxis(4);
}

if (T1-T0 > 0.05) // only change speed every so often
{
Pot=KANALOG_CONVERT_ADC_TO_VOLTS(ADC(0)) * (1.0/5.0);
if(Check_X)
{DoSpeedAxis(XAXIS, XPLUS, XMINUS, &LastSpeed_X, 3.5*Pot*MAX_SPEED_X);}
DoSpeedAxis(YAXIS, YPLUS, YMINUS, &LastSpeed_Y, Pot*MAX_SPEED_Y);
DoSpeedAxis(ZAXIS, ZPLUS, ZMINUS, &LastSpeed_Z, Pot*MAX_SPEED_Z);
}

}
}

void DoSpeedAxis(int ch, int Plus, int Minus, double *LastSpeed, double Speed)
{

if (ReadBit(Plus)) //toggle to plus direction?
{
Jog(ch,Speed);
*LastSpeed = Speed;
T0=T1; // save last time speed was changed
}
else if (ReadBit(Minus)) //toggle to minus direction
{
Jog(ch,-Speed);
*LastSpeed = -Speed;
T0=T1; // save last time speed was changed
}


else //neither toggle so stop, if axis isn't already
{


if (ReadBit(XPLUS)&&ReadBit(XMINUS)) // Watch an external input switch
{
DAC(4,0);
EnableAxis(4);

}

if (ReadBit(YPLUS)&&ReadBit(YMINUS)) // Watch an external input switch
{
DAC(5,0);
EnableAxis(5);
}

if (ReadBit(ZPLUS)&&ReadBit(ZMINUS)) // Watch an external input switch
{
DAC(6,0);
EnableAxis(6);
}

if (*LastSpeed != 0.0) Jog(ch,0.0);
*LastSpeed=0.0;

}

}
"

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

Re: JOG Axis , and stop mmediately

Post by TomKerekes » Mon Jul 20, 2020 3:17 pm

Hi REGENS,

The Video is private and not viewable.

I'm not sure the purpose of this:

Code: Select all

		if (!ReadBit(XPLUS) && !ReadBit(XMINUS))	// Watch an external input switch
		{
			DAC(4, 0);
			EnableAxis(4);
		}
There isn't any purpose for writing to the DAC when the Axis is enabled and also writing to the DAC.

Also continuously Enabling the Axis when it is already enabled will cause problems.

Please post any code using the Code Tag so it is readable.

You should also post your configuration.

HTH
Regards,

Tom Kerekes
Dynomotion, Inc.

REGENS
Posts: 8
Joined: Wed Mar 18, 2020 3:27 pm

Re: JOG Axis , and stop mmediately

Post by REGENS » Wed Jul 22, 2020 7:31 am

Here i attach the code again:

Code: Select all

#include "KMotionDef.h"

#define XAXIS 4
#define YAXIS 5
#define ZAXIS 6

#define XPLUS 1040
#define XMINUS 1041
#define YPLUS 1042
#define YMINUS 1043
#define ZPLUS 1045
#define ZMINUS 1044

#define MAX_SPEED_X 49500
#define MAX_SPEED_Y 8000
#define MAX_SPEED_Z 5000

void DoSpeedAxis(int ch, int Plus, int Minus, double *LastSpeed, double Speed);

double T0=0.0,T1;

main()
{
void DoSpeedAxis(int ch, int Plus, int Minus, double *LastSpeed, double Speed);
double Pot,LastSpeed_X=0.0,LastSpeed_Y=0.0,LastSpeed_Z=0.0;

printf("%f\n",KANALOG_CONVERT_ADC_TO_VOLTS(ADC(0)));

for (;;)
{
T1=WaitNextTimeSlice();


if (!ReadBit(XPLUS)&&!ReadBit(XMINUS)) // Watch an external input switch
{

DAC(4,0);
EnableAxis(4);
}

if (T1-T0 > 0.05) // only change speed every so often
{
Pot=KANALOG_CONVERT_ADC_TO_VOLTS(ADC(0)) * (1.0/5.0);
if(Check_X)
{DoSpeedAxis(XAXIS, XPLUS, XMINUS, &LastSpeed_X, 3.5*Pot*MAX_SPEED_X);}
DoSpeedAxis(YAXIS, YPLUS, YMINUS, &LastSpeed_Y, Pot*MAX_SPEED_Y);
DoSpeedAxis(ZAXIS, ZPLUS, ZMINUS, &LastSpeed_Z, Pot*MAX_SPEED_Z);
}

}
}

void DoSpeedAxis(int ch, int Plus, int Minus, double *LastSpeed, double Speed)
{

if (ReadBit(Plus)) //toggle to plus direction?
{
Jog(ch,Speed);
*LastSpeed = Speed;
T0=T1; // save last time speed was changed
}
else if (ReadBit(Minus)) //toggle to minus direction
{
Jog(ch,-Speed);
*LastSpeed = -Speed;
T0=T1; // save last time speed was changed
}

else //neither toggle so stop, if axis isn't already
{

if (ReadBit(XPLUS)&&ReadBit(XMINUS)) // Watch an external input switch
{
DAC(4,0);
EnableAxis(4);

}

if (ReadBit(YPLUS)&&ReadBit(YMINUS)) // Watch an external input switch
{
DAC(5,0);
EnableAxis(5);
}

if (ReadBit(ZPLUS)&&ReadBit(ZMINUS)) // Watch an external input switch
{
DAC(6,0);
EnableAxis(6);
}

if (*LastSpeed != 0.0) Jog(ch,0.0);
*LastSpeed=0.0;

}

}

REGENS
Posts: 8
Joined: Wed Mar 18, 2020 3:27 pm

Re: JOG Axis , and stop mmediately

Post by REGENS » Wed Jul 22, 2020 9:18 am

Here is the Enable C Program, contains the axis configurations:

Code: Select all

#include "KMotionDef.h"

#define TMP 10 // which spare persist to use to transfer data
#include "KflopToKMotionCNCFunctions.c"

#define CHANGE_TOL 0.02  // only update if change is more than this
#define CHANGE_TIME 0.05  // don't update more often then this time
double LastFRO=-1;
double LastFROTime=0;

// Configure KFLOP to service Konnect 32 Input 16 output IO board
// Board address is 0, 
// 16 Outputs are mapped to Virtual IO 48-63 (VirtualBits)
// 32 Inputs are mapped to Virtual IO 1024-1055 (VirtualBits[0])
//
// Attach Service to Aux0 Port (KFLOP JP4) instead of standard Aux1 Port (KFLOP JP6)
double Pot,FRO,T,Pot1;
double Pot2,RRO;
double Pot3,SSO;
double T;
// Service the FRO Selector.  When it changes and becomes
// stable command new FRO
//void Service_FRO_AND_RRO(void)

// Service the SSO Selector.  When it changes and becomes
// stable command new SSO
void Service_FRO(void)
{
	Pot1=KANALOG_CONVERT_ADC_TO_VOLTS(ADC(0));
	FRO = (Pot1*1.9/5.0)+0.1;
	if (FRO>2)
		FRO=2;
	DoPCFloat(PC_COMM_SET_FRO,FRO);

	
}
void ServiceSSO(void)
{
	Pot2=KANALOG_CONVERT_ADC_TO_VOLTS(ADC(1));

	SSO = (Pot2*1.9/5.0)+0.1;
	if (SSO>2)
		SSO=2;
	DoPCFloat(PC_COMM_SET_SSO,SSO);
}
main()
{
	InitAux();
	AddKonnect(0,&VirtualBits,VirtualBitsEx);
	//DEFINE Inputs
#define X 4
#define Y 5
#define Z 6
#define Z_NEGATIVE_LIMIT_BIT 1024
#define Z_POSITIVE_LIMIT_BIT 1025
#define Z_REFERENCE_BIT 1026
#define X_NEGATIVE_LIMIT_BIT 1028
#define X_POSITIVE_LIMIT_BIT 1027
#define X_REFERENCE_BIT 1028
#define X_REFERENCE_2_BIT 1029
#define Y_NEGATIVE_LIMIT_BIT 1030
#define Y_POSITIVE_LIMIT_BIT 1031
#define Y_REFERENCE_BIT 1032
#define TOOL_UNLOCK_PB 1033
#define GEAR_SHIFT_M41_SENSOR 1034
#define GEAR_SHIFT_M42_SENSOR 1035
#define GEAR_SHIFT_M43_SENSOR 1036
#define GEAR_OIL_LEVEL_SENSOR 1037
#define EMERGENCY_IN_BIT 1038
#define DRIVERS_FAULT_SERIES 1039

#define SPARE_INPUT_1 1046
#define SPARE_INPUT_2 1047

//DEFINE OUTPUTS
#define ENABLE_X_AXIS_DRIVER 63
#define ENABLE_Y_AXIS_DRIVER 62
#define ENABLE_Z_AXIS_DRIVER 61
#define SPINDLE_FORWARD_SPIN 60
#define SPINDLE_REVERSE_SPIN 59
#define LUBRICATION_START 58
#define WATER_MIST_VALVE_M8 57
#define HYDRAULIC_POWER_ON 56
#define GEAR_SHIFT_VALVE_M41 55
#define GEAR_SHIFT_VALVE_M43 54
#define TOOL_UNLOCK_VALVE 53
#define INVERTER_EMERGENCY  1039
#define XPLUS  1041
#define XMINUS 1040
#define YPLUS  1043
#define YMINUS 1042
#define ZPLUS  1045
#define ZMINUS 1044
#define MAX_SPEED_X 500.0
#define MAX_SPEED_Y 500.0
#define MAX_SPEED_Z 500.0
#define XAXIS 0
#define YAXIS 1
#define ZAXIS 2

void DoSpeedAxis(int ch, int Plus, int Minus, double *LastSpeed, double Speed);

double T0=0.0,T1;
	ch4->InputMode=ENCODER_MODE;
	ch4->OutputMode=DAC_SERVO_MODE;
	ch4->Vel=60000.000000; //12000
	ch4->Accel=820000.000000; //2000
	ch4->Jerk=100000.000000;
	ch4->P=3.2500000;//0.8
	ch4->I=0.00000;//0.0
	ch4->D=0.25000;//0.01
	ch4->FFAccel=0.000000;
	ch4->FFVel=0.0000;
	ch4->MaxI=200.000000;
	ch4->MaxErr=2000.000000;
	ch4->MaxOutput=2000.000000;
	ch4->DeadBandGain=1.000000;
	ch4->DeadBandRange=0.000000;
	ch4->InputChan0=4;
	ch4->InputChan1=4;
	ch4->OutputChan0=4;
	ch4->OutputChan1=4;
	ch4->InputGain0=1.0000000;
	ch4->InputGain1=1.0000000;
	ch4->InputOffset0=0.000000;
	ch4->InputOffset1=0.000000;
	ch4->OutputGain=1.0;
	ch4->invDistPerCycle=0.000250;
	ch4->Lead=0.000000;
	ch4->MaxFollowingError=200000.000000;
	ch4->StepperAmplitude=100.000000;
	ch4->iir[0].B0=1.000000;
	ch4->iir[0].B1=0.000000;
	ch4->iir[0].B2=0.000000;
	ch4->iir[0].A1=0.000000;
	ch4->iir[0].A2=0.000000;
	ch4->iir[1].B0=1.000000;
	ch4->iir[1].B1=0.000000;
	ch4->iir[1].B2=0.000000;
	ch4->iir[1].A1=0.000000;
	ch4->iir[1].A2=0.000000;
	ch4->iir[2].B0=1.000000;
	ch4->iir[2].B1=0.000000;
	ch4->iir[2].B2=0.000000;
	ch4->iir[2].A1=0.000000;
	ch4->iir[2].A2=0.000000;	
	ch4->MasterAxis=-1;
	
	ch5->InputMode=ENCODER_MODE;
	ch5->OutputMode=DAC_SERVO_MODE;
	ch5->Vel=20000.000000;//2000000.0
	ch5->Accel=200000.000000;//500000.00000
	ch5->Jerk=100000.000000;//1000000.000000
	ch5->P=0.8000;//0.8
	ch5->I=0.00000000;//0.0
	ch5->D=0.00500;//0.005
	ch5->FFAccel=0.000000;
	ch5->FFVel=0.000000;
	ch5->MaxI=2000.000000;
	ch5->MaxErr=200000000.000000;
	ch5->MaxOutput=800.000000;//400
	ch5->DeadBandGain=1.000000;
	ch5->DeadBandRange=0.000000;
	ch5->InputChan0=6;
	ch5->InputChan1=6;
	ch5->OutputChan0=5;
	ch5->OutputChan1=5;
	ch5->InputGain0=1.000000;
	ch5->InputGain1=1.000000;
	ch5->OutputGain=-1;
	ch5->InputOffset0=0.000000;
	ch5->InputOffset1=0.000000;
	ch5->invDistPerCycle=0.000250;
	ch5->Lead=0.000000;
	ch5->MaxFollowingError=500000.000000;
	ch5->StepperAmplitude=100.000000;
	ch5->iir[0].B0=1.000000;
	ch5->iir[0].B1=0.000000;
	ch5->iir[0].B2=0.000000;
	ch5->iir[0].A1=0.000000;
	ch5->iir[0].A2=0.000000;
	ch5->iir[1].B0=1.000000;
	ch5->iir[1].B1=0.000000;
	ch5->iir[1].B2=0.000000;
	ch5->iir[1].A1=0.000000;
	ch5->iir[1].A2=0.000000;
	ch5->iir[2].B0=1.000000;
	ch5->iir[2].B1=0.000000;
	ch5->iir[2].B2=0.000000;
	ch5->iir[2].A1=0.000000;
	ch5->iir[2].A2=0.000000;
	ch5->MasterAxis=-1;
	
	ch6->MasterAxis=-1;
	ch6->InputMode=ENCODER_MODE;
	ch6->OutputMode=DAC_SERVO_MODE;
	ch6->Vel=10000.000000;
	ch6->Accel=200000.000000;
	ch6->Jerk=100000.000000;
	ch6->P=1.800;//0.2
	ch6->I=0.0000000;//0.0000050
	ch6->D=0.005;//7.5
	ch6->FFAccel=0.000000;
	ch6->FFVel=0.000000;
	ch6->MaxI=2000.000000;
	ch6->MaxErr=20000.000000;
	ch6->MaxOutput=1000.000000;
	ch6->DeadBandGain =1.000000;
	ch6->DeadBandRange=0.000000;
	ch6->InputChan0=5;
	ch6->InputChan1=5;
	ch6->OutputChan0=6;
	ch6->OutputChan1=6;
	ch6->InputGain0=-1.000000;//-1.000000;
	ch6->InputGain1=-1.000000;//-1.000000;
	ch6->InputOffset0=0.000000;
	ch6->InputOffset1=0.000000;
	ch6->OutputGain=-1.0;
	ch6->invDistPerCycle=0.000250;
	ch6->BacklashMode=BACKLASH_OFF;
	ch6->BacklashAmount=000.00000;
	ch6->BacklashRate=0.0;
	ch6->Lead=0.000000;
	ch6->MaxFollowingError=500000.000000;
	ch6->StepperAmplitude=100.000000;
	ch6->iir[0].B0=1.000000;
	ch6->iir[0].B1=0.000000;
	ch6->iir[0].B2=0.000000;
	ch6->iir[0].A1=0.000000;
	ch6->iir[0].A2=0.000000;
	ch6->iir[1].B0=1.000000;
	ch6->iir[1].B1=0.000000;
	ch6->iir[1].B2=0.000000;
	ch6->iir[1].A1=0.000000;
	ch6->iir[1].A2=0.000000;
	ch6->iir[2].B0=1.000000;
	ch6->iir[2].B1=0.000000;
	ch6->iir[2].B2=0.000000;
	ch6->iir[2].A1=0.000000;
	ch6->iir[2].A2=0.000000;	
	

	EnableAxis(4);
	EnableAxis(5);
	EnableAxis(6);

	SetBit(HYDRAULIC_POWER_ON);
	SetBit(ENABLE_X_AXIS_DRIVER);
	SetBit(ENABLE_Y_AXIS_DRIVER);
	SetBit(ENABLE_Z_AXIS_DRIVER);

	ClearBit(SPINDLE_FORWARD_SPIN);
	ClearBit(SPINDLE_REVERSE_SPIN);
	DAC(3,0);


	DefineCoordSystem6(4,5,6,-1,-1,-1);

DAC(3,0);


for (;;) // loop forever
	{	
		WaitNextTimeSlice();
		ServiceSSO();
		Service_FRO();
	
		if (!ReadBit(INVERTER_EMERGENCY))  // Watch an external input switch
		{
			StopCoordinatedMotion();  //feedhold
		}
		// assume 5V range where 2.5V is nominal FRO
		Pot=KANALOG_CONVERT_ADC_TO_VOLTS(ADC(0)) - 2.5;
		
		FRO = Pot*0.5+1.0;

		// send message to KMotionCNC if the pot changed significantly
		// and it has been a while since the last message
		if ((FRO > LastFRO+CHANGE_TOL || FRO < LastFRO-CHANGE_TOL) && 
			T > LastFROTime+CHANGE_TIME)
		{	printf("SSO = %f\n",SSO);
			printf("FRO = %f\n",FRO);
			DoPCFloat(PC_COMM_SET_FRO,FRO);
			
			LastFRO=FRO;
			LastFROTime=T;
		}
	}
	}

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

Re: JOG Axis , and stop mmediately

Post by TomKerekes » Wed Jul 22, 2020 4:13 pm

Hi REGENS,

Please indent your programs properly to make them readable.

You have duplicated code.

These functions

ServiceSSO();
Service_FRO();

Are called continuously and will flood commands to KMotionCNC. Make sure there is at least 0.05 seconds delay between each command.

Read my last Post. Do not call EnableAxis() continuously. Only call if not Enabled. Do not write to the DAC.
Regards,

Tom Kerekes
Dynomotion, Inc.

REGENS
Posts: 8
Joined: Wed Mar 18, 2020 3:27 pm

Re: JOG Axis , and stop mmediately

Post by REGENS » Wed Jul 22, 2020 7:34 pm

Dear Tom,

Thank you for your reply, please advice how to do that stop jogging immediately after release the jog push button, please show us examples, and what are the possible causes of delaying the immediate stop.

Regards,

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

Re: JOG Axis , and stop mmediately

Post by TomKerekes » Wed Jul 22, 2020 10:10 pm

Hi REGENS,

Please see and respond to my previous posts.
Regards,

Tom Kerekes
Dynomotion, Inc.

REGENS
Posts: 8
Joined: Wed Mar 18, 2020 3:27 pm

Re: JOG Axis , and stop mmediately

Post by REGENS » Mon Jul 27, 2020 11:53 am

I have changed as described, which are:

Code: Select all

ServiceSSO();
Service_FRO();
and tried to not call these functions.

And I have deleted the EnableAxis commands, the unneeded ones.


But still I face the problem, which is the stop jogging by external inputs; it does not stop immediately, please help to solve.

Regards,

REGENS
Posts: 8
Joined: Wed Mar 18, 2020 3:27 pm

Re: JOG Axis , and stop mmediately

Post by REGENS » Mon Jul 27, 2020 11:55 am

Here is the previous video showing the jog problem, please see the jog behaviour.


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

Re: JOG Axis , and stop mmediately

Post by TomKerekes » Mon Jul 27, 2020 9:29 pm

Please post the corrected programs.

When making Videos please describe what you are doing.

I see the DRO's are in blue. This means the encoder position is being displayed. See here.

It may be that the servos are poorly tuned and are slowly converging to the commanded position. To see if this is the case un-check Display Encoders to see if the DROs (now green) stop changing quickly.
Regards,

Tom Kerekes
Dynomotion, Inc.

Post Reply