control loop - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

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 *Pin /*Pin readback*/
){

double error=0.0;
double div=2.0;


if(ReadPin (Pin) == FAIL)//read variable under control
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
if(ReadPin (Pin) == FAIL)
return FAIL;

}//while

return OK;

}

Comments

  • LundinLundin Posts: 3,711Member
    : 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 *Pin /*Pin readback*/
    : ){
    :
    : double error=0.0;
    : double div=2.0;
    :
    :
    : if(ReadPin (Pin) == FAIL)//read variable under control
    : 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
    : if(ReadPin (Pin) == FAIL)
    : 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]

Sign In or Register to comment.