: 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?
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;
}