/********************************************************
Teoría de Control - K4571 - 2C2023
Proyecto Grupal - Impresora 3D
Franco Cingolani - Bladimir Parihuancollo
********************************************************/
// Este proyecto simula un bloque calentador que recibe una corriente para llevarlo a una temperatura nominal/referencial
// Se utiliza una librería con un contorlador PID
// De lado derecho hay un potenciómetro donde se setea el valor nominal de la temperatura del bloque a la cual se quiere llegar
// De lado izquierdo hay un sensor de temperatura que toma los valores de temperatura del bloque calentador y su perturbación y lo envía al controlador PID para su ajuste
// En el medio hay un potenciómetro para simular perturbaciones en la temperatura mediante una corriente de aire.
// Para que los efectos de la perturbación sean más notorios que la realidad, se elige sobredimensionar los valores para que pueda disminuir la temperatura hasta 50ºC.
#include "PID_v1.h" // https://github.com/br3ttb/Arduino-PID-Library
double v_referencial, perturbacion, InputPID, voltaje;
//Se especifican los valores del controlador PID
double Kp = 25, Ki = 1, Kd = 4;
PID myPID(&InputPID, &voltaje, &v_referencial, Kp, Ki, Kd, P_ON_E, DIRECT);
//Seteo de constantes de pines analógicas
const int PERTURBACION_PIN = A0; // Analog pin para potenciómetro de perturbación
const int V_REFERENCIAL_PIN = A1; // Analog pin para potenciómetro de valor referencial
const int SENS_TEMP_PIN = A2; //Analog pin para sensor de temperatura
void setup()
{
Serial.begin(115200);
pinMode(A0, INPUT);
myPID.SetOutputLimits(0, 255);
v_referencial = 0;
perturbacion = 0;
myPID.SetMode(AUTOMATIC);
InputPID = simBloqueCalentador(0.0,1.0, 0.0); // simular calentamiento inicial
}
void loop()
{
float calentador = (int)voltaje * 20.0 / 255; // calentador de 20v
if (myPID.Compute())
{
v_referencial = analogRead(V_REFERENCIAL_PIN) / 4; // lee valor de temperatura referencial
float bloqueTemp = simBloqueCalentador(calentador,voltaje>0?1.0:1-voltaje, perturbacion); // simular calentamiento
float tempConPerturbacion = simPerturbacion(bloqueTemp); //simular perturbación
float temperaturaSensada = sensorTemperatura(tempConPerturbacion); //simular sensor de temperatura
InputPID = temperaturaSensada; // Asigno al input del PID el valor de la temperatura obtenida por el sensor
}
report(calentador);
}
//Reporte por pantalla por cada intervalo
void report(float calentador)
{
static uint32_t last = 0;
const int interval = 1000;
if (millis() - last > interval) {
last += interval;
Serial.print("Valor_Referencial: ");
Serial.print(v_referencial);
Serial.print("ºC");
Serial.print(" // ");
Serial.print(" Temperatura: ");
Serial.print(InputPID);
Serial.print("ºC");
Serial.print(" // ");
Serial.print("Perturbación: ");
Serial.print(perturbacion);
Serial.print("ºC");
Serial.print(" // ");
Serial.print("Voltaje: ");
Serial.print(calentador);
Serial.print("v");
Serial.println();
}
}
float simBloqueCalentador(float voltaje,float hfactor, float perturbacion) {
//Simula un bloque de aluminio de 1x1x2 cm, con una resistencia calentadora y enfriamiento pasivo por ambiente
//Se setea la temperatura ambiente a 25ºC
float h = 5 *hfactor ; // Coeficiente térmico de convección para enfriamiento pasivo
float Cps = 0.89; // J/g°C
float area = 1e-4; // Área de convección
float masa = 10 ; // g
float Tamb = 25; // °C
static float T = Tamb; // °C
static uint32_t last = 0;
uint32_t interval = 100; // ms
if (millis() - last >= interval) {
last += interval;
T = T + voltaje * interval / 1000 / masa / Cps - (T - Tamb) * area * h;
}
return T;
}
float simPerturbacion(float T){
perturbacion = map(analogRead(PERTURBACION_PIN), 25, 1024, 1, 51); // Lee valor del potenciómetro de perturbación, con mapeo de 0 a 50ºC
int parteEntera = (int)T; // Obtener la parte entera
float parteDecimal = T - parteEntera; // Obtener los decimales
//Antes de devolver la temperatura, verifica si con la perturbación no queda valor negativo
if(T-perturbacion < 0){
return 0;
}else{
return (T-perturbacion) + parteDecimal;
}
}
float sensorTemperatura(float T){
int parteEntera = (int)T; // Obtener la parte entera
float parteDecimal = T - parteEntera; // Obtener los decimales
return map(analogRead(SENS_TEMP_PIN), 953, 115, T, T) + parteDecimal;
}
255°
0°
Sensor de temperatura
Simulación Impresora 3D control PID temperatura
Temperatura valor nominal
Perturbación