//Call standard analog PID
Kzd = min(1e3/(f_frq*Tzd), 1);
Kint = min(1e3/(f_frq*Ti), 1);
Kdif = min(1e3/(f_frq*Td), 1);

//Scale error
if(max <= min) return 0;

//Prepare values
spv = 100*(sp-min)/(max-min);
val = 100*(var-min)/(max-min);
val += K1*in1 + K2*in2;
val = min(100,max(-100,val));

//Error
err = spv - val;
err = (abs(err)<Zi) ? 0 : ((err>0) ? err-Zi : err+Zi );
err *= Kp;
err = min(100,max(-100,err));
errP = err-err1;
errD = err1-err2;
err2 = err1; err1 = err;

integ += Kint*err;							//Integral
difer -= Kdif*(difer-errD);				//Differecial wait
dlag  += Kzd*((errP-difer)-dlag);	//Differecial lag

//Automatic mode enabled
if(auto) { outPID = errP + Ki*err + integ + Kd*dlag; outA = 50 + outPID + K3*in3 + K4*in4; }
else {
	outPID = 0;
	casc = false;
	if(followSp) sp = var;
	outA = manIn;
}

//Check output limits
outA = manIn = min(Hup, max(Hdwn,outA));

//Fix integral for manual and limits
//integ = outA - errP - Kd*dlag - K3*in3 - K4*in4;

if(f_start || f_stop) { impQup = impQdwn = false; return 0; }

//Call impuls generator
outA = 2*(outA-50);
if(perLag <= 0 && ((outA*KImpRfact) >= (100*TImpMin/TImpPer) || (-outA/KImpRfact) >= (100*TImpMin/TImpPer) || (!auto && abs(outA) > 0.1)))
{
	impLag = max(abs(outA)*TImpPer/100,TImpMin);
	impLag = (outA > 0) ? impLag*KImpRfact : impLag/KImpRfact;
	perLag = TImpPer;
	if(outA > 0) impQup = true; else impQdwn = true;  
}
else if(perLag > 0) {
	perLag -= 1e3/f_frq;
	if((TImpPer-perLag) >= impLag) {
		impQup = impQdwn = false;
		if(!auto) perLag = 0;
  }
}

if(!auto) manIn = 50;

if(impQupTm > 1 || (impQupTm && !impQup)) impQupTm--;
if(impQup && !impQupTm) impQupTm = 2*f_frq;
if(impQdwnTm > 1 || (impQdwnTm && !impQdwn)) impQdwnTm--;
if(impQdwn && !impQdwnTm) impQdwnTm = 2*f_frq;

if(impQup || impQdwn) integ = 0;

if(impAnImit) {
	if(impQup) out += 100/(impAnOut*f_frq);
	if(impQdwn) out -= 100/(impAnOut*f_frq);
	return max(0, min(100,out));
}
return impAnOut;