% Calc for acid pump control 
% 
% This is based on Ed Peltzers calcs for the HCL concentration and
% predicted currents
% 
% copyright (c) 2005 by W.J.Kirkwood of MBARI
% February 2, 2005 
% Last Modified 2/20/05 
% Revision: 1.0 
%
% ///////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
% 
% clean up from last activity 
clear all ; clf;
%
% Variable Declarations
% 
% pH_SetPoint = 7.300               % pH target value for control volume 
% pH_Delta = 0                      % pH difference from set point initialized
% pH1 = 7.700;                      % pH Probe 1 value
% pH2 = 7.700;                      % pH Probe 2 value
% pH3 = 7.700;                      % pH Probe 3 value
% pH_Valid_Max = 8.0;               % Maximum allowable value for inclusion in average
% pH_Valid_Min = 6.0;               % Minimum allowable value for inclusion in average
% PumpH20 = 720;                    % Sets the water pump at 720 mL/min
% PumpAcid = 720;                   % Sets the acid pump at 720 mL/min
% PumpFixedFlow = 1440;             % Sets the total pump flow at maximum current
%
% /////////////////// Variable Reset if Enabled \\\\\\\\\\\\\\\\\\\\\\\
% This section is to input values for max and min on several variables

% /////////////////// Set pH Probe Calibration \\\\\\\\\\\\\\\\\\\\\\\\\
%
% Probe Calibration uses a scale of 0 to 5 volts per Ed with 2.5 being theoretical zero
% There are two inputs to calibrate the probe: offset (+ or -) and slope (+)
% Each probe has in calibration input of the form:
% pH1_initial_calib = 7.00;  
% pH1_initial_calib_V = (2.500 * 7.00); 
% pH1_true_calib_V = (pH1_initial_calib_V + offset);   units are volts sets mid-point refernce

% pH2_initial_calib = 7.00;  
% pH2_initial_calib_V = (2.500 * 7.00); 
% pH2_true_calib_V = (pH2_initial_calib_V + offset);   units are volts sets mid-point refernce

% pH3_initial_calib = 7.00;  
% pH3_initial_calib_V = (2.500 * 7.00); 
% pH3_true_calib_V = (pH3_initial_calib_V + offset);   units are volts sets mid-point refernce

% /////////////////////// pH Probe Filter \\\\\\\\\\\\\\\\\\\\\\\\\
% Based on a FIFO using a reading Frequency and a Number of Samples

% SampNumDefault = 10;             % The number of readings used to average
% FreqDefault = 2;                 % Reading frequency in Hertz 

% SampNumInput = input('Enter number of samples to tune filter : '); 
% K1 = logical(SampNumInput);        % converts line input to logical for test
%   if K1 NOT 1
%       SampNum = SampNumInput;
%   else
%       SampNum = SampNumDefault;
%   end
%
% FreqInput = input(' Enter the frequency you wish to sample probes at : ');
% K2 = logical (FreqInput);
%   if K2 NOT 1
%       ProbeDataFreq = FreqInput;
%   else
%       ProbeDataFreq = FreqDefault; 
%   end
% 
% pH1_Filter = zeros(1,SampNum);         % Martrix for Probe 1 filtering 
% pH2_Filter = zeros(1,SampNum);         % Martrix for Probe 2 filtering 
% pH3_Filter = zeros(1,SampNum);         % Martrix for Probe 3 filtering 

% ////////////////////// H20 Current Estimate \\\\\\\\\\\\\\\\\\\\\
% Entered as a flow relationship to set pump volumes
% First order calcs from Ed Peltzer show the relationship in the current
% and pH regimes to be apporximatley linear. Based on a fix solution of acid
% at 10% HCL concentration use the following ratio relationship:

% Current estimate at 10 cm/sec acid flow is 

% This section bounds the current since the flow design is limited in capability
% MinCurrent = 10;              % Minimum current estimate in cm/sec
% MaxCurrent = 30;              % Maximum current estiamte in cm/sec

% EstimateCurrent = input('Enter current in cm/sec : ');
%   if MinCurrent > EstimateCurrent
%       Current = MinCurrent;
%   elseif MaxCurrent < EstimateCurrent
%       Current = MaxCurrent;
%   else 
%       Current = EstimateCurrent;
%   end
% %%%%  Current = (Current/100);      % transform to liters 

