MATLAB script to prove functionality of MPPT algorithm

Authors: Andrew Flynn, Ben Beauregard, Johnathan Adams

This script attempts to imulate the functionality of the maximum power point tracking algorithm built in C for use with the projects hardware. This is meant as a proof that the concept is sound and the algorithm will track theoretical and actual maximum power point data, not as an actual implementation to run on the hardware. As such, certain things are abstracted, such as duty cycle setting and tracking, ISRs, and other MCU-specific functionality.

Contents

Flynn's Code to load Experimental Data

We're just calling another script here. It reads a data file in a terribly... unintuitive way, but it does work, and if it ain't broke...

clear;
fid = fopen('Full_Data.txt', 'r') ; % Open source file.
if fid == -1
    disp('ERROR 404: File Not Found') ;
else
    fgetl(fid) ;                                  % Read/discard line.
    fgetl(fid) ;                                  % Read/discard line.
    buffer = fread(fid, Inf) ;                    % Read rest of the file.
    fclose(fid);
    fid = fopen('_temp.txt', 'w')  ;   % Open destination file.
    fwrite(fid, buffer) ;                         % Save to file.
    fclose(fid) ;
    A = tdfread('_temp.txt') ;
    delete('_temp.txt') ;
end

Data-Error Check

If we have more voltage samples than current samples something is wrong and should probably be fixed before the simulation is continued.

if length(A.Voltage_0x5BV0x5D) ~= length(A.x0x23_Current_0x5BA0x5D)
    error('Sample Size Mismatch. What are you doing?')
else
   IV = [A.Voltage_0x5BV0x5D.'; A.x0x23_Current_0x5BA0x5D.'];
end

Declaration of Variables

These Variables are hereby independant from the monarch of Great Britan.

sim_time = 0; % tracks current elapsed time in simulation, us
Tsample = 1 / 500; % 500Hz MPPT sample rate, we want the period though
num_samp = length(IV); % Number of samples in performance data
delta_dc = 100 * (2 / 320); % Duty cycle increment value
duty_cycle = delta_dc; % Current duty cycle in simulation (range 0 - 100)
power = 0; % Holds current power point
mpp_dc = 0; % duty cycle at maximum power point
mpp = 0; % Power level at maximum power point
samp_idx = 1; % Array Index of current voltage/current sample
sim_data = []; % Array to store simulation results.
finished = 0; % Flag set when sweep is finished to prevent further sweeping

Data Resolution Error Check

Confirm that we have enough experimental data to support the duty cycle increment value given to the simulation. If not, abort, because simulation won't give accurate results.

if length(A.Voltage_0x5BV0x5D) < 100 / delta_dc
    error(['Not enough simulation data points to match given duty '...
        'cycle change rate.']);
end

Define Simulation Parameters

These define the nature of the time-domain loop. This is not robust at all. Simulation time must be evenly divisible by Tsample or simulation will derp.

disp(['Recommended Simulation Time (1 full sweep): ',...
    num2str(Tsample * 160 * 1e3),'ms.']);
sim_len = input('Please enter the time length of the simulation, in ms: ');
while sim_len < Tsample * 10e3
    tmpstr = ['Sim. Length too small.  Minimum length is ',...
        num2str(Tsample * 10e3),'. Please try again: '];
    sim_len = input(tmpstr);
end
sim_res = input('Please enter the time step for the simulation, in us: ');
while sim_res > Tsample * 1e6 / 2 || sim_res < .001
    tmpstr = ['Resolution invalid.  Maximum resolution is ',...
        num2str(Tsample * 1e6 / 2),...
        'us, minimum is 0.001us. Please try again: '];
    sim_res = input(tmpstr);
end
Recommended Simulation Time (1 full sweep): 320ms.
Error using input
Cannot call INPUT from EVALC.

Error in TimeDomainSimulation_try2 (line 69)
sim_len = input('Please enter the time length of the simulation, in ms: ');

Time-Domain Simulation Loop

While the simulation time is less than the requested time, continue simulating.

while sim_time < sim_len * 1e-3
    % Change Duty Cycle at Given Interval
    % mod(x,y) doesn't seem to give actual zero answers... derp...
    if mod(sim_time,Tsample) < 1e-12 && ~ finished
        disp('Simultion Tick');
        % Increment Duty Cycle
        if duty_cycle >= 100 - delta_dc
            duty_cycle = mpp_dc;
            finished = 1; % Mark end of sweep
        else
            duty_cycle = duty_cycle + delta_dc;
        end
        % Check if MPP
        % This indexing code is a bit wat
        samp_idx = round(length(A.Voltage_0x5BV0x5D) * duty_cycle / 100);
        power = A.Voltage_0x5BV0x5D(samp_idx) *...
            A.x0x23_Current_0x5BA0x5D(samp_idx);
        if power > mpp
            mpp = power;
            mpp_dc = duty_cycle;
        end
    end
    % Data Logging
    sim_data = [sim_data;[sim_time,duty_cycle,power,...
        A.Voltage_0x5BV0x5D(samp_idx),...
        A.x0x23_Current_0x5BA0x5D(samp_idx)]]; % Rewrite this later
    % Increment simulaiton time and restart loop
    sim_time = sim_time + sim_res * 1e-6;
end

Graph the Simulation Results

[Ax,H1,H2] = plotyy(sim_data(:,1),sim_data(:,2),sim_data(:,1),...
    sim_data(:,3));
title('Power and Duty Cycle versus Time');
xlabel('Time, [s]');
ylabel(Ax(1),'Duty Cycle, [%]');
ylabel(Ax(2),'Power, [W]');