%%Project4_PIControl % LSA project day 4 script - Proporitional, and integral control test. This % script will implement a PI controller for the speed of a DC motor. % % Delvin E Peterson % Walla Walla University % ENGR 350 - Winter 2020 % Project Day 4 % Based on previous code by Ralph Stirling clear variables, close all global sample_period V_max %Global values are available to subfunctions sample_period = 1/100; %length of sample time interval %% Changeable paramters V_max = 10; %Set to the voltage displayed on your multimeter Kp = .06; %Proportional control constant Ki = 0; %Integral control constant om_des = 300; %Desired output speed run_time = 5; %Run time in seconds filter_step = 10; %Increasing this will smooth out response, but also slow initial response %% Set up input voltages and time vectors len = run_time/sample_period + 1; %Length of run in samples t_exp = 0:sample_period:run_time; %Time data SHOULD be collected at t_act = t_exp; %Time data WERE collected at (set later) enc = zeros(1,len); %Pre-allocate the motor encoder data spd_rps = zeros(1,len); %Pre-allocate the motor speed spd_rps_f = spd_rps; %Pre-allocate filtered motor speed om_int = 0; %Set the integral of speed to start at 0 Vp = zeros(1,len); %Pre-allocate the proportional signal Vi = zeros(1,len); %Pre-allocate the integral signal V_in = Vp+Vi; %Pre-allocate the total input voltage %% Run the test % The motor is driven by an H-bridge circuit and pulse width modulation. serial_start; enc(1) = read_enc(); % write_volt(volts(1)); tic for cnt=2:len enc(cnt) = read_enc(); %Read encoder counts since last sample period t_act(1,cnt) = toc; %Store actual time elapsed om_act = motor_speed(t_act(cnt-1:cnt),enc(cnt-1:cnt)); spd_rps(cnt) = om_act; % Implement digital filter if cnt <= filter_step spd_rps_f(cnt) = mean(spd_rps(1:cnt)); else spd_rps_f(cnt) = mean(spd_rps(cnt-filter_step:cnt)); end om_act_f = spd_rps_f(cnt); % Vp(cnt) = Kp*(om_des - om_act_f); %Calculate proportional signal om_int = om_int + (om_des - om_act_f)*(t_act(cnt) - t_act(cnt-1)); Vi(cnt) = Ki*om_int; %Calculate integral signal V_in(cnt) = Vp(cnt) + Vi(cnt); if abs(V_in(cnt)) > V_max %Cap the voltage at the max V_in(cnt) = V_max*sign(V_in(cnt)); end write_volt(V_in(cnt)); %Write voltage value to controller end write_volt(0); serial_stop; % plot(t_exp,t_act,'b-',t_exp,t_exp,'g:') %Debug time stepping %% Calculate and plot results % [spd_rps,spd_rpm] = motor_speed(t_act,enc); figure,subplot(2,1,1) plot(t_act,spd_rps,'b-',t_act,spd_rps_f,'c-') title(['Motor Response Speed to PI Control with Kp = ' num2str(Kp,3) ... ' and Ki = ' num2str(Ki,3)]) ylabel('Motor Speed (rad/s)') ymx = mean(spd_rps)*2; ylim([-abs(ymx) abs(ymx)]) legend('Unfiltered','Digital Filter','Location','SouthOutside') subplot(2,1,2) plot(t_act,Vp,'b-.',t_act,Vi,'r-.',t_act,V_in,'g-') xlabel('Time (s)') ylabel('Control Signal (V)') legend('Proportional Signal','Integral Signal','Total Signal',... 'Location','SouthOutside')