Hacer un PID discreto

Hola a todos!! Estoy un poco atascado en un pequeño rastreador y necesito programar un controlador PID. El caso es que no se cómo programarlo para sistemas discretos, expongo mi caso.
Tengo el robot que debe seguir la línea negra, pero es muy inestable y va oscilando sobre la linea negra, y a veces se sale. Para ello tengo 8 sensores que se encargan de detectar la línea negra y dan errores -3,-2,-1,0,0,1,2,3 respectivamente. Actualmente lo controlo por medio de un switch en función del error que detecte y pongo los motores en una configuración determinada. Ahora me gustaría implementar un PID, para que apenas oscile sobre la línea negra.
Lo que sé hasta ahora es programar el controlador PD de la siguiente forma:
U=Kperror_actual + Kd(error_actual-error_anterior)
Donde U sería la señal de control que hay que sumar a 'bias', siendo 'bias' la señal inicial de los motores.
El problema es que no se cómo implementar la parte integral, para hacer el control.

Lo que describes sobre el PID lo conocemos todos.
Sería un poco mas apropiado que nos indiques algo mas acerca de los sensores.
No entiendo la secuencia de errores que mencionas -3,-2,-1,0,0,1,2,3
De todas formas solo requieres la librería PID.h y mirar un ejemplo y ya puedes disponer de ella.

Arduino PID Library

Buenas, me gustaría hacer el PID por mí mismo, para poderlo adaptar a otros micros que no tengan librería de PID:)
Explico lo de los errores.
Los 8 sensores realizan una lectura y cada sensor está asociado a un error de forma que si la línea está centrada debajo del rastreador el error es 0, si está un poco a la derecha el error es 1, si está más a la derecha el error es 2 y si está muy a la derecha el error es 3. Los errores positivos indican que el rastreador debe girar a la derecha. Lo mismo para los errores negativos. Cuanto más grande sea el error, más alejada está la línea del centro del rastreador. El signo indica el lado hacia el que hay que girar.
Espero haberme explicado mejor :slight_smile:

Otros micros? No comprendo estas en el foro Arduino, no hay otros micros en este foro.
Pero bueno si quieres hacerla nadie te lo impide.
De todas formas es una rutina en C, porteable a cualquier micro, tomas la librería y la usas a tu gusto.

No veo tu código para decirte o sugerirte algo.

Busca en este foro : PID y encontrarás librerías y códigos hechos por los foristas.

Este es un enlace que explica bastante bien el tema usando arduino

Este es un posible ejemplo de como acerlo enlace

Si encuentro algo mejor lo posteo acá pero solo busca en google o en este foro.

Este es un muy buen código, complejo por su contexto pero tiene bien implementado el PID

Muchas gracias por la información, me ha sido realmente útil.
He estado mirándola y tratando de implementar mi PID. Por último me gustaría que le echaras un vistacillo a ver si está ok! :slight_smile:
El programa finalmente devuelve el valor de Uc, que sería el valor que calcula el controlador y que es sumado a BIAS en el programa principal

Un saludo

PID.ino (477 Bytes)

He puesto dos comentarios o sugerencias en tu rutina PID

float PID(float Kp, float Ki, float Kd, int error){
  
  float P=0,
        I=0,
        D=0;
        
  float Uc, Kz;  //Señal de control
  unsigned long T;
  
  T = millis() - ultimo_T;  
  
  Kz = T/1000.00;
  error_acum += error;
  
  P = Kp * error;
  I = Ki* ((error_acum + error) / Kz) ;
  D = Kd * Kz * (error - ultimo_error);    // VER: ultimo_error no figura como se calcula
  
  Uc= P + I + D;  
  Serial.println(P);
  Serial.println(I);
  Serial.println(D);
  Serial.println(Uc);
  ultimo_T = millis();                             // VER: creo que ultimo_T debería ir acá.
  return(Uc);
  }

Vale, ultimo_error se actualiza en la rutina principal, al final del todo con la sentencia:

ultimo_error=error;

Por lo demás está bien implementado el PID no??

Muchas gracias por tus comentarios y ayuda!!!! :):slight_smile: