-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathP311_ziegler_nichols.m
120 lines (91 loc) · 4.27 KB
/
P311_ziegler_nichols.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
function [y,u,t,K] = P311_ziegler_nichols(a,N,dT,p,bv,K,TI,TD,saveFile)
% ******* PART A: Description of the different variables *******
% output values:
% - y: vector containing level values
% - u: vector containing signal values
% - t: vector containing 't' samples (timepoints)
% argument values:
% - a: arduino-object, accessed with: a = arduino_com('COMxx')
% - N: total samples
% - dT: samplingtime in seconds
% - p: inputsignal (tank1 or tank2)
% - m: signal strength (0-255) given in procent (0..100%)
% - bv: desired level for the regulation given in procent (0..100%)
% - K: ...
% - TI: ...
% - TD: ...
% ***************************************************************
H1Max=740; % Max level-value for tank 1
H2Max=745; % Max level-value for tank 2
% ******* PART B: Initialization of inputs and outputs and internal variables *******
% Calculate desired-level in absolute numbers
r=(bv*H2Max/100)*ones(1,N); % skapar vektor med r i en rad med N element
% *******************************************************************************
% *** PART C: Create and initialize different variables to save measurement results ***
y = zeros(1, N); % vector with N nulls on a (1) row to be filled with measurements of the level in water tank 1 and 2
e = zeros(1, N); % vector with N nulls on a (1) row to be filled with calculations of the error value e
w = zeros(1, N);
u = zeros(1, N); % vector to be filled with calculations of the signal u
t = (1:N)*dT; % vector currently as a numbering of times from 1 to N times sampling time
ok=0; % used to detect too short sampling time
% *************************************************************************************
% if you want to get rid of strange values in the beginning
% make a "read analog" before the loop of analog inputs:
a.analogRead(p);
% ******* PART D: start regulating *******
for k=1:N % the loop will run N times, each time takes exactly dT seconds
start = cputime; % start timer to measure exececution of one loop
if (ok < 0) % check if sampling time too short
disp('samplingtime too short! Increase the value for dT');
return
end
t(k)=k*dT; % update timevector
% ---------------- Read sensor values --------------
y(k) = a.analogRead(p); % measure water level in tank 1 or 2 depending on variable p
e(k) = r(k)-y(k); % calculate the error (desired level - actual level)
% --------------------------------------------------
% --------------- update control signal and write to DAC1 ---------------
if k>1 % we can not assume a value that does not exist yet
%u(k) = K*( e(k) + dT/TI*sum(e) + TD*(e(k)-e(k-1))/dT );
w(k) = w(k-1) + e(k);
u(k) = K * (e(k) + dT/TI * w(k) + TD * (e(k)-e(k-1))/dT);
end
u(k) = min(max(0, round(u(k))), 255); % limit the signal between 0-255
disp("signal " + u(k))
analogWrite(a,u(k),'DAC1');
% -----------------------------------------------------------------------
% ------- online-plot START -------
figure(1)
plot(t,y,'k-',t,u,'m:',t,r,'g');
xlabel('samplingar (k)');
if(p == 'a0')
title('tank 1 PID (zieger-nichols), level (y), signal (u), desired level(r)');
else
title('tank 2 PID (zieger-nichols), level (y), signal (u), desired level(r)');
end
disp(y(k));
legend('y ', 'u ', 'r ');
% ---------------------------------
elapsed=cputime-start; % counts the amount of time in seconds
ok=(dT-elapsed); % saves the time margin in ok
pause(ok); % pauses remaining sampling time
end % -for (end of the samples)
% PART E: end experiment
analogWrite(a,0,'DAC1'); % turn pump off
% plot a final picture
figure(2)
if(p == 'a0')
plot(t,y,'k-',t,u,'m:',t,r,'g-');
xlabel('samples (k)')
ylabel('level (y), signal (u), desired level (r)')
title('Tank 1, PID (zieger-nichols)')
legend('y ', 'u ', 'r ')
else
plot(t,y,'k-',t,u,'m:',t,r,'g:');
xlabel('samples (k)')
ylabel('level (y), signal (u), desired level (r)')
title('Tank 2, PID (zieger-nichols)')
legend('y ', 'u ', 'r ')
end
saveas(figure(2), saveFile);
end