Hola a todos, estoy con problemas al utilizar la librería PID con salida a relay.
El proyecto es un sistema de control de calefacción de un vehículo el cual tiene una válvula ON/OFF que deja circular el agua. La temperatura es obtenida por un sensor DS18B20, la temperatura de referencia se modifica mediante 2 interrupciones y cuando se modifica se almacena en la eeprom para que no se pierda el valor cuando se apague el vehículo.
Todo eso trabaja bien, el problema es que el relay siempre queda encendido y solo en un ciclo después de muchos se apaga y se enciende al tiro. he revisado y no logro encontrar el problema. les dejo el código.
Muchas gracias por su tiempo y ayuda!!
/********************************************************
#include <PID_v1.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h> // F Malpartida's NewLiquidCrystal library
#include <EEPROM.h>
/*-----( Declare Constants )-----*/
#define I2C_ADDR 0x27 // Direccion I2C para PCF8574A que es el que lleva nuestra placa diseñada por MJKDZ
//definimos las constantes para esta placa
#define LED_OFF 0
#define LED_ON 1
//mjkdz i2c LCD board
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// Pin donde se conecta el bus 1-Wire
const int pinDatosDQ = 9;
// Instancia a las clases OneWire y DallasTemperature
OneWire oneWireObjeto(pinDatosDQ);
DallasTemperature sensorDS18B20(&oneWireObjeto);
float temp;
int calpin = 13;
volatile int tref;
volatile long t0 = 0;
boolean flag = false;
// necesario para guardar t en eeprom
int Direccion = 0;
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
double Kp = 2, Ki = 0.1, Kd = 0.05;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
int WindowSize = 5000;
unsigned long windowStartTime;
int relay;
void setup()
{
// put your setup code here, to run once:
// Iniciamos la comunicación serie
Serial.begin(9600);
// Iniciamos el bus 1-Wire
sensorDS18B20.begin();
pinMode(calpin, OUTPUT);
lcd.begin (16, 2);
lcd.setBacklight(LED_ON);
lcd.clear();
tref = EEPROM.read(Direccion);
delay(100);
pinMode(2, INPUT);
pinMode(3, INPUT);
attachInterrupt( 0, distemp, LOW);
attachInterrupt( 1, aumtemp, LOW);
windowStartTime = millis();
//initialize the variables we're linked to
Setpoint = tref;
//tell the PID to range between 0 and the full window size
myPID.SetOutputLimits(0, WindowSize);
//turn the PID on
myPID.SetMode(AUTOMATIC);
delay(1500);
}
void loop()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T SET");
lcd.setCursor(6, 0);
lcd.print(tref);
lcd.setCursor(0, 1);
lcd.print("TEMP");
lcd.setCursor(6, 1);
lcd.print(temp);
if (relay == 1) {
lcd.setCursor(12, 0);
lcd.print("ON ");
} else {
lcd.setCursor(12, 0);
lcd.print("OFF");
}
Serial.print("Temp refe: ");
Serial.println(tref);
Serial.print("Temp medida: ");
Serial.println(temp);
Serial.print("Flag: ");
Serial.println(flag);
Serial.print("Relay: ");
Serial.println(relay);
Serial.println("otro ciclo");
Serial.println("");
if (flag == true) {
EEPROM.write(Direccion, tref);
flag = false;
delay(10);
}
sensorDS18B20.requestTemperatures();
temp = (sensorDS18B20.getTempCByIndex(0));
delay(100);
Input = temp;
myPID.Compute();
/************************************************
turn the output pin on/off based on pid output
************************************************/
if (millis() - windowStartTime > WindowSize)
{ //time to shift the Relay Window
windowStartTime += WindowSize;
}
if (Output < millis() - windowStartTime) {
digitalWrite(calpin, HIGH);
relay = 1;
}
else {
digitalWrite(calpin, LOW);
relay = 0;
}
}
void distemp()
{
if ( millis() > t0 + 200)
{ tref-- ;
flag = true;
t0 = millis();
}
}
void aumtemp()
{
if ( millis() > t0 + 200)
{ tref++ ;
flag = true;
t0 = millis();
}
}