classdef Thor_PDFA < handle properties(Access= public) serialport_number safety_mode statusInfo StatusRegisterValue Interlock TEC0_temp TEC1_temp Temp_stable Temp_fault LASER LOS_Status PumpLevel end methods (Access=public) function obj = Thor_PDFA(options) arguments options.serialport_number = 'COM12' options.safety_mode = 1; end % fn = fieldnames(options); for n = 1:numel(fn) try obj.(fn{n}) = options.(fn{n}); end end obj.getStatus(); end function o = connectSerial(obj) try % Connect to the PDFA o = serialport(obj.serialport_number, 9600); configureTerminator(o, "CR", "CR"); % Set the terminator to carriage return (CR) flush(o); catch ME disp(['Error connecting to PDFA: ', ME.message]); % List available serial ports availablePorts = serialportlist("available"); if isempty(availablePorts) disp('No available serial ports found.'); else disp('Available serial ports:'); disp(availablePorts); end end end function getStatus(obj) o = obj.connectSerial(); obj.getStatus_(o); if obj.safety_mode obj end end function enablePDFA(obj) o = obj.connectSerial(); if obj.safety_mode % Prompt the user to enable choice = questdlg('Do you want to enable the PDFA?', ... 'TURN ON PUMP', ... 'PUMP IT!', 'No', 'No'); else choice = 'PUMP IT!'; end % Handle the response switch choice case 'PUMP IT!' % Enable the pump success = obj.enablePump_(o); disp('PDFA enabled.'); case 'No' % Abort the operation disp('Operation aborted. Laser remains disabled.'); end end function disablePDFA(obj) o = obj.connectSerial(); if obj.safety_mode % Prompt the user to disable choice = questdlg('Do you want to disable the PDFA?', ... 'TURN OFF PUMP', ... 'Turn off', 'No', 'No'); else choice = 'Turn off'; end % Handle the response switch choice case 'Turn off' % Enable success = obj.disablePump_(o); disp('PDFA enabled.'); case 'No' % Abort the operation disp('Operation aborted. Laser remains disabled.'); end end function success = setPumpLevel(obj,desiredPump) success = 0; o = obj.connectSerial(); obj.setPumpLevel_(o,desiredPump); end function cleanedResponse = cleanResponse(~,responseToClean) cleanedResponse = regexprep(responseToClean, '\x1B\[[0-9;]*[a-zA-Z]', ''); end end methods(Access= private) function pumpLevel = readPumpLevel(obj,serialObj) writeline(serialObj, "gloc"); pause(0.05); response = read(serialObj,serialObj.NumBytesAvailable,"char"); cleanedResponse = obj.cleanResponse(response); currentPercentage = regexp(cleanedResponse, '([0-9]+\.[0-9]+)%', 'tokens', 'once'); obj.PumpLevel = str2double(currentPercentage{1}); pumpLevel = obj.PumpLevel; end function getStatus_(obj,o) writeline(o, "stat"); pause(0.5); response = read(o,o.NumBytesAvailable,"char"); cleanedResponse = obj.cleanResponse(response); % Parse and convert values % Convert Status Register Value (hexadecimal to decimal) statusValueHex = regexp(cleanedResponse, 'Status Register Value = (0x[0-9A-F]+)', 'tokens', 'once'); obj.StatusRegisterValue = hex2dec(statusValueHex{1}); % Convert Interlock status to logical (Closed = true, Open = false) interlockStatus = regexp(cleanedResponse, 'Interlock\s*:\s*(\w+)', 'tokens', 'once'); obj.Interlock = strcmp(interlockStatus{1}, 'Closed'); % Convert TEC0 and TEC1 temp to logical (Good = true, Fault = false) tec0Temp = regexp(cleanedResponse, 'TEC0 temp\s*:\s*(\w+)', 'tokens', 'once'); obj.TEC0_temp = strcmp(tec0Temp{1}, 'Good'); tec1Temp = regexp(cleanedResponse, 'TEC1 temp\s*:\s*(\w+)', 'tokens', 'once'); obj.TEC1_temp = strcmp(tec1Temp{1}, 'Good'); % Convert Temp stable status to logical (Stable = true, Unstable = false) tempStable = regexp(cleanedResponse, 'Temp stable\s*:\s*(\w+)', 'tokens', 'once'); obj.Temp_stable = strcmp(tempStable{1}, 'Stable'); % Convert Temp fault status to logical (No Fault = false, Fault = true) tempFault = regexp(cleanedResponse, 'Temp fault\s*:\s*(\w+)', 'tokens', 'once'); obj.Temp_fault = strcmp(tempFault{1}, 'Fault'); % Convert LASER status to logical (OFF = false, ON = true) laserStatus = regexp(cleanedResponse, 'LASER\s*:\s*(\w+)', 'tokens', 'once'); obj.LASER = strcmp(laserStatus{1}, 'ON'); % Convert LOS Status to logical (Good = true, Faulty = false) losStatus = regexp(cleanedResponse, 'LOS Status\s*:\s*(\w+)', 'tokens', 'once'); obj.LOS_Status = strcmp(losStatus{1}, 'Good'); writeline(o, "gloc"); pause(0.5); response = read(o,o.NumBytesAvailable,"char"); cleanedResponse = obj.cleanResponse(response); % Use a regular expression to extract the operating current value in percentage currentPercentage = regexp(cleanedResponse, '([0-9]+\.[0-9]+)%', 'tokens', 'once'); % Convert the extracted percentage to a numeric value obj.PumpLevel = str2double(currentPercentage{1}); end function success = enablePump_(obj,o) success = 0; curPump = obj.readPumpLevel(o); if curPump ~= 0 cnt = 0; pumpSetToZero = 0; while ~pumpSetToZero pumpZero = 0; pumpSetToZero = obj.setPumpLevel_(o,pumpZero); cnt = cnt+1; end end % set pump on writeline(o, 'le'); pause(0.5); response = read(o,o.NumBytesAvailable,"char"); cleanedResponse = obj.cleanResponse(response); isEnabled = contains(cleanedResponse, {'ENABLE LASER'}); pause(5); obj.getStatus_(o); if isEnabled && obj.LASER success = 1; else error('Could not enable the pump....'); end end function success = disablePump_(obj,o) success = 0; curPump = obj.readPumpLevel(o); if curPump ~= 0 cnt = 0; pumpSetToZero = 0; while ~pumpSetToZero pumpZero = 0; pumpSetToZero = obj.setPumpLevel_(o,pumpZero); cnt = cnt+1; end end % set pump on writeline(o, 'ld'); pause(0.5); response = read(o,o.NumBytesAvailable,"char"); cleanedResponse = obj.cleanResponse(response); isDisabled = contains(cleanedResponse, {'DISABLE LASER'}); pause(5); obj.getStatus_(o); if isDisabled && ~obj.LASER success = 1; else error('Could not disable the pump....'); end end function success = setPumpLevel_(obj,o,desiredPump) success = 0; curPump = obj.readPumpLevel(o); while abs(curPump-desiredPump) > 0 % difference diff_pump = curPump-desiredPump; % set new pump increment_pump = -1 * sign(diff_pump) ; % set new incr. pump writeline(o, ['sloc ',num2str(curPump+increment_pump)]); if increment_pump < 0 pause(0.1); else pause(0.3); end response = read(o,o.NumBytesAvailable,"char"); cleanedResponse = obj.cleanResponse(response); curPump = str2double(regexp(cleanedResponse, '([0-9]+\.[0-9]+)%', 'tokens', 'once')); end curPump = obj.readPumpLevel(o); if obj.PumpLevel == desiredPump success = 1; else warning('Pump nicht richtig?') end end end end