classdef gui_1 < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure
        Button5
        Button4
        Button3               
        Button2                
        Button                 
        SerialsettingsLabel    
        BaudrateDropDown       
        BaudrateDropDownLabel  
        PortNameDropDown      
        PortNameDropDownLabel 
        SETPARAMETERSLabel    
        EditField3             
        EditField2            
        EditField            
        EditFieldLabel         
        UIAxes
        Lamp
        LampLabel
        device        
        P_gain
        I_gain
        D_gain
        BTN1
        BTN2
        Drawing
        Read_logic
        Target_position
        Target_position_logic
        Target_position_count
        Current_position
        Data
        Time
        Ind
        SC_pix
        Height
        Width
        h
        t
    end
     
   
    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(PID)
            PID.SC_pix = get(0,'ScreenSize')
            PID.Width = PID.SC_pix(3)
            PID.Height = PID.SC_pix(4)

            up = 650;
            up_1 = 550;
            up_2 = 350;
            % Create UIFigure and hide until all components are created
            PID.UIFigure = uifigure('Visible', 'off');
            PID.UIFigure.Units = 'normalized'
            PID.UIFigure.Position = [0.88 0.05 0.12 0.92];
            PID.UIFigure.Name = 'PID_REGULATOR_GUI';    
            
            %PID.UIFigure.CloseRequestFcn =  createCallbackFcn(PID, @CloseRequest, true);


            % Create SerialsettingsLabel
            PID.SerialsettingsLabel = uilabel(PID.UIFigure);
            PID.SerialsettingsLabel.Position = [0.01*PID.Width 0.90*PID.Height 0.08*PID.Width 0.03*PID.Height];
            PID.SerialsettingsLabel.Text = 'Serial settings:';

            % Create PortNameDropDownLabel
            PID.PortNameDropDownLabel = uilabel(PID.UIFigure);
            PID.PortNameDropDownLabel.Position = [0.01*PID.Width 0.87*PID.Height 0.08*PID.Width 0.03*PID.Height];
            PID.PortNameDropDownLabel.Text = 'Port Name:';

            % Create PortNameDropDown
            PID.PortNameDropDown = uidropdown(PID.UIFigure);         
            PID.PortNameDropDown.Items = {''};
            PID.PortNameDropDown.Position = [0.02*PID.Width 0.85*PID.Height 0.08*PID.Width 0.02*PID.Height];


            % Create BaudrateDropDownLabel
            PID.BaudrateDropDownLabel = uilabel(PID.UIFigure);
            PID.BaudrateDropDownLabel.Position = [0.01*PID.Width 0.82*PID.Height 0.08*PID.Width 0.03*PID.Height];
            PID.BaudrateDropDownLabel.Text = 'Baudrate:';

            % Create BaudrateDropDown
            PID.BaudrateDropDown = uidropdown(PID.UIFigure);
            PID.BaudrateDropDown.Position = [0.02*PID.Width 0.79*PID.Height 0.08*PID.Width 0.02*PID.Height];
            PID.BaudrateDropDown.Items = {'9600','1200','2400','4800','14400','19200','2880','3840',...
                                         '57600','115200','230400'};

            %%BUTTONS
            % Create CONNECT
            PID.Button = uibutton(PID.UIFigure, 'push');
            PID.Button.Position =[0.02*PID.Width 0.70*PID.Height 0.08*PID.Width 0.03*PID.Height];
            PID.Button.Text = 'CONNECT';
            PID.Button.Tag = 'CONNECT';
            PID.Button.ButtonPushedFcn = createCallbackFcn(PID, @ButtonPushed, true);
          
            % Create REFRESH
            PID.Button2 = uibutton(PID.UIFigure, 'push');
            PID.Button2.Position = [0.02*PID.Width 0.66*PID.Height 0.08*PID.Width 0.03*PID.Height];
            PID.Button2.Text = 'REFRESH';
            PID.Button2.Tag = 'REFRESH';
            PID.Button2.ButtonPushedFcn = createCallbackFcn(PID, @ButtonPushed2, true);
                  
           
             % Create START
            PID.Button3 = uibutton(PID.UIFigure, 'push');
            PID.Button3.Position =[0.02*PID.Width 0.54*PID.Height 0.08*PID.Width 0.03*PID.Height];
            PID.Button3.Text = 'NEW FIGURE';
            PID.Button3.Tag = 'NEW FIGURE';
            PID.Button3.ButtonPushedFcn = createCallbackFcn(PID, @NEWFIG, true);


             % Create CLOSE FIGURE
            PID.Button5 = uibutton(PID.UIFigure, 'state');
            PID.Button5.Position = [0.02*PID.Width 0.5*PID.Height 0.08*PID.Width 0.03*PID.Height];
            PID.Button5.Text = 'STOP';
            PID.Button5.Tag = 'STOP';            
            %PID.Button5.ButtonPushedFcn = createCallbackFcn(PID, @ButtonPushed5, true);

            % Create SETPARAMETERSLabel
            PID.SETPARAMETERSLabel = uilabel(PID.UIFigure);
            PID.SETPARAMETERSLabel.Position = [0.02*PID.Width 0.4*PID.Height 0.08*PID.Width 0.03*PID.Height];
            PID.SETPARAMETERSLabel.Text = 'SET PARAMETERS';
            PID.EditFieldLabel.Text = '';

            % Create EditField
            PID.EditField = uieditfield(PID.UIFigure, 'text');
            PID.EditField.Editable = 'off';
            PID.EditField.Position = [0.02*PID.Width 0.35*PID.Height 0.08*PID.Width 0.03*PID.Height];

            % Create EditField2
            PID.EditField2 = uieditfield(PID.UIFigure, 'text');
            PID.EditField2.Editable = 'off';
            PID.EditField2.Position = [0.02*PID.Width 0.31*PID.Height 0.08*PID.Width 0.03*PID.Height];

            % Create EditField3
            PID.EditField3 = uieditfield(PID.UIFigure, 'text');
            PID.EditField3.Editable = 'off';
            PID.EditField3.Position = [0.02*PID.Width 0.27*PID.Height 0.08*PID.Width 0.03*PID.Height];   
                     
           
            
            % Create LampLabel
            PID.LampLabel = uilabel(PID.UIFigure);
            PID.LampLabel.Position = [0.02*PID.Width 0.15*PID.Height 0.08*PID.Width 0.03*PID.Height];
            PID.LampLabel.Text = 'Lamp';

            % Create Lamp
            PID.Lamp = uilamp(PID.UIFigure);
            PID.Lamp.Position = [0.05*PID.Width 0.12*PID.Height 0.025*PID.Width 0.025*PID.Height];
            PID.Lamp.Color = 'red';
           
            % Show the figure after all components are created            
            PID.UIFigure.Visible = 'on';
            PID.UIAxes.Visible = 'on';            
           
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function PID = gui_1
            
            % Create UIFigure and components
            createComponents(PID);

            % Register the app with App Designer
            registerApp(PID, PID.UIFigure);

             pause(2.5);

            Createfig(PID); 
            
            PID.Button5.Value = 0;
            

            if nargout == 0
                clear app
            end
        end

         % Code that executes before app deletion
        function delete(PID)

            % Delete UIFigure when app is deleted
            delete(PID.UIFigure)
        end
    end

    methods (Access = private)

        function ButtonPushed(PID,event)

            PID.Lamp.Color = 'green';
            COMport = PID.PortNameDropDown.Value;
            Baudrate = str2double(PID.BaudrateDropDown.Value);
            PID.device = serialport(COMport,Baudrate);
            PID.device.UserData = struct("Data",[],"Count",1,"Data_param",[],"Data_string",[]);
            
          
            PID.EditField.Value = "HELLO WORLD!!";
            PID.EditField2.Value = "PRESS START TO READ";
            PID.EditField3.Value = "PID_REGULATOR";

            PID.Read_logic = 1;
            PID.Drawing = 0;
            PID.Ind = 1;
            PID.Time = 1;

            
            ReadUart(PID,event);            

        end 

        function Createfig(PID,event) 

                figure('Name', 'PID_regulation','NumberTitle','off','Units','normalized','Position',[0 0.05 0.88 0.86])%0.88 0.93
                PID.h = animatedline('Color','r','LineWidth',1.05);
                PID.t = animatedline('Color','b','LineWidth',1.05);
                legend('Aktuální natočení','Požadované natočení')                             
           
                xlabel("Čas [s]")
                ylabel("Natočení [°]")

                grid on
                grid minor

        end
