How would I connect an torque screwdriver to MATLAB to simultaneously output a graph of Torque vs Time while my other code measures force from a sensor?
    조회 수: 10 (최근 30일)
  
       이전 댓글 표시
    
I am working on a research project that uses a MATLAB program that measures force from a donut hole FUTEK sensor in conjunction with implanted screws that go into bones. A screw goes into the hole on the sensor and compresses bone and we measure that force. Here is the sensor specs:

Essentially,  I am  attempting to use a digital torque screwdriver (this model: https://imada.com/products/cedar-did-4a-digital-torque-screwdriver/) to incorporate real-time continuous torque measurements and compare these with the force outputs from the written MATLAB program. My current task is centered on trying to incorporate this into the MATLAB program possibly by having it side by side on two different graphs with one being force data and one being torque amount which could then be filtered or even overlaying both sets. 
I am pretty new to MATLAB but have some experience and would like some suggestions on how to connect devices to the program and read their output and how I can add to this program to output torque from the screwdriver and compare it to the force. Any help is appreciated!
Here is the code for the project (written before I joined the project) that I am attempting to add to, it includes an app interface :
    % Properties that correspond to app components
    properties (Access = public)
        UIFigure                     matlab.ui.Figure
        cutoff                       matlab.ui.control.NumericEditField
        FilterCutoffEditFieldLabel   matlab.ui.control.Label
        order                        matlab.ui.control.NumericEditField
        FilterOrderEditFieldLabel    matlab.ui.control.Label
        ReadyButton                  matlab.ui.control.StateButton
        persecondLabel               matlab.ui.control.Label
        DataCollectionRateLabel      matlab.ui.control.Label
        DataRate                     matlab.ui.control.NumericEditField
        AppliedLoad                  matlab.ui.control.NumericEditField
        AppliedLoadkgEditFieldLabel  matlab.ui.control.Label
        CalibrationStatusLamp        matlab.ui.control.Lamp
        CalibrationStatusLampLabel   matlab.ui.control.Label
        SetupButton                  matlab.ui.control.Button
        FullCalibrationButton        matlab.ui.control.Button
        QuickCalibrationButton       matlab.ui.control.Button
        CheckCalibrationButton       matlab.ui.control.Button
        BoneViscoelasticityDataCollectionLabel  matlab.ui.control.Label
        Directions                   matlab.ui.control.Label
        txtLabel1                    matlab.ui.control.Label
        Filename                     matlab.ui.control.EditField
        FilenameEditFieldLabel       matlab.ui.control.Label
        StopButton                   matlab.ui.control.StateButton
        StartButton                  matlab.ui.control.Button
        TimeLabel                    matlab.ui.control.Label
        ResetButton                  matlab.ui.control.Button
        TurnGague                    matlab.ui.control.LinearGauge
        NumberofTurnsGaugeLabel      matlab.ui.control.Label
        TurnButton                   matlab.ui.control.Button
        UIAxes                       matlab.ui.control.UIAxes
    end
    methods (Access = private)
        function results = func(app)
        end
    end
    methods (Access = public)
        function results = func2(app)
        end
    end
    % Callbacks that handle component events
    methods (Access = private)
        % Button pushed function: TurnButton
        function TurnButtonPushed(app, event)
            app.TurnGague.Value = app.TurnGague.Value + 0.25;
        end
        % Button pushed function: ResetButton
        function ResetButtonPushed(app, event)
            app.TurnGague.Value = 0;
            app.StopButton.Value = 0;
            app.TimeLabel.Text = num2str(0);
            app.Directions.Text = 'Program reset. Type new filename for new data collection';
            global file;
            file = 1;
            pause (0.0001);
        end
        % Button pushed function: StartButton
        function StartButtonPushed(app, event)
            global filename
            global file
            global rate
            global order
            global cutoff
            if file == 1
                app.Directions.Text = 'Please type new filename for data collection';
            end
            if rate ~= 0 %prevents from dividing by zero
                timeconst = 1 / rate; %seconds between readings
            else
                timeconst = 0.1; %defaults to 10 times per second
            end
            stop = app.StopButton.Value;
            app.Directions.Text = 'beginning data collection';
            pause(1)
            global ard;
            global calZero;
            global calOffset;
            [b,a] = butter(order, cutoff);
            i = 0; %initialization of counter
            t=(tic);
            while (stop == 0 && file == 0)
                turns = app.TurnGague.Value;
                pause(0.00001);
                if toc >= (timeconst * i)
                    tstart=now();
                    time = toc(t);
                    app.TimeLabel.Text = num2str(time);
                    voltage = readVoltage(ard, 'A1');
                    compression = (voltage - calZero) / calOffset;
                    app.Directions.Text = strcat(num2str(compression), " Newtons");
                    pause(0.00001);
                    if i == 0
                        data = table(time, voltage, compression, turns);
                        plotdata = compression;
                        avg0 = compression;
                    elseif i == 1
                        T = table(time, voltage, compression, turns);
                        data = vertcat(data, T);
                        plotdata = [plotdata ((compression + avg0) / 2)];
                        avg1 = compression;
                    else
                        T = table(time, voltage, compression, turns);
                        data = vertcat(data, T);
                        plotdata = [plotdata ((compression + avg0 + avg1) / 3)];
                        avg0 = avg1;
                        avg1 = compression;
                    end
                    writetable(data, filename);
                    plot(app.UIAxes, data.time, plotdata);
                    i = i + 1;
                    stop = app.StopButton.Value;
                    pause(0.001);
                end
                %app.Directions.Text= strcat(num2str(now()-tstart), " time");
            end
            filtered = filter(b,a,data.compression);
            time = data.time;
            turns = data.turns;
            T2 = table(time, filtered, turns);
            filename2 = strcat(erase(filename, ".xlsx"), "_filtered.xlsx");
            writetable(T2, filename2);
            if file == 0
            app.Directions.Text = 'Data collection ended. Reset to collect new data';
            end
        end
        % Value changed function: Filename
        function FilenameValueChanged(app, event)
            global filename 
            filename = app.Filename.Value;
            t = datetime('now'); %append with date time to prevent overwriting data
            filename = strcat(filename, '_');
            filename = strcat(filename, datestr(t, 'mm.dd.yy_HH.MM.SS'));
            filename = strcat(filename, '.xlsx'); %makes output an excel spreadsheet file
            global file
            file = 0;
            app.Directions.Text = 'press start when ready';
        end
        % Button pushed function: SetupButton
        function SetupButtonPushed(app, event)
            global ard;
            if ~isempty(instrfind)
                fclose(instrfind);
                delete(instrfind);
            end
            if isempty(ard) == 1
                ard = arduino('/dev/cu.usbmodem1301','Mega2560');
            end
            cfile = fopen('calibData.txt', 'r');
            cdata = fscanf(cfile, '%f\n');
            fclose('all');
             %create global variables with calibration constants
            global calZero
            calZero = cdata(1);
            global calOffset
            calOffset = cdata(2);
            global rate
            rate = app.DataRate.Value;
            global order
            order = app.order.Value;
            global cutoff
            cutoff = app.cutoff.Value;
            app.Directions.Text = 'Setup Complete. Run calibration check or enter filename to begin data collection.';
        end
        % Value changed function: DataRate
        function DataRateValueChanged(app, event)
            global rate
            rate = app.DataRate.Value;
        end
        % Button pushed function: CheckCalibrationButton
        function CheckCalibrationButtonPushed(app, event)
            app.Directions.Text = 'Please remove all load from sensor and press Ready';
            go = 0;
            while go == 0
                go = app.ReadyButton.Value;
                pause(0.01)
            end
            app.Directions.Text = 'Measuring zero';
            pause(1)
            global ard 
            global calZero
            global calOffset
            %run a loop to measure output with zero load
            val = zeros(20,1);
            i = 0;
            timeconst = 0.1;
            tic
            while i < 20
                if toc > (timeconst * i)
                    val(i + 1) = readVoltage(ard, 'A1');
                    i = i + 1;
                end
            end
            checkzero = mode(val);
            app.ReadyButton.Value = 0;
            app.Directions.Text = 'Please load sensor with tray and 25lb weight and press Ready';
            go = 0;
            while go == 0
                go = app.ReadyButton.Value;
                pause(0.01)
            end
            app.Directions.Text = 'Measuring weight';
            pause(1);
            %run a loop to measure output with load
            val = zeros(20,1);
            i = 0;
            tic
            while i < 20
                if toc > (timeconst * i)
                    val(i + 1) = readVoltage(ard, 'A1');
                    i = i + 1;
                end
            end
            checkoffset = mode(val);
            checkoffset = (checkoffset - checkzero) / 117.4 %load in newtons from tray and weight
            checkoffset = abs(checkoffset - calOffset) / calOffset; 
            checkzero = abs(checkzero - calZero) / calZero %calculate the error
            if (checkzero < 0.01) && (checkoffset < 0.01)
                calib = 0
            elseif checkzero < 0.01
                calib = 1;
            elseif checkoffset < 0.01
                calib = 1;
            elseif (checkzero < 0.05) && (checkoffset < 0.05)
                calib = 1;
            else
                calib = 2;
            end
            switch calib
                case 0
                    txt = strcat('Calibration is good. Checkzero = ', num2str(checkzero));
                    txt = strcat(txt, ', Checkoffset =', num2str(checkoffset));
                    app.Directions.Text = txt;
                    app.CalibrationStatusLamp.Color = 'green';
                case 1
                    txt = strcat('Calibration is slightly off. Quick calibration recommended. Checkzero = ', num2str(checkzero));
                    txt = strcat(txt, ', Checkoffset =', num2str(checkoffset));
                    app.Directions.Text = txt;
                    app.CalibrationStatusLamp.Color = 'yellow';
                case 2
                    txt = strcat('Calibration is off. Quick or full calibration necessary. Checkzero = ', num2str(checkzero));
                    txt = strcat(txt, ', Checkoffset =', num2str(checkoffset));
                    app.Directions.Text = txt;                   
                    app.CalibrationStatusLamp.Color = 'red';
            end
            app.ReadyButton.Value = 0;
        end
        % Button pushed function: QuickCalibrationButton
        function QuickCalibrationButtonPushed(app, event)
            %copy current calibration values to new file
            cfile = fopen('calibData.txt', 'r');
            t = datetime('now'); %append with date time to show old calibration
            newfile = strcat('calibDataBefore', datestr(t, 'mm.dd.yy_HH.MM.SS'));
            newfile = strcat(newfile, '.txt');
            cfilenew = fopen(newfile, 'w');
            cdata = fscanf(cfile, '%f\n');
            fprintf(cfilenew, '%f\n', cdata);
            fclose('all');
            %measure different loads, starting at zero
            app.Directions.Text = 'Please remove all load from sensor for calibration and press Ready';
            go = 0;
            while go == 0
                go = app.ReadyButton.Value;
                pause(0.01)
            end
            app.Directions.Text = 'Calibrating zero';
            pause(1)
            weights = [0; 54.286; 117.143];
            val = zeros(20,1);
            i = 0;
            timeconst = 0.1;
            global ard
            tic
            while i < 20
                if toc > (timeconst * i)
                    val(i + 1) = readVoltage(ard, 'A1');
                    i = i + 1;
                end
            end
            zcal = mode(val);
            %repeat with small weight
            app.ReadyButton.Value = 0;
            app.Directions.Text = 'Please load sensor with tray and 10lb weight and press Ready';
            go = 0;
            while go == 0
                go = app.ReadyButton.Value;
                pause(0.01)
            end
            app.Directions.Text = 'Calibrating weight';
            pause(1)
            val = zeros(20,1);
            i = 0;
            tic
            while i < 20
                if toc > (timeconst * i)
                    val(i + 1) = readVoltage(ard, 'A1');
                    i = i + 1;
                end
            end
            wcalsmall = mode(val);
            %repeat with larger weight
            app.ReadyButton.Value = 0;
            app.Directions.Text = 'Please load sensor with tray and 25lb weight and press Ready';
            go = 0;
            while go == 0
                go = app.ReadyButton.Value;
                pause(0.01)
            end
            app.Directions.Text = 'Calibrating weight';
            pause(1)
            val = zeros(20,1);
            i = 0;
            tic
            while i < 20
                if toc > (timeconst * i)
                    val(i + 1) = readVoltage(ard, 'A1');
                    i = i + 1;
                end
            end
            wcalbig = mode(val);
            %calculate calibration constants
            global calZero
            global calOffset
            voltages = [zcal; wcalsmall; wcalbig];
            W = [ones(length(weights), 1) weights];
            B = W\voltages; %calculates linear regression
            calZero = B(1);
            calOffset = B(2);
            app.CalibrationStatusLamp.Color = 'green';
            %overwrite calibration file with new calibration constants
            cfile = fopen('calibData.txt', 'w');
            fprintf(cfile, '%f\n', B);
            fclose('all');
            app.ReadyButton.Value = 0;
        end
        % Value changed function: AppliedLoad
        function AppliedLoadValueChanged(app, event)
            global load
            load = app.AppliedLoad.Value;
        end
        % Button pushed function: FullCalibrationButton
        function FullCalibrationButtonPushed(app, event)
            %copy current calibration values to new file
            cfile = fopen('calibData.txt', 'r');
            t = datetime('now'); %append with date time to show old calibration
            newfile = strcat('calibDataBefore', datestr(t, 'mm.dd.yy_HH.MM.SS'));
            newfile = strcat(newfile, '.txt');
            cfilenew = fopen(newfile, 'w');
            cdata = fscanf(cfile, '%f\n');
            fprintf(cfilenew, '%f\n', cdata);
            fclose('all');
            %define weights and calculate all values
            weightskg = [0; 10; 25; 50; 75; 100; 125; 150; 175; 200];
            weightsN = weightskg * 9.807;
            voltages = zeros(10, 1);
            i = 1;
            global ard
            global load
            timeconst = 0.1;
            while i <= 10
                app.ReadyButton.Value = 0;
                txt = strcat('Please load sensor with ', num2str(weightskg(i)));
                txt = strcat(txt, ' kilograms and enter exact value then press Ready');
                app.Directions.Text = txt;
                go = 0;
                while go == 0
                    go = app.ReadyButton.Value;
                    pause(0.01)
                end
                weightsN(i) = load * 9.807;
                val = zeros(20,1);
                j = 0;
                tic
                while j < 20
                    if toc > (timeconst * i)
                        val(j + 1) = readVoltage(ard, 'A1');
                        j = j + 1;
                    end
                end
                voltages(i) = mode(val);
                i = i + 1;
            end
            %calculate linear regression and save as global calibration constants
            W = [ones(length(weightsN), 1) weightsN];
            B = W\voltages; %calculates linear regression
            global calZero
            global calOffset
            calZero = B(1);
            calOffset = B(2);
            app.CalibrationStatusLamp.Color = 'green';
            %overwrite calibration file with new calibration constants
            cfile = fopen('calibData.txt', 'w');
            fprintf(cfile, '%f\n', B);
            fclose('all');
            app.ReadyButton.Value = 0;
        end
댓글 수: 0
답변 (1개)
  Nathan Blanc
      
 2024년 3월 6일
        The answer to this depends on your hardware for torque measurments. almost any data acquisition hardware can be read using the data acquisition toolbox. Alternativeky, If your measurments can be continously recorded to a file, you can  periodically read from the file using matlab.
e.g. the following code will read from the file 'blabla.text' every second and plot the data.
fileID = fopen('blabla.txt','r');
while true
    A = fscanf(fileID,'%f');
    plot(A);
    pause(1)
end
fclose(fileID);
댓글 수: 0
참고 항목
카테고리
				Help Center 및 File Exchange에서 Web Services에 대해 자세히 알아보기
			
	제품
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

