This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Global Var

HI!!

I declared 3 global var, i call it inside diferent task and every execution this var should be updates but not to do it.
I have a 8051 under evaluation board.
Maybe can be a problem of my small micro?
What do u think about this?

Thanks

  • In this funtion, i return pid->iState, first this var returned 10 and after returned 4 and should return 14.

  • are you actually writing into the piece of memory pointed by iA? show that please...

  • For Erik!!

    What is your problem???????
    I have no problem

    Im a student and i work too hard to learn it
    why, then, does it upset you that I tell you HOW to learn it?

    Erik

  • javi,
    forget about your task for a moment. first of all you need conversion tables - for example, if you want to maintain constants speed of a system using a PID controller, assuming you have a speed sensor, you would translate your speed error (that is, set point minus actual speed) to desired current (based on the known properties of your system - speed control valve of some kind) and then again, convert that to a duty cycle (based on the properties on a valve that regulate the speed). and of course, this must be done for as long as speed control is required, so that the system can make continuous adjustments!
    please note that you do not need a task to do this. if you choose to use one - do not terminate it unless you want to stop closed loop control.

  • NO, sorry. I didnt understand you!!

  • This is my PID task, it should update the iA, but not to do it!!

    void PIDa (void) _task_ A _priority_ 1 {
    
    
            Ua = UpdatePID (&iA, SPa, PVa, 1, 4);
    
            os_send_signal(WRITE);
    
            os_delete_task(A);
    
    }
    

  • This is my PID task, it should update the iA, but not to do it!!

    Without seeing the code of updatePID, it is impossible for anyone to tell what the function does and what not.

    As long as you keep information scarce, all you're going to get is speculation.

  • please post the body of

    UpdatePID
    

    not just the calls to it - the function itself.

  • OK, well!! I explain the code:

    -I have a global var type struct.
    -I have 2 task: WRITE task: here create PID task PID task: here call to the funtion that update the those struct.

    This is the piece of code:

    PID.H
    
    typedef int real;
    
    typedef struct {
    
    real dState;            /* Ultima posicion             */
    real iState;            /* Estado del integrador       */
    real uMax,uMin;     /* Saturacion del actuador     */
    real Kp;                    /* Ganancia proporcional       */
    real Ti,Td;                     /* Cte, tiempo integral y derivativo        */
    real Ts,Tt;                     /* Periodo muestreo, Cte. tiempo tracking   */
    real Kwindup;           /* Cte. antireset windup                    */
    
    } SPid;
    
    real UpdatePID (SPid *pid, real SP, real PV, unsigned int AUTO,real Uman) reentrant{
             into PID.c
             ....
             pid->iState += error;
             return pid->iState;
    }
    
    MAIN.C
    
    //global var
    SPid iA
    
    void Write (void) _task_ WRITE _priority_ 1{
               .....
               os_create_task(A);
               os_wait(K_SIG, WAIT_FOREVER,0);
               os_clear_signal(WRITE);
    }
    
    void PIDa (void) _task_ A _priority_ 1 {
               ...
               Ua = UpdatePID (&iA, SPa, PVa, 1, 4);
               os_send_signal(WRITE);
               os_delete_task(B);
    }
    
    the iA var never update
    
    

  • real UpdatePID (SPid *pid, real SP, real PV, unsigned int AUTO,real Uman) reentrant {
    
            real P,I,D,v,u,Es,error;
    
            if (AUTO){
    
                    error = SP - PV;
    
                    P = pid->Kp*error;
                    if (pid->Ti){
                            I = pid->iState*(pid->Kp*(pid->Ts/pid->Ti)+ pid->Kwindup);
                            pid->iState = pid->iState + error;
                    }else I=0;
                    if (pid->Td){
                            D = (pid->Kp*(pid->Td/pid->Ts)*(PV - pid->dState));
                            pid->dState = PV;
                    }else D=0;
                    v = P + I + D;
                    if (v > pid->uMax) u=pid->uMax;                           /* Antireset windup */
                    else if (v < pid->uMin) u=pid->uMin;
                    else u=v;
                    Es = u-v;
                    pid->Kwindup = Es/pid->Tt;
    
            }else{                 /* Modo Manual */
    
                    u = Uman;
                    pid->iState = Uman - (pid->Kp*error);       /* Bumpless transfer */
    
            }
    
            return u;
    
    }
    

  • are you sure your gains are not 0?
    if your

    iA
    

    is not updates, maybe

    if (pid->Ti)
    

    and

    if (pid->Td)
    

    are 0?
    did you try to debug this code?

  • it is OK because if i do it:

    return pid->iState;
    

    First the value is for example 10, after is 4, but should be 14.

  • but you said that your iA variable is not updated! so it is updated after all, and the problem seems to be a calculation bug of some kind. I suggest you start debugging.

  • Always Im debugging my code, i trying everythings and im seeing for webs and datasheet.
    And i dont know where is the problem. Im exasperate!!!

    Thanks.

  • I see some serious problems with your implementation.
    I think your integrator is totally wrong - you do not even accumulate the error!
    it should be something like this:

    double UpdatePID(SPid * pid, double error, double position)
    {
      double pTerm, dTerm, iTerm;
    
      pTerm = pid->pGain * error;
    
      // calculate the proportional term
      // calculate the integral state with limiting
    
      pid->iState += error;
      if (pid->iState > pid->iMax) pid->iState = pid->iMax;
      else if (pid->iState < pid->iMin)
      {
         pid->iState = pid->iMin;
         iTerm = pid->iGain * iState;
      }
    
      dTerm = pid->dGain * (position - pid->dState);
      pid->dState = position;
    
      return pTerm + iTerm - dTerm;
    }