Unicórdoba, calidad, innovación e inclusión para la transformación del territorio.
TCLAB
Control Automático de Procesos
Ingeniería de Alimentos
Universidad de Córdoba
2025
2
TCLAB: Temperature Control Lab
✓ El laboratorio de control ✓ La energía térmica
de temperatura es una generada por el
aplicación de control por calentador se transfiere
retroalimentación que al sensor de temperatura
utiliza: por conducción,
convección y radiación.
Un Arduino, un LED, dos Además, el calor también
calentadores y dos se transfiere desde el
sensores de temperatura. dispositivo hacia el
entorno.
✓ La salida de potencia de los calentadores se
ajusta para mantener un punto de ajuste de
temperatura deseado.
3
TCLAB: Temperature Control Lab
✓ Este laboratorio es una herramienta ideal para la
identificación de modelos y el desarrollo de
controladores.
✓ Es un laboratorio compacto que incluye software
en Python, MATLAB y Simulink, diseñado para
reforzar la teoría de control y beneficiar a los
estudiantes.
[Link]
4
TCLAB: Temperature Control Lab
El kit del laboratorio de control de temperatura incluye:
•Arduino (Leonardo): Microcontrolador principal para
manejar el sistema.
•PCB de control de temperatura: Una tarjeta electrónica
diseñada para gestionar los sensores y calentadores.
•Cable de alimentación USB con conector tipo barril
(20AWG): Para suministrar energía a los calentadores.
•Fuente de alimentación USB de 5V: Incluye enchufe
para EE. UU., con opciones para UE, Reino Unido y
Australia si se solicitan.
•Cable USB para conexión serial: Compatible con
computadoras MacOS, Windows, Linux y Raspberry Pi.
Es una solución completa y portátil para realizar experimentos y desarrollar controles en un entorno compacto.
[Link]
5
TCLAB: Temperature Control Lab
[Link]
6
TCLAB: Temperature Control Lab
7
TCLAB: Temperature Control Lab
Arduino Dynamic Temperature Modeling
8
TCLAB: Temperature Control Lab
Arduino Dynamic Temperature Modeling
9
TCLAB: Temperature Control Lab
Arduino Dynamic Temperature Modeling
% simulacion_temperatura.m
clc; clear all; close all; format shortg
%% Conectar al Arduino
try
Instalar antes la app:
a = arduino;
disp(a)
catch
warning('Unable to connect, user input required')
disp('Para Windows:')
disp(' Abrir administrador de dispositivos, seleccionar "Puertos (COM & LPT)"')
disp('Para MacOS:')
disp(' Abrir terminal y escribir: ls /dev/*.')
disp('Para Linux:')
disp(' Abrir terminal y escribir: ls /dev/tty*')
com_port = input('Especificar puerto (e.g. COM4 para Windows o /dev/ttyUSB0 para Linux): ','s');
a = arduino(com_port,'Uno');
disp(a)
end
%% Funciones auxiliares
v1 = @() readVoltage(a, 'A0'); % Leer voltaje sensor 1
v2 = @() readVoltage(a, 'A2'); % Leer voltaje sensor 2
TC = @(V) (V - 0.5)*100.0; % Celsius
T1C = @() TC(v1());
T2C = @() TC(v2());
led = @(level) writePWMDutyCycle(a,'D9',max(0,min(1,level))); % Control LED
h1 = @(level) writePWMDutyCycle(a,'D3',max(0,min(100,level))*0.9/100); % Calentador 1
h2 = @(level) writePWMDutyCycle(a,'D5',max(0,min(100,level))*0.5/100); % Calentador 2
% Modelo FOPDT
function Tp_fod = fopdt(Tss,dt,Tp_prev,ii,loops,level)
Kp = 0.7; tauP = 120.0; thetaP = 10;
Qss = 0; TssC = Tss - 273.15;
z = exp(-dt/tauP);
Tp_fod = (Tp_prev - TssC) * z + level(max(1,ii-thetaP-1)-Qss) * (1-z) * Kp + TssC;
end
% Modelo de balance energético
function dTdt = energy_bal(time,T,Q,alpha,Ta,U)
m = 4e-3; Cp = 500; eps = 0.9; sigma = 5.67e-8; A = 1.2e-3;
dTdt = (1.0/(m*Cp)) * (U*A*(Ta-T) + eps * sigma * A * (Ta^4 - T^4) + alpha * Q);
end
%% Simulación
Ta = 20.4 + 273.15; U = 10.0; alpha = 0.01;
time = 10; loops = time * 60;
T1 = ones(loops) * T1C(); Tp_fnd = T1; Tp_fod = T1;
error_fnd = ones(loops); error_fod = zeros(loops); Qlog = ones(loops);
figure(1)
subplot(2,1,1); hold on; grid on;
anexp = animatedline('LineStyle','-', 'Color', 'g', 'LineWidth', 2);
anpredfnd = animatedline('LineStyle','--','Color', 'b','LineWidth', 2);
anpredfod = animatedline('LineStyle','--','Color', 'r', 'LineWidth', 2);
xlabel('time (sec)'); ylabel('Temperature \circC');
legend('T_1 Measured', 'Energy Bal Pred', 'FOPDT Pred', 'Location', 'northwest');
title('Temperature Simulation');
subplot(2,1,2); hold on; grid on;
yyaxis left; anerrorfnd = animatedline('LineStyle','-', 'Color', 'b', 'LineWidth', 2);
anerrorfod = animatedline('LineStyle','-', 'Color', 'r' , 'LineWidth', 2);
xlabel('Time (sec)'); ylabel('Cumulative Error');
yyaxis right; anQ = animatedline('LineStyle','-', 'Color', 'k', 'LineWidth', 3);
ylabel('Power Level Q (%)'); xlabel('time (sec)');
legend('Energy Balance Error', 'FOPDT Error', 'Location', 'northwest');
title('Fundamental vs. FOPDT Error');
%level = ones(loops,1); level(1:9) = 0; level(10:300) = 90; level(241:end) = 0;
level = ones(loops,1); level(1:2) = 0; level(3:590) = 50; level(591:end) = 0;
start_time = clock; prev_time = start_time;
for ii = 1:loops
Q = level(ii); h1(Q); Qlog(ii) = level(ii);
pause_max = 1.0; pause_time = pause_max - etime(clock,prev_time);
pause(max(pause_time, 0.01)); t = clock; dt = etime(t,prev_time); prev_time = t;
jj = ii+1;
[tsim, Tnext_fnd] = ode45(@(tsim,x)energy_bal(tsim,x,Q,alpha,Ta,U), [0 dt], Tp_fnd(jj-1)+273.15);
Tp_fnd(jj) = Tnext_fnd(end) - 273.15;
Tnext_fod = fopdt(Ta,dt,Tp_fod(jj-1),ii,loops,level);
Tp_fod(jj) = Tnext_fod;
T1(ii) = T1C();
error_fnd(jj) = error_fnd(ii) + abs(T1(ii) - Tp_fnd(ii));
error_fod(jj) = error_fod(ii) + abs(T1(ii)-Tp_fod(ii));
addpoints(anexp,ii,T1(ii)); addpoints(anpredfnd,ii,Tp_fnd(ii));
addpoints(anpredfod,ii,Tp_fod(ii)); addpoints(anerrorfnd,ii,error_fnd(ii));
addpoints(anerrorfod,ii,error_fod(ii)); addpoints(anQ,ii,Qlog(ii));
drawnow;
end
disp(['Error acumulado de balance energético = ', num2str(error_fnd(end,1))]);
disp(['Error acumulado FOPDT = ', num2str(error_fod(end,1))]);
disp(['Valor de U = ', num2str(U)]);
level = 0; h1(level);
disp(['Calentador apagado: ', num2str(level) '%']);
if T1C() > 50
led(1);
disp(['Advertencia, temperatura del calentador = ', num2str(T1C())]);
else
led(0);
end
10
TCLAB: Temperature Control Lab
Arduino Dynamic Temperature Modeling
% simulacion_temperatura.m
clc; clear all; close all; format shortg
%% Conectar al Arduino
try
a = arduino;
disp(a)
catch
warning('Unable to connect, user input required')
disp('Para Windows:')
plot([Link],T1(:,1))
disp(' Abrir administrador de dispositivos, seleccionar "Puertos (COM & LPT)"')
disp('Para MacOS:')
disp(' Abrir terminal y escribir: ls /dev/*.')
disp('Para Linux:')
disp(' Abrir terminal y escribir: ls /dev/tty*')
com_port = input('Especificar puerto (e.g. COM4 para Windows o /dev/ttyUSB0 para Linux): ','s');
a = arduino(com_port,'Uno');
disp(a)
end
%% Funciones auxiliares
v1 = @() readVoltage(a, 'A0'); % Leer voltaje sensor 1
v2 = @() readVoltage(a, 'A2'); % Leer voltaje sensor 2
TC = @(V) (V - 0.5)*100.0; % Celsius
T1C = @() TC(v1());
T2C = @() TC(v2());
Treal=T1(:,1); plot(Times, T2, Times, Treal(1:end))
led = @(level) writePWMDutyCycle(a,'D9',max(0,min(1,level))); % Control LED
h1 = @(level) writePWMDutyCycle(a,'D3',max(0,min(100,level))*0.9/100); % Calentador 1
h2 = @(level) writePWMDutyCycle(a,'D5',max(0,min(100,level))*0.5/100); % Calentador 2
% Modelo FOPDT
function Tp_fod = fopdt(Tss,dt,Tp_prev,ii,loops,level)
Kp = 0.7; tauP = 120.0; thetaP = 10;
Qss = 0; TssC = Tss - 273.15;
z = exp(-dt/tauP);
Tp_fod = (Tp_prev - TssC) * z + level(max(1,ii-thetaP-1)-Qss) * (1-z) * Kp + TssC;
end
% Modelo de balance energético
function dTdt = energy_bal(time,T,Q,alpha,Ta,U)
m = 4e-3; Cp = 500; eps = 0.9; sigma = 5.67e-8; A = 1.2e-3;
dTdt = (1.0/(m*Cp)) * (U*A*(Ta-T) + eps * sigma * A * (Ta^4 - T^4) + alpha * Q);
end
%% Simulación
Ta = 20.4 + 273.15; U = 10.0; alpha = 0.01;
time = 10; loops = time * 60;
T1 = ones(loops) * T1C(); Tp_fnd = T1; Tp_fod = T1;
error_fnd = ones(loops); error_fod = zeros(loops); Qlog = ones(loops);
figure(1)
subplot(2,1,1); hold on; grid on;
anexp = animatedline('LineStyle','-', 'Color', 'g', 'LineWidth', 2);
anpredfnd = animatedline('LineStyle','--','Color', 'b','LineWidth', 2);
anpredfod = animatedline('LineStyle','--','Color', 'r', 'LineWidth', 2);
xlabel('time (sec)'); ylabel('Temperature \circC');
legend('T_1 Measured', 'Energy Bal Pred', 'FOPDT Pred', 'Location', 'northwest');
title('Temperature Simulation');
subplot(2,1,2); hold on; grid on;
yyaxis left; anerrorfnd = animatedline('LineStyle','-', 'Color', 'b', 'LineWidth', 2);
anerrorfod = animatedline('LineStyle','-', 'Color', 'r' , 'LineWidth', 2);
xlabel('Time (sec)'); ylabel('Cumulative Error');
yyaxis right; anQ = animatedline('LineStyle','-', 'Color', 'k', 'LineWidth', 3);
ylabel('Power Level Q (%)'); xlabel('time (sec)');
legend('Energy Balance Error', 'FOPDT Error', 'Location', 'northwest');
title('Fundamental vs. FOPDT Error');
%level = ones(loops,1); level(1:9) = 0; level(10:300) = 90; level(241:end) = 0;
level = ones(loops,1); level(1:2) = 0; level(3:590) = 50; level(591:end) = 0;
start_time = clock; prev_time = start_time;
for ii = 1:loops
Q = level(ii); h1(Q); Qlog(ii) = level(ii);
pause_max = 1.0; pause_time = pause_max - etime(clock,prev_time);
pause(max(pause_time, 0.01)); t = clock; dt = etime(t,prev_time); prev_time = t;
jj = ii+1;
[tsim, Tnext_fnd] = ode45(@(tsim,x)energy_bal(tsim,x,Q,alpha,Ta,U), [0 dt], Tp_fnd(jj-1)+273.15);
Tp_fnd(jj) = Tnext_fnd(end) - 273.15;
Tnext_fod = fopdt(Ta,dt,Tp_fod(jj-1),ii,loops,level);
Tp_fod(jj) = Tnext_fod;
T1(ii) = T1C();
error_fnd(jj) = error_fnd(ii) + abs(T1(ii) - Tp_fnd(ii));
error_fod(jj) = error_fod(ii) + abs(T1(ii)-Tp_fod(ii));
addpoints(anexp,ii,T1(ii)); addpoints(anpredfnd,ii,Tp_fnd(ii));
addpoints(anpredfod,ii,Tp_fod(ii)); addpoints(anerrorfnd,ii,error_fnd(ii));
addpoints(anerrorfod,ii,error_fod(ii)); addpoints(anQ,ii,Qlog(ii));
drawnow;
end
disp(['Error acumulado de balance energético = ', num2str(error_fnd(end,1))]);
disp(['Error acumulado FOPDT = ', num2str(error_fod(end,1))]);
disp(['Valor de U = ', num2str(U)]);
level = 0; h1(level);
disp(['Calentador apagado: ', num2str(level) '%']);
if T1C() > 50
led(1);
disp(['Advertencia, temperatura del calentador = ', num2str(T1C())]);
else
led(0);
end
11
TCLAB: Temperature Control Lab
SIMULADOR ONLINE
[Link]
12
Bibliografía
•APMonitor. (n.d.). Arduino Temperature Control. Recuperado el 27
de abril de 2025, de APMonitor.
•Columbia University. (n.d.). TCLab: Technological Change Lab.
Recuperado el 27 de abril de 2025, de Columbia University.
•Marín Castillo, C. A. (2021). Modelado y control de temperatura
para sistema multivariable GPC sobre plataforma TCLAB Arduino.
Recuperado el 27 de abril de 2025, de UPC Commons.
13