Adaptive PID Controller For DC Motor Speed Control

24 次查看(过去 30 天)
Mnh
Mnh 2025-10-11,17:28
评论: Umar 16 minutes 前
I am currently working on a project titled “Speed Control of a DC Motor Using an Adaptive PID Controller.” However, during the control process, I have encountered several issues that cause the motor to operate unstably. Specifically, the plant does not closely follow the reference model at low and medium speed ranges. Therefore, I would like to ask if anyone has a Simulink diagram related to this topic that I could refer to.
  3 个评论
Mnh
Mnh 39 minutes 前
编辑:Mnh 30 minutes 前
%% MRAS Adaptive PID (MIT rule) for DC Motor (Realtime Plot)
% Hardware:
% - Arduino UNO R3 + L298N
% - Encoder: 334 pulses/rev × 34 (gear ratio)
% - No-load: ~160 rpm ≈ 16.76 rad/s
% - Supply: 12V
clc; clear; close all;
%% --- Arduino setup ---
a = arduino('COM4','Uno','Libraries',{'RotaryEncoder'});
enc = rotaryEncoder(a,'D2','D3',334*34); % TOTAL_PPR = 11356
in1 = 'D4'; in2 = 'D5'; ena = 'D6';
configurePin(a,in1,'DigitalOutput');
configurePin(a,in2,'DigitalOutput');
configurePin(a,ena,'PWM');
%% --- Parameters ---
T = 0.03; % Sample time [s]
am = 6.0; bm = 6.0; % Reference model
ym = 0; % Model output
% MRAS learning parameters
gamma_p = 0.010; gamma_i = 0.003; gamma_d = 0.002;
norm_p = 0.08; norm_i = 0.02; norm_d = 0.05;
% PID gains and bounds
Kp = 1.8; Ki = 0.7; Kd = 0.05;
Kp_min=0.2; Kp_max=6.0; Ki_min=0; Ki_max=2.5; Kd_min=0; Kd_max=0.2;
% Filters
speed_alpha = 0.6; deriv_alpha = 0.5;
MAX_SPEED = 31; % rad/s
PWM_MAX = 255; PWM_DEADZONE = 8;
% States
I = 0; e_prev = 0; yp_filt = 0; d_filt = 0;
count_prev = 0;
setpoint = 5; % rad/s
disp('MRAS Adaptive PID with realtime plot. Use Ctrl+C to stop.');
fprintf('Current setpoint: %.2f rad/s\n', setpoint);
%% --- Initialize Realtime Plot ---
figure('Name','MRAS Adaptive PID Realtime','NumberTitle','off','Color','w');
subplot(2,1,1);
hRef = animatedline('Color',[0.7 0.7 0.7],'LineWidth',1.5,'LineStyle','--');
hYm = animatedline('Color',[0.2 0.6 1],'LineWidth',1.8);
hYp = animatedline('Color',[1 0.3 0.2],'LineWidth',1.8);
xlabel('Time (s)'); ylabel('Speed (rad/s)');
title('Motor Speed Tracking (Y_p vs Y_m)');
legend({'Ref','Model (Y_m)','Plant (Y_p)'},'Location','best');
grid on;
subplot(2,1,2);
hKp = animatedline('Color','r','LineWidth',1.5);
hKi = animatedline('Color','b','LineWidth',1.5);
hKd = animatedline('Color','g','LineWidth',1.5);
xlabel('Time (s)'); ylabel('Gain value');
title('Adaptive PID Gains (Kp, Ki, Kd)');
legend({'Kp','Ki','Kd'},'Location','best');
grid on;
%% --- Main Control Loop ---
t0 = tic;
while ishandle(hRef)
t = toc(t0);
% --- (1) Measure speed ---
count = readCount(enc);
delta = count - count_prev;
count_prev = count;
rev = double(delta)/11356;
inst_speed = rev * 2*pi / T;
if abs(inst_speed) > MAX_SPEED && abs(inst_speed) > 3*abs(yp_filt + 1e-6)
inst_speed = yp_filt;
end
yp_filt = speed_alpha*yp_filt + (1-speed_alpha)*inst_speed;
yp = yp_filt;
% --- (2) Reference model ---
ym = ym + T*(-am*ym + bm*setpoint);
% --- (3) Error terms ---
e = setpoint - yp;
em = ym - yp;
% --- (4) Derivative & Integral ---
d_raw = (e - e_prev)/T;
d_filt = deriv_alpha*d_filt + (1-deriv_alpha)*d_raw;
I = I + e*T;
% --- (5) Control law ---
uP = Kp*e + Kd*d_filt;
u_tent = uP + Ki*I;
if (u_tent>=PWM_MAX && e>0) || (u_tent<=0 && e<0)
I = I*0.999;
end
u = uP + Ki*I;
pwmOut = min(max(u,0),PWM_MAX);
if pwmOut>0 && pwmOut<PWM_DEADZONE
pwmOut = PWM_DEADZONE;
end
writeDigitalPin(a,in1,1);
writeDigitalPin(a,in2,0);
writePWMVoltage(a,ena,5.0*pwmOut/255);
% --- (6) MIT adaptation ---
freeze = ( (pwmOut>=PWM_MAX && em>0) || (pwmOut<=0 && em<0) );
if ~freeze
phi_p = e; phi_i = I; phi_d = d_filt;
dKp = gamma_p * em * phi_p / (1 + norm_p*phi_p^2);
dKi = gamma_i * em * phi_i / (1 + norm_i*phi_i^2);
dKd = gamma_d * em * phi_d / (1 + norm_d*phi_d^2);
Kp = Kp + dKp; Ki = Ki + dKi; Kd = Kd + dKd;
Kp = min(max(Kp,Kp_min),Kp_max);
Ki = min(max(Ki,Ki_min),Ki_max);
Kd = min(max(Kd,Kd_min),Kd_max);
end
% --- (7) Realtime plot update ---
addpoints(hRef,t,setpoint);
addpoints(hYm,t,ym);
addpoints(hYp,t,yp);
addpoints(hKp,t,Kp);
addpoints(hKi,t,Ki);
addpoints(hKd,t,Kd);
drawnow limitrate;
% --- (8) Display info every ~0.3s ---
if mod(round(t,2),0.3)<T
fprintf('t=%.1fs | Yp=%.2f | Ym=%.2f | e=%.2f | Kp=%.2f Ki=%.2f Kd=%.2f | PWM=%3d\n',...
t, yp, ym, em, Kp, Ki, Kd, round(pwmOut));
end
e_prev = e;
pause(T);
end
disp('Stopped MRAS Adaptive PID realtime loop.');
Hello @Umar, thank you for your reminder. I am currently controlling a motor using a MATLAB .m file. However, when I upload the code to the motor for execution, I encounter several errors that I have been unable to resolve. I am considering switching to Simulink for implementation, but if possible, could you please guide me on how to fix these errors in the MATLAB .m code?
Umar
Umar 16 minutes 前

Hi @Mnh,

This will take some time to figure out the root cause. Let me review it carefully and I will get back to you. Hope you are not in rush.

请先登录,再进行评论。

回答(1 个)

Sabin
Sabin about 6 hours 前
Without a sample model we can not really point to any specific problem. You can start building the simulation model using existing examples in Simscape Electrical. This example shows a cascade speed-control structure for a DC motor:
Simscape Electrical also provide a discrete-time PID-based model reference adaptive control that can be used in the example I mentionded:

类别

Help CenterFile Exchange 中查找有关 Motor Drives 的更多信息

产品


版本

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by