%%
        function ReadUart(PID,event)            
                      
            while PID.Read_logic == 1  
                
             if PID.Button5.Value == 1                 
                
                PID.Read_logic = 0;                                  
                    continue
              end
                                  
             if(PID.device.NumBytesAvailable ~= 0)         % Controling incoming data

                if(PID.Drawing == 0)

                        PID.device.UserData.Data_Param(PID.Ind) = readline(PID.device);                                 % Reading from device
                        PID.Target_position_logic = strncmpi((PID.device.UserData.Data_Param(PID.Ind)),"Position",4);   % Comparing with string
                                           
        
                        if PID.Target_position_logic == 1  
        
                                PID.Target_position_count = PID.Ind;                                
                        end
        
                        % Writing data to textfield
                        PID.P_gain = strncmpi((PID.device.UserData.Data_Param(PID.Ind)),"P - ",4);                      
                        PID.I_gain = strncmpi((PID.device.UserData.Data_Param(PID.Ind)),"I - ",4);
                        PID.D_gain = strncmpi((PID.device.UserData.Data_Param(PID.Ind)),"D - ",4);
        
                        if PID.P_gain == 1 
        
                                PID.EditField.Value = PID.device.UserData.Data_Param(PID.Ind);
                                PID.P_gain = 0; 
        
                        end
        
                        if PID.I_gain == 1
        
                            PID.EditField2.Value =PID.device.UserData.Data_Param(PID.Ind);  
                            PID.I_gain = 0;
        
                        end

                        if PID.D_gain == 1
    
                            PID.EditField3.Value = PID.device.UserData.Data_Param(PID.Ind);
                            PID.D_gain = 0;
    
                        end

                          PID.BTN2 = strncmpi(PID.device.UserData.Data_Param(PID.Ind),"BTN2",4);

                            if PID.BTN2 == 1
                               
                                PID.Drawing = 1;
                                PID.Time = 1;
                                PID.BTN2 = 0;
                               
                                continue
                            end

                          PID.Ind = PID.Ind + 1;
                end

            if (PID.Drawing == 1)

                    PID.Target_position = str2double(PID.device.UserData.Data_Param(PID.Target_position_count + 1));
                    
                    PID.device.UserData.Data_string = readline(PID.device);
        
                    PID.BTN1 = strncmpi(PID.device.UserData.Data_string,"BTN1",4);


                        if PID.BTN1 == 1
            
                            PID.Ind = 1;
            
                            PID.Drawing = 0;
            
                            PID.BTN1 = 0;            
                           
                            continue
                         end

                            PID.device.UserData.Data(PID.Time) = str2double(PID.device.UserData.Data_string);
                
                            y_target = PID.Target_position;
                
                            y_current = PID.device.UserData.Data(PID.Time);
                            x = PID.Time/100;            
                             
                          
                            addpoints(PID.h,x,y_current); 
                            addpoints(PID.t,x,y_target);                
                            
                            
                            xlim([-0.5+x, 0.2+x]);
                            ylim([30 130]);
                            
                            drawnow limitrate
                            
                            PID.Time = PID.Time + 1; 

                        continue
        
                 end          
          
                    continue
            end
                 
          end
            

        end
   
        
%%
          function ButtonPushed2(PID, event)
            PID.Lamp.Color = 'blue';
             A = serialportlist("available");     

            PID.PortNameDropDown.Items = A;
    
          end
        
          function NEWFIG(PID, event)
            PID.Lamp.Color = 'yellow';
            close PID_regulation 
            PID.Read_logic = 1;
            PID.Button5.Value = 0;
            Createfig(PID); 
            ReadUart(PID,event);   
          end        

                       
        
            function CloseRequest(PID, event)
                fig = uifigure('Units','normalized','Position',[0 0.5-0.5*0.91 1 0.92]);
                selection = uiconfirm(fig,'Close the figure window?',...
                    'Confirmation');
                
                switch selection
                    case 'OK'
                        delete(fig)
                        delete(PID.UIFigure)
                    case 'Cancel'
                        return
                end   
            end
    end  
    
end