www.gusucode.com > Arduino_Engineering_Kit_Hardware_Support 工具箱matlab源码程序 > Arduino_Engineering_Kit_Hardware_Support/matlab/MATLABAddon/+arduinoioaddons/+arduino/MKRRotaryEncoder.m

    classdef MKRRotaryEncoder < arduinoio.AddonBase & matlab.mixin.CustomDisplay
%MKRRotaryEncoder Create a rotary encoder object 
%
% encoder1 = rotaryEncoder(mkrcarrier, 1) Creates a encoder object at
% channel 1 of MKR motor carrier
%
% Copyright 2018 The MathWorks, Inc.

    properties(Access = private, Constant = true)
        CREATE_ENCODER = hex2dec('0A')
        RESET_ENCODER_COUNT = hex2dec('0B')        
        READ_ENCODER_COUNT = hex2dec('0C')         
        READ_ENCODER_SPEED  = hex2dec('0D')
        DELETE_ENCODER  = hex2dec('0E')
    end
     properties(Access = private)
        ResourceOwner = 'MKRMotorCarrier\Encoder';
    end
    properties(SetAccess = immutable)
        Channel = 1
        Encoding  = 'X4'
    end    
    properties(Access = private, Constant = true)
        MaxEncoders = 2
        CountsPerRev = 1200
        ResourceMode = 'MKRMotorCarrier\Encoder';
    end
    methods(Hidden, Access = public)
        function obj = MKRRotaryEncoder(parentObj,channel,varargin)
            obj.Parent = parentObj;
            arduinoObj = parentObj.Parent;
            try
                if (nargin < 2)
                    obj.localizedError('MATLAB:minrhs');
                end
            catch e
                throwAsCaller(e);
            end
            channel = arduinoio.internal.validateIntParameterRanged( ...
                [obj.ResourceOwner 'channel'], ...
                channel, ...
                1, ...
                obj. MaxEncoders);   
            
            try
                encoders = getSharedResourceProperty(arduinoObj, obj.ResourceOwner, 'encoders');
            catch 
                locEn = 1; %#ok<NASGU>
                encoders = [parentObj.I2CAddress zeros(1, obj.MaxEncoders)];
            end
            carrierEnAddresses = encoders(:, 1);
            [~, locEn] = ismember(parentObj.I2CAddress, carrierEnAddresses);
            if locEn == 0
                encoders = [encoders; parentObj.I2CAddress zeros(1, obj.MaxEncoders)];
                locEn = size(encoders, 1);
            end
            
            % Check for resource conflict with Encoders
            if encoders(locEn, channel+1)
                error('Arduino:MKRMotorCarrier:conflictEncoderMKR', 'ArduinoMKRMotorCarrier\\\\Encoder ''%d'' is already in use', channel);
            end
            encoders(locEn, channel+1) = 1;
            setSharedResourceProperty(arduinoObj, obj.ResourceOwner, 'encoders', encoders);
            obj.Channel = channel;
            p = inputParser;           
            addParameter(p, 'Encoding', 'X4');
            parse(p,varargin{:});            
            obj.Encoding = p.Results.Encoding;
            createEncoder(obj);
            obj.Parent.EncoderExists(obj.Channel) = true;
        end
    end
    %% 
    methods
        function resetCount(obj,count)
            try
                commandID = obj.RESET_ENCODER_COUNT;
                if nargin < 2
                    count = 0;
                end
                try
                    validateattributes(count, {'double', 'int32'}, {'scalar', 'real', 'integer', 'finite', 'nonnan', '<=', intmax, '>=', intmin});
                catch
                    obj.localizedError('MATLAB:arduinoio:general:invalidEncoderCount', num2str(intmin), num2str(intmax));
                end
                data = typecast(int32(count), 'uint8'); 
                params = [obj.Channel-1, data];
                sendCommand(obj,commandID, params);
            catch e
                throwAsCaller(e);
            end
        end
        function count = readCount(obj)
            commandID = obj.READ_ENCODER_COUNT;
            params = obj.Channel-1;
            countByte = sendCommand(obj,commandID,params);
            %convert to int32 count
            count = double(typecast(uint8(countByte(1:4)),'int32'));
            %convert to int16 count
            overflowStatus = countByte(5);
            underflowStatus = countByte(6);
         end
        function rpm = readSpeed(obj)
            commandID = obj.READ_ENCODER_SPEED;
            params = obj.Channel-1;
            countByte = sendCommand(obj,commandID,params);
            countPerCentiSec = double(typecast(uint8(countByte),'int32'));   
            countPerSec = countPerCentiSec * 100;
            rpm = (countPerSec*60)/obj.CountsPerRev; % converting revolutions per sec to rpm by multiplying with 60
        end
    end
    %% Private methods
    methods(Access = private)
        function createEncoder(obj)
            commandID = obj.CREATE_ENCODER;
            if strcmpi(obj.Encoding,'X1')
                encoding = 0;
            elseif strcmpi(obj.Encoding , 'X2')
                encoding = 1;
            else
                encoding = 2;
            end
            params = [obj.Channel-1,encoding];
            sendCommand(obj,commandID,params);
        end
    end
     %% Protected methods
    methods(Access = protected) 
        function delete(obj)
            originalState = warning('off','MATLAB:class:DestructorError');
            try
                parentObj = obj.Parent;
                arduinoObj = parentObj.Parent;               
                % Clear the Encoder Motor
                if ~isempty(obj.Channel)
                    %no delete yet for encoder
                end
                encoders = getSharedResourceProperty(arduinoObj, obj.ResourceOwner, 'encoders');
                carrierEnAddresses = encoders(:, 1);
                [~, locEn] = ismember(parentObj.I2CAddress, carrierEnAddresses);
                encoders(locEn, obj.Channel+1) = 0;
                setSharedResourceProperty(arduinoObj, obj.ResourceOwner, 'encoders', encoders);  
                obj.Parent.EncoderExists(obj.Channel) = false;
            catch
                % Do not throw errors on destroy.
                % This may result from an incomplete construction.
            end
            warning(originalState.state, 'MATLAB:class:DestructorError');
        end
        function output = sendCommand(obj, commandID, params)            
            output = sendCarrierCommand(obj.Parent, commandID, params);
        end
    end
end