% ////////////////////// Pump Flow Control \\\\\\\\\\\\\\\\\\\\\\\
% Two pumps run as an inverse ratio to maintain a set over flow volume
% uses the estimated current relationship. 
% ............ Note: Pumps ordered are 4.8 ml / rev ............... 
%   if Current = 10
%          Total_Flow = 480;             % Minimum ml/min from combined pumps
%          PumpAcid = Total_Flow / 2;
%          PumpFixedFlow =  Total_Flow - PumpAcid;  % Default total output from pumps in ml/sec
%   elseif Current = 30
%          Total_Flow = 1440;             % Maximum ml/min from combined pumps
%          PumpAcid = Total_Flow / 2;
%          PumpFixedFlow =  Total_Flow - PumpAcid;  % Default total output from pumps in ml/sec
%   else 
%          Total_Flow = 1440 * (Current / MaxCurrent); % Minimum ml/min from combined pumps
%          PumpAcid = Total_Flow / 2;
%          PumpFixedFlow =  Total_Flow - PumpAcid;  % Default total output from pumps in ml/sec
%   end
%
% PumpAcidMax  = PumpAcid;
% PumpAcidMin = -PumpAcid;
%
% ////////////////// Running Control Loop \\\\\\\\\\\\\\\\\\\\\\\\\

% Start time 
% Necessary serial port open statements 

% pH_port1 = serial('COM1');
% fopen(pH_port1)
% fprintf(pH_port1,'RS232?')

% pH_port2 = serial('COM2');
% fopen(pH_port2)
% fprintf(pH_port2,'RS232?')

% pH_port3 = serial('COM3');
% fopen(pH_port3)
% fprintf(pH_port3,'RS232?')

% For time = T
% 
% Read pH Probe new value at designated time
% pH_read1 = fscanf(pH_port1);
% pH_read2 = fscanf(pH_port2);
% pH_read3 = fscanf(pH_port3);

% Check probes for valid data and give notice of bad input
% ********  NOTE: This section notifies of anamolous data *************
%   if ((pH_Valid_Min < pH_read1) && (pH_read1 < pH_Valid_Max)) ~= 1
%       'pH Probe 1 value error :', pH_read1;         % error statement
%   end
%   if ((pH_Valid_Min < pH_read2) && (pH_read2 < pH_Valid_Max)) ~= 1
%       'pH Probe 2 value error :', pH_read2;         % error statement
%   end
%   if ((pH_Valid_Min < pH_read3) && (pH_read3 < pH_Valid_Max)) ~= 1
%       'pH Probe 3 value error :', pH_read3;         % error statement
%   end

