Greetings,

Making progress. Have built an all new control. Wired up the valve system. Attached is the file I am running the machine with. As well as the init____.c file I am using. Not complete yet.

I am so far using jog... to limit switches. Down Button, Up Button, Down Foot Peddle. I have encoder feedback for both axis. Two hydraulic cylinders. Valve control for fast down, slow down, and fast return.
I have done step response tuning.... and able to get a profile move 2000 counts. And it moves pretty good on a single axis.

So I can jog, like Jog(0, 2000); Jog(1, 2000); and this moves down Pressing reasonably good. When it hits the switch it returns to the top. I have even tested some jogging to a ch0->Position and then reacting to this, which can be useful.
What I don't have... is closed loop motion... I am probably missing something... I have encoders that are 5080 cnts/inch. I can get action via the tuning... but not with a move command like this??? MoveRelAtVel(0, -5080, 2000); //MOVE UP ONE INCH

The code is debugged, but don't have that newest copy here. Another problem... with Jog... is that I have to Zero(0); Zero(1); both axis so that I can get them to move right away when commanded to jog.
As well the DEST does not match the Position.... the Dest is just running on and on... and the position of course is matching the linear encoders... for axis 0, 1. Most likely related to no closed loop???

Thanks for your help!




#include "KMotionDef.h"

// Press Brake Run Version 4.0.3
// ADDED RAPID
//120mm/s Approach
//10mm/s Pressing
//100mm/s Return

enum { HOME, RETURN1, RETURN2, IDLE, DOWN, DOWNFAST, UP, DELAY, BOTTOM, TOP, RETURN}; // states
#define CLOSE 136
#define OPEN 137
#define RAPID 140
#define TOP 139
#define BOTTOM 138
#define SLAVE 1

int state = IDLE;
int slow = 2000; //2000 for pressing 40000 High Speed
int medium = 20000;
int fast = 20000;
double DelayTime;
int offset; //OFFSET
int Y3 = 144;
int Y5 = 145;
int A0; //PRESSURE
float a10; //Dwell calculation
int a12; //Dwell calculation
int dwell; // Bend Delay
int cnt1 = 0; //Pressure OFF after count
int automode = 0; //Auto Mode
int position = 0; //Destination Position for leveling

