Problemas control PID Arduino

#1
Buenas , estoy realizando el control de apertura y cierre de una válvula(con un motor de 12V DC) , para controlar la cantidad de líquido en el depósito tengo conectado un potenciómetro multiuelta a una boya , de manera que cuando el líquido suba , el potenciómetro se mueva . El programa me funciona correctamente cuando se trata de valores máximos y mínimos , es decir el motor gira en la dirección correcta para abrir o cerrar la válvula hasta que el potenciómetro alcanza los valores máximos y mínimos.
Mi problema es que no soy capaz de establecer un cierto valor ( un valor entre el máximo y el mínimo) y la válvula se abra o se cierre hasta dicho punto sin llegar a los límites mencionados .

Estoy utilizando la libreria PID de Arduino , el driver que estoy utilizando para mover el motor es Ardumoto(basado en el L298P) . adjunto el trozo de código en el que no consigo realizar esto :

if(Output>0) //la válvula se abre
{

//AQUI PUEDES DAR VALORES A INPUT

//Si está dentro de 1000 el valor de apertura, ejecuta el PID . 1000 es el valor máximo superior para abrir la válvula
if(Input<1000)
{
aux=abs(Output);
driveArdumoto(MOTOR_B, FORWARD, aux); //función del driver , utilizando el motor_b , hacia la direccion derecha y a una velocidad marcada (-255,255)



}
//Si se pasa de 1000 al abrir, la válvula se para y
//manda un 0 a la salida
else
{
myPID.SetMode(MANUAL);
Output=0;
stopArdumoto(MOTOR_B);//Funcion para parar el motor b




}

//Función para mover el motor

void driveArdumoto(byte motor, byte dir, byte spd)
{
if (motor == MOTOR_B)
{
digitalWrite(DIRB, dir);
analogWrite(PWMB, spd);
}
}
 
#2
Con solo leer los comentarios del codigo, y sabiendo que en la variable "Input" tienes el valor, ya tienes todo hecho.
Quizas usar un switch-case para valores predeterminado, o comparar con alguna entrada analogico (potenciometro en alguna de las entradas de ADC), y asi establecer el maximo y minimo segun "seteas" externamente.
 
#3
Con solo leer los comentarios del codigo, y sabiendo que en la variable "Input" tienes el valor, ya tienes todo hecho.
Quizas usar un switch-case para valores predeterminado, o comparar con alguna entrada analogico (potenciometro en alguna de las entradas de ADC), y asi establecer el maximo y minimo segun "seteas" externamente.
No he entendido muy bien lo que has querido decirme , debido a que no llevo mucho manejando esto .
En la variable Input tengo guardado el valor del potenciómetro , que esta conectado a una boya , por lo que irá girando hasta llegar al valor deseado .
Utilizo una variable denominada Setpoint= mapeado , en la que guardo el valor obtenido en la función map.
Supongo que necesito conseguir una estructura que lea la variable Setpoint y la compare con la variable Input , y cuando ésta última llegue al Setpoint el motor se pare . ¿ Podrían ir por ahí los tiros ?
Gracias por tu respuesta
 
#4
Si.
Por ejemplo
Podrias "mapear" ambos potenciometros, y que los resultados sean de 0% (vacio, o valor minimo) a 100% (lleno, o valor maximo).
Entonces comparas ambos resultados.
Otra cosa es ponerle margenes al potenciometro de ajuste externo, para que no haya un "rebote" apenas baje un poco el nivel (a menos que asi lo desees), ya que lo ideal seria algo asi.
Con valor minimo, empieza el llenado.
Suponiendl que el ajuste del nivel está en 35%.
Entonces al llegar a 35% para el llenado, y apaga todo.
Si baja, por ejemplo, a 30%, vuelve activar hasta los 35% seteados.

Eso me parece a mi, porque sino, apenas baje a 34%, se vuelve activar, y si la descarga es rapida estarias activando y desactivando el motor constantemente.

Los valores en porcentaje son a modo de ejemplo, luego lo adaptas a tus necesidades
 
#5
Si.
Por ejemplo
Podrias "mapear" ambos potenciometros, y que los resultados sean de 0% (vacio, o valor minimo) a 100% (lleno, o valor maximo).
Entonces comparas ambos resultados.
Otra cosa es ponerle margenes al potenciometro de ajuste externo, para que no haya un "rebote" apenas baje un poco el nivel (a menos que asi lo desees), ya que lo ideal seria algo asi.
Con valor minimo, empieza el llenado.
Suponiendl que el ajuste del nivel está en 35%.
Entonces al llegar a 35% para el llenado, y apaga todo.
Si baja, por ejemplo, a 30%, vuelve activar hasta los 35% seteados.

Eso me parece a mi, porque sino, apenas baje a 34%, se vuelve activar, y si la descarga es rapida estarias activando y desactivando el motor constantemente.

Los valores en porcentaje son a modo de ejemplo, luego lo adaptas a tus necesidades
Ya te he entendido . El problema es que solo estoy utilizando un motor de corriente continua para abrir y cerrar la válvula y un potenciómetro que conectado a la boya marcará la posición actual del agua . Esto me funciona perfectamente para poder parar cuando el agua llega al punto máximo y al punto mínimo .
Para poder realizar esto que te comenté , ¿ Sería necesario contar con otro potenciómetro o componente para poder comparar ambas señales no ? No es posible realizarlo únicamente con estos dos componentes .
 

DOSMETROS

High 2m Modereitor
#6
El control PID (Proporcional - Integral y Derivativo) es un poco mas complejo , por ahora eso sólo funciona por si o por no abriendo y cerrando totalmente la válvula , deberías agregar la parte Proporcional , o sea 100% abierta para tanque vacío , 80 % abierta para 20% de tanque , 50% abierta para 50% de tanque , 20 % abierta para 80 % de tanque y 0% abierta para tanque lleno (con todos sus pasos intermedios)

. . . Luego verás lo Integral y Derivativo . . .
 

Dr. Zoidberg

Well-known-Papá Pitufo
#7
El control PID (Proporcional - Integral y Derivativo) es un poco mas complejo , por ahora eso sólo funciona por si o por no abriendo y cerrando totalmente la válvula , deberías agregar la parte Proporcional , o sea 100% abierta para tanque vacío , 80 % abierta para 20% de tanque , 50% abierta para 50% de tanque , 20 % abierta para 80 % de tanque y 0% abierta para tanque lleno (con todos sus pasos intermedios)
. . . Luego verás lo Integral y Derivativo . . .
Para ponerlo mas claro:
Lo que está haciendo (bah, pretendiendo hacer en realidad) es un mísero control ON/OFF. Eso de PID no tiene absolutamente NADA.
Mi recomendación sería: flaco, agarrá un libro de control, estudiá y luego seguimos hablando de los PID..
 
#8
Para ponerlo mas claro:
Lo que está haciendo (bah, pretendiendo hacer en realidad) es un mísero control ON/OFF. Eso de PID no tiene absolutamente NADA.
Mi recomendación sería: flaco, agarrá un libro de control, estudiá y luego seguimos hablando de los PID..
Obviamente el código compartido es en el que se realiza la apertura y cierre de la válvula y en el que solo busco que se detenga en un punto predeterminado que yo elija ( ahí el problema de mi programación) . La parte de código en la que configuro el PID con los valores ideales para la planta que estoy utilizando no está copiado , pues estoy casi seguro que esta programado correctamente .
Ojalá nacer aprendido como usted .
saludos .
 
#9
No es posible realizarlo únicamente con estos dos componentes
Si, pero solo tendras maximo y minimo, o como dicen los colegas "ON-OFF".
Si quieres control total del volumen deseado, entonces haz lo que dice 2ME, o como te sugeri yo mas arriba.

Si quieres mas complejo, hasta le puedes poner una pantalla LCD que muestre el porcentanje, y pulsadores para setear los valores, hasta puedes setear el maximo y el minimo segun requieras
 

Dr. Zoidberg

Well-known-Papá Pitufo
#10
La parte de código en la que configuro el PID con los valores ideales para la planta que estoy utilizando no está copiado , pues estoy casi seguro que esta programado correctamente .
Entonces por que pones de titulo del tema "Problema control PID Arduino" si el problema es de otra cosa????
Y mostras un codigo que no tiene NADA que ver con lo que dice titulo... supones que nosotros tenemos que adivinar lo que te sucede???
No es cuestión de nacer aprendido sino de tratar de ser coherente.
 
#11
Lo primero que debes plantearte mas alla de lo que te han dicho es que los que estamos del otro lado no sabemos que sabes y que no. Basamos nuestros comentarios en lo que expones.
Lo que expones es al menos muy liviano.
Se supone que debes entregar la mayor cantidad de información posible.. porque nosotros no hemos visto tu boya (como la nombras), no sabemos si tu boya o sensor potenciométrico se comporta linealmente con el nivel de líquido o no.
Has probado si esto es asi?. Se te ocurrio medir desde 0 y leer la salida del potenciometro... y luego tomar digamos 10 lecturas de nivel hasta completar el 100% y hacer una curva de como es la transferencia?
De lo contrario una cosa es creer que tienes algo lineal y otra es que no lo sea.

Ahora mira el código que has puesto, lo he identado para que se entienda (al menos a mi me hace falta)
Observa que es parcial, y no solo parcial sino que empieza y no sabemos si termina o no ya que lo primero no tiene llave de fin, pero luego hay otro procedimiento como driveArdumoto que esta claramente definido.



Código:
 // <= ACA NO SABEMOS DE DONDE VIENE
  if (Output>0) { //la válvula se abre
    //AQUI PUEDES DAR VALORES A INPUT

    //Si está dentro de 1000 el valor de apertura, ejecuta el PID . 1000 es el valor máximo superior para abrir la válvula
    if (Input<1000)   {
      aux=abs(Output);
      driveArdumoto(MOTOR_B, FORWARD, aux); //función del driver , utilizando el motor_b , hacia la direccion derecha y a una velocidad marcada (-255,255)
    }

    //Si se pasa de 1000 al abrir, la válvula se para y
    //manda un 0 a la salida
    else     {
      myPID.SetMode(MANUAL);
      Output = 0;
      stopArdumoto(MOTOR_B);//Funcion para parar el motor b
    }

  //Función para mover el motor
// <= ACA NO SABEMOS SI TERMINA ALGO?

void driveArdumoto(byte motor, byte dir, byte spd)  {
  if (motor == MOTOR_B)  {
      digitalWrite(DIRB, dir);
      analogWrite(PWMB, spd);
  }
}
Asi que tienes algunas directivas para trabajar que espero te sirvan y recuerda.
Aporta toda la información, código completo, esquema de conexiones aunque sea obvio (un bosquejo mano alzada sirve).
 
Última edición:

Arriba