www.gusucode.com > Arduino_Engineering_Kit_Hardware_Support 工具箱matlab源码程序 > Arduino_Engineering_Kit_Hardware_Support/simulink/+codertarget/+arduinobase/+internal/arduinoUltrasonic.m

    classdef arduinoUltrasonic < matlab.System ...
                           & matlab.system.mixin.Propagates ...
                           & coder.ExternalDependency ...
                           & matlab.system.mixin.internal.SampleTime ...
                           & matlab.system.mixin.internal.CustomIcon 
    %Ultrasonic sensor.
    %      
    % Copyright 2018 The MathWorks, Inc.
    %#codegen
      
    properties(Nontunable)
       %NumSignalPins - Number of signal pins
       NumSignalPins  = '2';
       %TrigPin - Trigger pin
       TrigPin = 4;
       %EchoPin - Echo pin
       EchoPin = 5;   
       %SignalPin - Signal pin
       SignalPin = 3; 
       %SampleTime_ - Sample time
       SampleTime_ = 0.1;
       %Block Platform
        blockPlatform = 'ARDUINO';
    end       
      
    properties(Constant, Hidden)
        NumSignalPinsSet = matlab.system.StringSet({'1', '2'});                        
    end
 
    methods %constructor
        function obj = arduinoUltrasonic(varargin)
            %This would allow the code generation to proceed with the
            %p-files in the installed location of the support package.
            coder.allowpcode('plain');
            
            % Support name-value pair arguments when constructing the object.
            setProperties(obj,nargin,varargin{:});
        end
        
        function set.TrigPin(obj,val)
            classes = {'numeric'};
            attributes = {'nonempty','nonnan','finite','real','nonnegative','scalar','integer','<', 255};
            paramName = 'Trigger pin';
            validateattributes(val,classes,attributes,'',paramName);           
            obj.TrigPin = val;
        end
        
        function set.EchoPin(obj,val)
            classes = {'numeric'};
            attributes = {'nonempty','nonnan','finite','real','nonnegative','scalar','integer','<', 255};
            paramName = 'Echo pin';
            validateattributes(val,classes,attributes,'',paramName);           
            obj.EchoPin = val;
        end
         
        function set.SignalPin(obj,val)
            classes = {'numeric'};
            attributes = {'nonempty','nonnan','finite','real','nonnegative','scalar','integer','<', 255};
            paramName = 'Signal pin';
            validateattributes(val,classes,attributes,'',paramName);           
            obj.SignalPin = val;
        end
        
        function set.SampleTime_(obj, val)
            coder.extrinsic('error');
            coder.extrinsic('message');
            
            validateattributes(val,{'numeric'},...
                {'nonempty','nonnan', 'finite','real','>=',-1},...
                '','''Sample time''');
            
            % Sample time must be a real scalar value or 2 element array.
            if ~isreal(val(1)) || numel(val) > 2
                error(message('arduino:build:InvalidSampleTimeNeedScalar'));
            end
            if numel(val) == 2 && val(1) > 0.0 && val(2) >= val(1)
                error(message('arduino:build:InvalidSampleTimeNeedSmallerOffset'));
            end
            if numel(val) == 2 && val(1) == -1.0 && val(2) ~= 0.0
                error(message('arduino:build:InvalidSampleTimeNeedZeroOffset'));
            end
            if numel(val) == 2 && val(1) == 0.0 && val(2) ~= 1.0
                error(message('arduino:build:InvalidSampleTimeNeedOffsetOne'));
            end
            if numel(val) ==1 && val(1) < 0 && val(1) ~= -1.0
                error(message('arduino:build:InvalidSampleTimeNeedPositiveWiFi'));
            end
            obj.SampleTime_ = val;
        end
        
    end
    
    methods (Access = protected)
        %% Common functions
        function setupImpl(obj)
            % Call setup methods only when both Trigger and Echo pins are
            % present on the sensor     
            if strcmp(obj.NumSignalPins, '2')            
                if coder.target('Rtw')
                   coder.cinclude('MW_Ultrasonic.h');
                   coder.ceval('MW_UltrasonicSetup',uint8(obj.TrigPin), uint8(obj.EchoPin));  
                end
            else
                % No need of setup for sensors have 1 signal pin
            end
        end        
        
        function out = stepImpl(obj)
            % The output distance is of type double
            out = zeros(1,1, 'double');
            % Duration is the output of the pulseIn function in wrapper
            duration = zeros(1,1,'uint32');
            hasTrig = strcmp(obj.NumSignalPins, '2');
            if hasTrig
                Trig_Pin = obj.TrigPin;
                Echo_Pin = obj.EchoPin; 
                Trigger_Pulse_Duration = 10; % in microseconds for sensors with trigger and echo pin
            else              
                Trig_Pin = obj.SignalPin;
                Echo_Pin = obj.SignalPin;
                Trigger_Pulse_Duration = 5; % in microseconds for sensors with one signal pin
            end
            if coder.target('Rtw')
                 coder.ceval('MW_UltrasonicRead', coder.wref(duration), uint8(hasTrig), ...
                     uint8(Trig_Pin), uint8(Echo_Pin), uint8(Trigger_Pulse_Duration));
            end 
            
            % Ultrasonic sensor gives the duration in microseconds between 
            % the advent of the pulse till it returns back after hitting 
            % the object. This implies 2 times the distance of the detected 
            % object.  The speed of sound is 343 m/s or 
            % 343*1e-6 m per microsecond. Thus distance of the object is
            % (duration * (343*1e-6)) /2 meters.
            
            out =  (double(duration) * (343*1e-6)) / 2;
        end
        
       
        function flag = isInactivePropertyImpl(obj,prop)
            % Return false if property is visible based on object 
            % configuration, for the command line and System block dialog
            flag = false;
            if strcmp(prop, 'TrigPin')
                flag = strcmp(obj.NumSignalPins, '1');            
            end
            if strcmp(prop, 'EchoPin')
                flag = strcmp(obj.NumSignalPins, '1');            
            end
            if strcmp(prop, 'SignalPin')
                flag = strcmp(obj.NumSignalPins, '2');            
            end
        end
        
        
        function N = getNumInputsImpl(~)
            % Specify number of System inputs
            N = 0;
        end
        
        function N = getNumOutputsImpl(~)
            % Specify number of System outputs
            N = 1;            
        end
        
        function out = getOutputNamesImpl(~)
            % Return output port names for System block
            out = 'Distance';
        end
        
        function out= getOutputSizeImpl(~)
            % Return size for each output port
            out = [1 1];            
        end
        
        function out = getOutputDataTypeImpl(~)
            out = 'double';            
        end
        
        function out  = isOutputComplexImpl(~)
            out = false;   
        end
        
        function out = isOutputFixedSizeImpl(~)           
            out = true;
        end
        
        function st = getSampleTimeImpl(obj)
            st = obj.SampleTime_;
        end
        
        function maskDisplayCmds = getMaskDisplayImpl(~)          
            maskDisplayCmds = { ...
                'color(''white'');',...
                'plot([100,100,100,100]*1,[100,100,100,100]*1);',...
                'plot([100,100,100,100]*0,[100,100,100,100]*0);',...
                'color(''blue'');', ...
                'text(99, 92, '' ARDUINO '', ''horizontalAlignment'', ''right'');',   ...
                'color(''black'');', ...
                'sppkgroot = strrep(motorcarrier.internal.getSpPkgRootDir(),''\'',''/'');',...
                'image(fullfile(sppkgroot,''resources'',''ultrasonic_sensor.png''),''center'')'
                };
        end
    end
    
    methods(Static, Access = protected)
        % Note that this is ignored for the mask-on-mask
        function header = getHeaderImpl
            %getHeaderImpl Create mask header
            %   This only has an effect on the base mask.
            header = matlab.system.display.Header(mfilename('class'), ...
                'Title', 'Arduino Ultrasonic Sensor', ...
                'Text', sprintf('Measure the distance to an object in meters. \n\nThe block outputs distance as a double-precision value. If the object is placed beyond the sensor''s range of detection, the block outputs 0.'), ...
                'ShowSourceLink', false);
        end
        
        function simMode = getSimulateUsingImpl
            % Return only allowed simulation mode in System block dialog
            simMode = 'Interpreted execution';
        end
        
        function flag = showSimulateUsingImpl
            % Return false if simulation mode hidden in System block dialog
            flag = false;
        end
        
        function groups = getPropertyGroupsImpl(~)
            % Define section for properties in System block dialog box.
            NumSignalPinsProp = matlab.system.display.internal.Property(...
                'NumSignalPins', 'Description', 'Number of signal pins');
            TrigPinProp = matlab.system.display.internal.Property(...
                'TrigPin', 'Description', 'Trigger pin');
            EchoPinProp = matlab.system.display.internal.Property(...
                'EchoPin', 'Description', 'Echo pin');
            SignalPinProp = matlab.system.display.internal.Property(...
                'SignalPin', 'Description', 'Signal pin');
            SampleTimeProp = matlab.system.display.internal.Property(...
                'SampleTime_', 'Description', 'Sample time');           
            blockPlatformProp = matlab.system.display.internal.Property(...
                'blockPlatform', 'IsGraphical', false);
            Group = matlab.system.display.Section(...
                'Title', 'Parameters', 'PropertyList', ...
                    {NumSignalPinsProp,TrigPinProp,EchoPinProp,...
                        SignalPinProp, SampleTimeProp,blockPlatformProp});

            groups = Group;
            
            % Add the button for View Pin Map
            viewPinMapAction = matlab.system.display.Action(@codertarget.arduinobase.blocks.openPinMapping, ...
                'Alignment', 'right', ...
                'Placement','NumSignalPins',...
                'Label', 'View pin map');
            matlab.system.display.internal.setCallbacks(viewPinMapAction, ...
            'SystemDeletedFcn', @codertarget.arduinobase.blocks.closePinMapping);
            groups(1).Actions = viewPinMapAction;
        end
    end
    
    methods (Static)
        function name = getDescriptiveName(~)
            name = 'Arduino Ultrasonic Sensor';
        end
        
        function b = isSupportedContext(context)
            b = context.isCodeGenTarget('rtw');
        end
        
        function updateBuildInfo(buildInfo, context)           
            if context.isCodeGenTarget('rtw')               
                % Include Paths
                addIncludePaths(buildInfo, fullfile(motorcarrier.internal.getSpPkgRootDir, 'include'));
                
                % Source Files
                systemTargetFile = get_param(buildInfo.ModelName,'SystemTargetFile');
                if isequal(systemTargetFile,'ert.tlc')
                    % Add the following when not in rapid-accel simulation
                    srcFilePath = fullfile(motorcarrier.internal.getSpPkgRootDir, 'src');
                    fileNameToAdd = {'MW_Ultrasonic.cpp'};
                    addSourceFiles(buildInfo, fileNameToAdd, srcFilePath);     
                end

            end
        end
    end
end