main()
{
for (; //forever loop
{
switch (state)
{
//WAIT FOR COMMAND TO MOVE
case IDLE:
if (!ReadBit(BOTTOM) && ReadBit(CLOSE)){ SET_OFFSET(); state = DOWNFAST; } //SET_OFFSET();
if (!ReadBit(TOP) && ReadBit(OPEN)){ ZERODEST(); state = UP; }
cnt1++;
Delay_sec(0.01);
if (cnt1 >= 2){ V_IDLE(); } //PUT PRESS VALVES INTO IDLE MODE AFTER 2 10THS OF A SECOND.
break;

//GOING DOWN FAST
case DOWNFAST:
if (ReadBit(RAPID)){ V_APPROACH(); Jog(0, fast); Jog(1, fast); state = BOTTOM; } //FAST CLOSE //RAPID REVERSED FOR EXTERNAL SWITCH ACTIVATION.
if (ReadBit(BOTTOM)){ Jog(0, 0); Jog(1, 0); SET_DWELL(); state = DELAY; }
break;


//GOING DOWN
case DOWN:
if (!ReadBit(BOTTOM) && !ReadBit(RAPID)){ V_PRESSING(); Jog(0, slow); Jog(1, slow); state = BOTTOM; } //CHANGE TO SLOW CLOSE
if (ReadBit(BOTTOM)){ Jog(0, 0); Jog(1, 0); SET_DWELL(); state = DELAY; }
break;

//WAIT FOR LIMIT OR RELEASE OF (FOOT PEDDLE OR DOWN BUTTON).
case BOTTOM:
if (!ReadBit(CLOSE)){ Jog(0, 0); Jog(1, 0); cnt1 = 0; state = IDLE; }
if (ReadBit(BOTTOM)){ automode = 1; Jog(0, 0); Jog(1, 0); SET_DWELL(); state = DELAY; } //Put into auto mode.
break;

//DWELL AT BOTTOM
case DELAY:
if (Time_sec() > DelayTime){ state = UP; }
break;

//GOING UP
case UP:
if (!ReadBit(TOP)){ V_DECOMPRESSION(); Jog(0, -slow); Jog(1, -slow); state = RETURN; } //SLOW OPEN
if (ReadBit(TOP)){ Jog(0, 0); Jog(1, 0); ZERODEST(); cnt1 = 0; state = IDLE; }
break;

//RETURN AT MEDIUM SPEED
case RETURN:
if (!automode && !ReadBit(TOP)){ V_RETURN(); ZERODEST(); Jog(0, -medium); Jog(1, -medium); state = TOP; } //MEDIUM OPEN
if (automode && !ReadBit(TOP)){ V_RETURN(); ZERODEST(); Jog(0, -medium); Jog(1, -medium); state = HOME; } //AUTO GO TO TOP LIMIT THEN LEVEL
break;

//WAIT FOR LIMIT OR (RELEASE OF UP BOTTON IF NOT IN AUTO MODE).
case TOP:
if (!ReadBit(OPEN)){ Jog(0, 0); Jog(1, 0); ZERODEST(); cnt1 = 0; state = IDLE; } //STOP AND PUT BAKE INTO IDLE
if (ReadBit(TOP)){ Jog(0, 0); Jog(1, 0); ZERODEST(); cnt1 = 0; state = IDLE; }
break;

//AUTO GO TO TOP LIMIT THEN LEVEL
case HOME:
if (automode && ReadBit(TOP)){ V_IDLE(); Jog(0, 0); Jog(1, 0); ZERODEST(); automode = 0; }
//MOVE DOWN AND EVEN
if (!automode && ReadBit(TOP)){
int pos1 = ch0->Position;
int pos2 = ch1->Position;
position = pos2;
Delay_sec(0.1);
if (pos1 < pos2){ V_PRESSING(); Jog(0, slow); state = RETURN1; }
if (pos1 > pos2){ V_RETURN(); Jog(0, -slow); state = RETURN2; }
}
break;

case RETURN1:
if (ch0->Position >= position){V_IDLE(); Jog(0, 0); Jog(1, 0); ZERODEST(); cnt1 = 0; state = IDLE;}
break;

case RETURN2:
if (ch0->Position >= position){V_IDLE(); Jog(0, 0); Jog(1, 0); ZERODEST(); cnt1 = 0; state = IDLE;}
break;

}

}
}

//----------------------------------- VALVE CONTROL ------------------------------------------------------

V_IDLE()
{
//SET SPEED TO ZERO
int max = 0; ch0->MaxOutput = max; ch1->MaxOutput = max;
ClearBit(Y3);
ClearBit(Y5);
DAC(2,0); //Pressure Setting Zero
}

V_APPROACH()
{
//SET SPEED TO NORM
int max = 600; ch0->MaxOutput = max; ch1->MaxOutput = max;
SetBit(Y3);
SetBit(Y5);
A0 = ADC(0) * 2.12; //0 - 945 Reading Pressure Setting
DAC(2, -A0); //SET PRESSURE
}

V_PRESSING()
{
//SET SPEED TO MAX
int max = 2000; ch0->MaxOutput = max; ch1->MaxOutput = max;
ClearBit(Y3); //Experiment
SetBit(Y5);
A0 = ADC(0) * 2.12; //0 - 945 Reading Pressure Setting
DAC(2, -A0); //SET PRESSURE
}

V_DECOMPRESSION()
{

//SET SPEED TO ZERO THEN TO MINIMAL
int max = 0; ch0->MaxOutput = max; ch1->MaxOutput = max; //Instant Stop
ClearBit(Y3);
ClearBit(Y5);
Delay_sec(1.0);
int max = 100; ch0->MaxOutput = max; ch1->MaxOutput = max;
A0 = ADC(0) * 2.12; //0 - 945 Reading Pressure Setting
DAC(2, -A0); //SET PRESSURE

}

V_RETURN()
{
//REGULATE UP SPEED
int max = 300; ch0->MaxOutput = max; ch1->MaxOutput = max;
ClearBit(Y3);
ClearBit(Y5);
A0 = ADC(0) * 2.12; //0 - 945 Reading Pressure Setting
DAC(2, -A0); //SET PRESSURE
}

//------------------------------ SET DWELL -----------------------------------------------------------------

SET_DWELL()
{
a10 = ADC(1) / 189;
if (a10 > 189)
{
if (a10 > 0 && a10 <= 1){dwell = 1;}
if (a10 > 1 && a10 <= 2){dwell = 2;}
if (a10 > 2 && a10 <= 3){dwell = 3;}
if (a10 > 3 && a10 <= 4){dwell = 4;}
if (a10 > 4 && a10 <= 5){dwell = 5;}
}
if (a10 < 189){ dwell = 1; }
if (a10 < 0){ dwell = 1; }
DelayTime = Time_sec() + dwell; state = DELAY;
}

//------------------------------ SET OFFSET -----------------------------------------------------------------

SET_OFFSET()
{

int a3 = ADC(2);
int a5 = convert_value(a3);
ch0->MaxOutput = 600;
ch1->MaxOutput = a5;
//printf("Y1 MaxOutput = %d\n",a5);
state = DOWN;
}

convert_value(int a3){
// Calculate the scaling factor (avoid floating-point math).
int scale_factor = (620 - 610) * 1000 / (945 - 4);

// Apply the scaling factor to a3 and offset by 610 to get the new value.
int new_value = a3 * scale_factor / 1000 + 610;

return new_value; }

//---------------------------------------- ZERO DEST AND ALL -------------------------------------------------------------

ZERODEST()
{
ch0->Dest = 0; ch1->Dest = 0; Delay_sec(0.1);
}

ZERONOW()
{
Zero(0); Zero(1); Delay_sec(0.1);
}



#include "KMotionDef.h"

main()
{
ch0->InputMode=ENCODER_MODE;
ch0->OutputMode=DAC_SERVO_MODE;
ch0->Vel=1000;
ch0->Accel=400000;
ch0->Jerk=4e+06;
ch0->P=30;
ch0->I=0;
ch0->D=60;
ch0->FFAccel=0.025;
ch0->FFVel=1.2;
ch0->MaxI=1000;
ch0->MaxErr=2e+06;
ch0->MaxOutput=600;
ch0->DeadBandGain=1;
ch0->DeadBandRange=0;
ch0->InputChan0=0;
ch0->InputChan1=0;
ch0->OutputChan0=0;
ch0->OutputChan1=0;
ch0->MasterAxis=-1;
ch0->LimitSwitchOptions=0x100;
ch0->LimitSwitchNegBit=0;
ch0->LimitSwitchPosBit=0;
ch0->SoftLimitPos=1e+09;
ch0->SoftLimitNeg=-1e+09;
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=1;
ch0->iir[2].B1=0;
ch0->iir[2].B2=0;
ch0->iir[2].A1=0;
ch0->iir[2].A2=0;

ch1->InputMode=ENCODER_MODE;
ch1->OutputMode=DAC_SERVO_MODE;
ch1->Vel=1000;
ch1->Accel=400000;
ch1->Jerk=4e+06;
ch1->P=30;
ch1->I=0;
ch1->D=60;
ch1->FFAccel=0.025;
ch1->FFVel=1.2;
ch1->MaxI=1000;
ch1->MaxErr=2e+06;
ch1->MaxOutput=620;
ch1->DeadBandGain=1;
ch1->DeadBandRange=0;
ch1->InputChan0=1;
ch1->InputChan1=0;
ch1->OutputChan0=1;
ch1->OutputChan1=0;
ch1->MasterAxis=-1;
ch1->LimitSwitchOptions=0x100;
ch1->LimitSwitchNegBit=0;
ch1->LimitSwitchPosBit=0;
ch1->SoftLimitPos=1e+09;
ch1->SoftLimitNeg=-1e+09;
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=1;
ch1->iir[2].B1=0;
ch1->iir[2].B2=0;
ch1->iir[2].A1=0;
ch1->iir[2].A2=0;


EnableAxis(0);
EnableAxis(1);

DefineCoordSystem(0,1,-1,-1);
}