Buenos días , estoy realizando un proyecto para controlar la apertura y cierre de una válvula , para ello utilizo un motor DC de 12 V , la posición de la válvula estará determinada por un potenciómetro.
Para controlar el motor estoy utilizando además de Arduino un motor driver basado en el L98P ( Ardumoto driver).
Necesito que una vez lea la posición actual del potenciómetro el motor se mueva hasta dicha posición y mediante un control PID vaya situandose hasta la posición requerida por el potenciómetro para finalmente terminar parándose.
En el código actual solo consigo variar la velocidad del motor con el potenciómetro , pero estoy lejos de lo que se desea .
Adjunto copia del código :
#include <PID_v1.h>
#define CW 0 // para definir sentido hacia un lado
#define CCW 1 //para definir sentido hacia otro lado
//Variables Driver
int DIRB=13; //controla direccion motor B
int PWMB=11; //enable controla velocidad motor B
//PARÁMETROS DE LA LIBRERÍA PID
double Setpoint, Input, Output;
//aquí pongo los valores del PID
PID myPID(&Input, &Output, &Setpoint,2.8,0.04,0, DIRECT);//Valores dados por el proyecto
double min, max;
int aux;
int err;
//Tiempo de muestreo
unsigned int tiempomuestreo=200;
//variable para el tiempo
unsigned long tiempoanterior=0;
int mapeado;
//Esta parte del código sólo se ejecuta al iniciar el Arduino
void setup()
{
Input = analogRead(1); //este es el potenciómetro
//Velocidad de comunicacion serie en baudios
Serial.begin(9600);
//Pongo el PID en modo automatico para que calcule la salida
myPID.SetMode(AUTOMATIC);
//Defino estos pines como salida
pinMode(11, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(PWMB, HIGH);
//Ciclo de trabajo. Varia entre 0 y 255. Subir para aumentar
//la potencia de la valvula
myPID.SetSampleTime(tiempomuestreo);
//defino los limites de la salida
myPID.SetOutputLimits(-255,255);
//Este es el orden en el que aparecen las variables por el
//puerto serie
//Serial.print("Referencia");
}
//Esta parte se ejecuta en bucle
void loop()
{
//bucle en el que estara hasta que sea el momento de
//ejecutar el algoritmo
unsigned long ahora = millis();
int tiempopasado = (ahora-tiempoanterior);
// while(tiempopasado<tiempomuestreo)
//{
ahora=millis();
tiempopasado=(ahora-tiempoanterior);
//}
tiempoanterior=millis();
//se pone ahora porque así no tengo que preocuparme por el
//tiempo de cómputo del resto del código y siempre será el
//tiempo indicado en tiempomuestreo
//Mapeo de la salida. Los valores de la salida aun asi //pueden variar algunas unidades, por eso despues se
//definen limites
//mapeado=map(salida,189,937,0,1023);
//if(mapeado<0)mapeado=0;
// if(mapeado>1023)mapeado=1023;
mapeado=500;//PARA REALIZAR LA PRUEBA
Setpoint = mapeado;
//Potenciometro "sensor"conectado a la entrada analógica 1
Input = analogRead(1);
// Serial.print(Setpoint);
//Serial.print (";");
Serial.print(Input);
//err=(Setpoint-Input);
myPID.SetMode(AUTOMATIC);
//Calcula la salida del PID
myPID.Compute();
if(Output>0) //la válvula se abre
{
//Si está dentro de 1000 el valor de apertura, ejecuta //el PID
if(Input<1000)
{
aux=abs(Output);
analogWrite(PWMB,aux);
analogWrite(DIRB,CW);
Serial.print(",");
Serial.print(aux);
}
//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;
Serial.print(",");
Serial.print(aux);
digitalWrite(PWMB,LOW);
}
}
else //la válvula se cierra
{
if (Input>50)
{
aux=abs(Output);
analogWrite(PWMB, aux);
analogWrite(DIRB,CCW);
Serial.print(",");
Serial.print(aux);
}
else
{
myPID.SetMode(MANUAL);
Output=0;
Serial.print(",");
Serial.print(aux);
digitalWrite(PWMB,LOW);
}
}