Hola, necesito hacer un controlador PID de presión, estoy intentando usar la librería "PID_v1.h", pero no la estoy entendiendo muy bien, la idea es que usando este controlador el Arduino mida la presión a través de un sensor de presión y abra o cierre una válvula (conectada a un relé) manteniendo la presión constante, pero no lo estoy logrando, no entiendo muy bien como usar la librería, la idea del código es poder cambiar el setpoint en cualquier momento a través de un teclado numérico conectado al Arduino y que esto se muestre en una pantalla LCD, esa parte funciona bien, pero el control PID no esta funcionando, ya que, independientemente de el setpoint, el output de la función intercala entre 0 y 1, no comprendo porque
#include <PID_v1.h>
#include <Key.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'},
};
byte rowPins[ROWS] = { 11, 10, 9, 8 }; //connect to the row pinouts of the keypad
byte colPins[COLS] = { 7, 6, 5, 4 }; //connect to the column pinouts of the keypad
float SPA = 5.00;
float N_SPA = 0.0;
int N_SPAint = 0;
int N_SPAdec = 0;
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
char key;
int dato;
double setpoint = 5.00;
double input, output;
double Kp = 1, Ki = 0.1, Kd = 0.01;
PID myPID(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);
int relayPin = 26;
int sensorPin = A0;
void setup()
{
Serial.begin(9600);
pinMode(relayPin, OUTPUT);
pinMode(sensorPin, INPUT);
pinMode(13,OUTPUT);
digitalWrite(13,LOW);
lcd.init();
lcd.backlight();
myPID.SetMode(AUTOMATIC);
}
void loop()
{
N_SPA = 0.0; // Nuevo Setpoint
N_SPAint = 0; //Parte entera del nuevo Setpoint
N_SPAdec = 0; //Parte decimal del nuevo Setpoint
ControladorPID_A(); //Llamamos al controlador PID
lcd.setCursor(0,0);
lcd.print("Contorlador A");
lcd.setCursor(0,1);
lcd.print("Setpoint: " + String(SPA) + " bares");
lcd.setCursor(0,2);
lcd.print("Presion: " + String(2.5) + " bares" );
key = keypad.getKey();
if (key)
{
if(key == 'A')
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Introducir nuevo Setpoint:");
int car = 0; //definimos el entero car que corresponde a la cantidad de caracteres que se han ingresado del nuevo Setpoint
while(car != 4) // el Setpoint siempre tendra 4 caracteres 2 enteros y 2 decimales
{
key = Controladores_PID_r(); //llamamos a la funcion recursiva del controlador PID
if(isdigit(key))
{
key -= 48; //Convertimos el char key en un int
if(car >= 2) // Esta es la parte decimal del nuevo Setpoint, lo hice así para poder ponerlo digito por digito en la LCD
{
N_SPAdec = N_SPAdec*10 + key; //Multiplica el valor anterior de N_SPAdec por 10 y le suma la nueva entrada
digitalWrite(13,HIGH);
lcd.setCursor(0,3);
lcd.print(String(N_SPAint) + "." + String(N_SPAdec));
car += 1;
}
else
{
N_SPAint = N_SPAint*10 + key; //Multiplica el valor anterior de N_SPAint por 10 y le suma la nueva entrada
digitalWrite(13,HIGH);
lcd.setCursor(0,3);
lcd.print(N_SPAint);
car += 1;
}
}
}
N_SPA = N_SPAint + N_SPAdec*0.01; //Guardamos el nuevo Setpoint
if(N_SPA < 13.00) //Comprobamos que no exceda el maximo
{
SPA = N_SPA;
lcd.setCursor(0,3);
lcd.print(SPA);
Controladores_PID();
delay(1000);
lcd.clear();
}
else
{
lcd.setCursor(0,3);
lcd.print("Valor excede el maximo");
Controladores_PID();
delay(1000);
lcd.clear();
}
}
}
}
void ControladorPID_A() //Definimos una funcion que Haga el control PID
{
setpoint = SPA;
input = random(0, 14); //como aun no tengo el sensor de presión estoy haciendo pruebas con un numero aleatorio entre 0 y 13
output = myPID.Compute();
if (output > 0) // Si el output del PID es positivo, abrimos la valvula (aumentando la presión)
{
digitalWrite(relayPin, HIGH);
}
else // Si el output del PID es negativo, cerramos la valvula y deisminuimos la presion
{
digitalWrite(relayPin, LOW);
}
}
char Controladores_PID_r() //Definimos una funcion recursiva para que este midiendo la presion hasta que se presione un tecla en el teclado
{ ControladorPID_A();
key = keypad.getKey();
if (key)
{
return key;
}
else
{
return Controladores_PID_r();
}
}
Como aun no tengo el sensor de presión estoy usando un numero aleatorio entre 0 y 13 para hacer las pruebas.
Gracias de antemano