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

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

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.