% Box car filter for pH Probes: Moves most recent reading into 1st matrix
% cell and pushes each cell down one
%   for i = 1:(SampNum - 1)
%       pH1_Filter(1,i+1) = pH1_Filter(1,i);         % Matrix for Probe 1 filtering 
%       pH2_Filter(1,i+1) = pH2_Filter(1,i);         % Matrix for Probe 2 filtering 
%       pH3_Filter(1,i+1) = pH2_Filter(1,i);         % Matrix for Probe 3 filtering 
%   end
%
% Insert new value in pH Matrix position 1
% pH1_Filter(1,1) = pH_read1;         
% pH2_Filter(1,1) = pH_read2;         
% pH3_Filter(1,1) = pH_read3;         
%
% Sum of array elements 
% pH1_sum = sum(pH1_Filter);
% pH2_sum = sum(pH2_Filter);
% pH3_sum = sum(pH3_Filter);
%
% Average of each probe for filter
% pH1_Avg = pH1_sum / SampNum;                  % Filtered output of pH probe 1
% pH2_Avg = pH2_sum / SampNum;                  % Filtered output of pH probe 2
% pH3_Avg = pH3_sum / SampNum;                  % Filtered output of pH probe 3
%
% Check of filtered pH data for failure
% ********  NOTE: This section lets the filter continue *************
%   if ((pH_Valid_Min < pH1_Avg) && (pH1_ Avg < pH_Valid_Max)) ~= 1
%           '*********** pH Probe 1 failure ************' ;        % failure statement
%           CountProbe1 = 0;                                       % eliminates probe from calc
%           pH1_Avg = 0;                                           % zeros bad probe value
%   else 
%           CountProbe1 = 1;                                       % allows probe in calc
%   end
%   if ((pH_Valid_Min < pH2_Avg) && (pH2_ Avg < pH_Valid_Max)) ~= 1
%           '*********** pH Probe 2 failure ************' ;        % failure statement
%           CountProbe2 = 0;                                       % eliminates probe from calc
%           pH2_Avg = 0;                                           % zeros bad probe value
%   else 
%           CountProbe2 = 1;                                       % allows probe in calc
%   end
%   if ((pH_Valid_Min < pH3_Avg) && (pH3_ Avg < pH_Valid_Max)) ~= 1
%           '*********** pH Probe 3 failure ************' ;        % failure statement
%           CountProbe3 = 0;                                       % eliminates probe from calc
%           pH3_Avg = 0;                                           % zeros bad probe value
%   else 
%           CountProbe3 = 1;                                       % allows probe in calc
%   end
% GoodProbes = CountProbe1 + CountProbe2 + CountProbe3;            % Total good probes
%
% Check to see if all the probes have failed and system is uncontrolled 
%   if GoodProbes = 0
%       '!!!!!!!!! Probes Have Failed - Exiting Control Loop !!!!!!!!';
%       ' Exiting Program ';
%       Stop Time                                                  % Terminate program
%   end
%
% Completed pH probe filter output for control
% pH_Control = (pH1_Avg + pH2_Avg + pH3_Avg) / GoodProbes; 
%
% Main Control Algorithm for Pumps
% Concept: We would like the pump control to be exponential as the pH
% wanders from the set point. This makes our control take the form 
% y = f(x) + K = a*2^(b*(x-h))+k 
% y is the acid pump commanded output
%
% a = scalar multiplier and moves the zero crossover on the x axis, also
% change of sign of a flips the control curve around the x axis
% a = .4;
%
% b = exponential multiplier and sets the rate of change of the slope of
% the control curve, also a sign change flips the control curve around the y axis
% b = 2.0;
% 
% h is the x offset constant and sets the x crossover at y = 0
% h = .5;
%
% K is the y offset constant and sets the y crossover at f(x) = 0
% K = 720;                  % scaled in ml/min 
% 
%
% pH Bounds lower is - .1 pH unit and upper is + .1 pH unit for deadband
% pH_BoundLow = pH_SetPoint - .10;
% pH_BoundHigh = pH_SetPoint + .10; 
% 
% Control Tests for sign on equation variables a, b, and K to invert curve
% about dead band
%
%   if pH_Control < pH_BoundLow
%          a = -a;
%          b = -b;
%          K = -K;
%   end
%          
% Set scaling for pump adjust
%
% pH_expo = b*(pH_Control - h);
% pH_X = a*(2^pH_expo);
% PumpAdjNum  = pH_X + K;
%
% Acid Flow Clipping Equation goes here 
%
%   if (PumpAdjNum > PumpAcidMax )
%       NewAcidNum = PumpAcidMax;
%   elseif (PumpAdjNum < PumpAcidMin )
%       NewAcidNum = PumpAcidMin;
%   else
%       NewAcidNum = PumpAdjNum;
%   end
% 
% Pump adjust test vs. pH 
%
%   if  pH _Control  > pH_BoundMax
%      PumpCmd
%
%
% slaving acid pump rate to the pH_Control variable
% pH_Delta = pH_SetPoint - pH_Control;                  % pH offset from desired value
%
% tests and settings for acid volume change
%   if pH_Delta < 0 
%          PumpAdjNum = pH_Delta_Old - pH_Delta;
%          PumpAcid = PumpAcid;                         % no change to pump input 
%          PumpFixedFlow =  Total_Flow - PumpAcid;      % Default total output from pumps in ml/sec
%   elseif pH_Delta > 0
%          PumpAcid = Total_Flow / 2;
%          PumpFixedFlow =  Total_Flow - PumpAcid;      % Default total output from pumps in ml/sec
%   else 
%          PumpAcid = PumpAcid;                         % no change in pump flow 
%   end      
%   pH_Delta_Old = pH_Delta;                            % resets pH for comparison to last value 
%   pH_PumpAcid_Old = pH_PumpAcid;                      % resets Acid Pump flow rate comparion to last value
%




% Shutdown and clean up 
% Stop time 

% fclose(pH_port1)
% fclose(pH_port2)
% fcloae(pH_port3) 


