% This skript calculates all possible voltage divider combinations at
% nomminal value as well as minimal and maximal tolarances.

clear;
close all;

% available resistor values
% base_values = [1 1.2 1.5 1.8 2.2 2.7 3.3 3.9 4.7 5.6 6.8 8.2];
base_values = [1 1.1 1.2 1.3 1.5 1.6 1.8 2.0 2.2 2.4 2.7 3.0 3.3 3.6 3.9 4.3 4.7 5.1 5.6 6.2 6.8 7.5 8.2 9.1];
min_factor = 0.1;
max_factor = 1000000;

values = [];
factor = min_factor;
while factor <= max_factor
    values = horzcat(values, base_values*factor);
    factor = factor*10;
end
values = horzcat(values, 10*max_factor);
amount = length(values);

% define E-Series values
base_series_max = 24;
base_series = zeros (1, base_series_max);

divider = 1;
while mod(base_series_max,divider) == 0
    for i=1:divider:base_series_max
        base_series(1, i) = base_series_max/divider;
    end
    divider = divider*2;
end

% maximum total resistor tolerance:
% - initial tolerance
% - change due to reflow
% - temperature drift
% typ: 0.01 + 100*100ppm + 0.01 = 0.03
tol = 0.03;

output_nom = zeros(amount, amount);
output_max = zeros(amount, amount);
output_min = zeros(amount, amount);

diff_max = zeros(amount, amount);
diff_min = zeros(amount, amount);

change_max = zeros(amount, amount);
change_min = zeros(amount, amount);

current = zeros(amount, amount);

for m = 1:amount
    for n = 1:amount
        % fill matrix with proportional output of voltage across lower resistor
        %
        % ---+
        %    |
        %  R1 (m)
        %    |
        %    +----
        %    |
        %  R2 (n)
        %    |
        % ---+----
        %
        output_nom(m,n) = values(n)/(values(n)+values(m));
        
        output_max(m,n) = values(n)*(1+tol)/(values(n)*(1+tol)+values(m)*(1-tol));
        output_min(m,n) = values(n)*(1-tol)/(values(n)*(1-tol)+values(m)*(1+tol)); 
        
        diff_max(m,n) = output_max(m,n)-output_nom(m,n);
        diff_min(m,n) = output_min(m,n)-output_nom(m,n);
        
        change_max(m,n) = (output_max(m,n)-output_nom(m,n))/output_nom(m,n);
        change_min(m,n) = (output_min(m,n)-output_nom(m,n))/output_nom(m,n);
        
        current(m,n) = 1/(values(m)+values(n));
    end
end

% mean nominal difference in procent
error = round(change_max+change_min, 10)*100;

% figure;
% surf(diff_max);
% figure;
% surf(diff_min);

%columns: E1, R1, E2, R2, U2/U1 nom, I/U1 nom,
%         U2/U1 min, U2/U1 max, diff min, diff max, rel min, rel max
output_list = zeros(amount*amount, 12);

for i = 1:amount
    for j = 1:amount
        output_list(i+amount*(j-1), 1)  = base_series(mod(i-1, base_series_max)+1);
        output_list(i+amount*(j-1), 2)  = values(i);
        output_list(i+amount*(j-1), 3)  = base_series(mod(j-1, base_series_max)+1);
        output_list(i+amount*(j-1), 4)  = values(j);
        output_list(i+amount*(j-1), 5)  = output_min(i,j);
        output_list(i+amount*(j-1), 6)  = output_nom(i,j);
        output_list(i+amount*(j-1), 7)  = output_max(i,j);
        output_list(i+amount*(j-1), 8)  = current(i,j);
        output_list(i+amount*(j-1), 9)  = diff_min(i,j);
        output_list(i+amount*(j-1), 10) = diff_max(i,j);
        output_list(i+amount*(j-1), 11) = change_min(i,j);
        output_list(i+amount*(j-1), 12) = change_max(i,j);
    end
end

%csvwrite('export_data.csv', output_list);

table = array2table(output_list, 'VariableNames',...
        {'E1', 'R1', 'E2', 'R2', 'out_min', 'out_nom', ...
        'out_max', 'current', 'diff_min', 'diff_max', ...
        'rel_min', 'rel_max'});

filename = 'voltage_divider_with_tolerances_export.xlsx';
writetable(table,filename);
    
