# control loop

I'm using the following control-loop algorithm in my application and I'm wondering if there is something more performant. Anyone expert about that?

int controlPin (
double synth, /*synth can be D_SYNT1 or D_SYNT2*/
double Cfre, /*frequency of SYNTH*/
double *SyLvlFIN, /*current setting of SYNTH*/
double PinSP, /*Setpoint of Pin*/
){

double error=0.0;
double div=2.0;

return FAIL;

error = *Pin - PinSP; //calculate error

//stay in loop while error is grater than resolution
while ( (*Pin > PinSP + Risol) ||
(*Pin < PinSP - Risol) ) {

//current iteration :positive error
if (*Pin > PinSP + Risol)
{
if (error > 0.0) //previous iteration: positive error
{
*SyLvlFIN -= (*Pin - PinSP)/2;
}

else //previous iteration: negative error
{
*SyLvlFIN -= (*Pin - PinSP)/(2 + div);
div += 2.0;
}
//actuate control action
if (SetSynt (Cfre, *SyLvlFIN, synth) == FAIL)
return FAIL;
}
//negative error
else
{
if (error < 0.0) //previous iteration: positive error
{
*SyLvlFIN += (PinSP - *Pin)/2;
}

else //previous iteration: negative error
{
*SyLvlFIN += (PinSP - *Pin)/(2 + div);
div += 2.0;
}
//actuate control action
if (SetSynt (Cfre, *SyLvlFIN, synth) == FAIL)
return FAIL;

}//close else negative error

error = *Pin - PinSP; //store error value for next iteration

//read new value for variable under control
return FAIL;

}//while

return OK;

}

• : I'm using the following control-loop algorithm in my application and I'm wondering if there is something more performant. Anyone expert about that?
:
:
: int controlPin (
: double synth, /*synth can be D_SYNT1 or D_SYNT2*/
: double Cfre, /*frequency of SYNTH*/
: double *SyLvlFIN, /*current setting of SYNTH*/
: double PinSP, /*Setpoint of Pin*/
: ){
:
: double error=0.0;
: double div=2.0;
:
:
: return FAIL;
:
: error = *Pin - PinSP; //calculate error
:
: //stay in loop while error is grater than resolution
: while ( (*Pin > PinSP + Risol) ||
: (*Pin < PinSP - Risol) ) {
:
: //current iteration :positive error
: if (*Pin > PinSP + Risol)
: {
: if (error > 0.0) //previous iteration: positive error
: {
: *SyLvlFIN -= (*Pin - PinSP)/2;
: }
:
: else //previous iteration: negative error
: {
: *SyLvlFIN -= (*Pin - PinSP)/(2 + div);
: div += 2.0;
: }
: //actuate control action
: if (SetSynt (Cfre, *SyLvlFIN, synth) == FAIL)
: return FAIL;
: }
: //negative error
: else
: {
: if (error < 0.0) //previous iteration: positive error
: {
: *SyLvlFIN += (PinSP - *Pin)/2;
: }
:
: else //previous iteration: negative error
: {
: *SyLvlFIN += (PinSP - *Pin)/(2 + div);
: div += 2.0;
: }
: //actuate control action
: if (SetSynt (Cfre, *SyLvlFIN, synth) == FAIL)
: return FAIL;
:
: }//close else negative error
:
: error = *Pin - PinSP; //store error value for next iteration
:
: //read new value for variable under control
: return FAIL;
:
: }//while
:
: return OK;
:
: }
:

Do you really need float numbers? After casting a brief glance at your code, the only place you seem to need accuracy is when you divide. Why not use integers and make your own divide algo?

[code]
uint32 gpfunc_roundDivide_uint32 (uint32 x, uint32 y)
{
uint32 remain;
uint32 quot;

if(y==0) /* divide by zero */
return 0;

quot = x/y;

remain = (x*100)/y - (quot)*100;

if(remain < 50)
return quot;
else
return quot + 1;
}
[/code]