基于Matlab模拟交互式玻璃化转变分析仪 (DSC)

该文介绍了一种使用Matlab进行动态热分析(DSC)数据的函数,用于分析和交互式选择LED封装环氧树脂的玻璃化转变温度测试条件。通过平滑数据并使用可拖动的垂直线选择分析区域,确定玻璃化转变的起始和中间点。文章包含示例代码,展示了如何在噪声信号中提取信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。

🍎个人主页:Matlab科研工作室

🍊个人信条:格物致知。

更多Matlab仿真内容点击👇

智能优化算法       神经网络预测       雷达通信       无线传感器        电力系统

信号处理              图像处理               路径规划       元胞自动机        无人机 

⛄ 内容介绍

DSC作为一种主要的热分析方法,适用于各种固化体系,应用很普遍.文章介绍了DSC的相关基础知识,研究了利用DSC测定LED封装环氧树脂的玻璃化转变温度的测试条件,对不同的测试条件进行了比较和评定,并进行了相关测试

⛄ 完整代码

% Version 1.0

% Robin Hartley (PhD), University of Bristol, Bristol Composites, Institute, Bristol, United Kingdom

%      - This is a function that analyses dynamic DSC data for glass

%      transitions using a GUI which allows you to smooth the data

%      interactively and interactively select the analysis regions using

%      draggable verticle lines

%

%      - Variables:

%           Temperature - DSC temperature data (°C)

%           DSCsignal - DSC data (mW/mg)

%      - Outputs:

%           TgOnset - Glass transition onset

%           TgMid - Glass transition midpoint

%Here is a demonstration of how it works using a sin wave:

function [TgOnset,TgMid] = GlassTransitionFunc

% Define sine wave parameters

t = 0:0.01:1; % time vector

f = 1; % frequency of sine wave

A = 1; % amplitude of sine wave

sine_wave = A*sin(2*pi*f*t); % generate sine wave

% Add noise to sine wave

SNR = 25; % signal-to-noise ratio

noise_power = (norm(sine_wave)^2)/(length(sine_wave)*10^(SNR/10));

noise = sqrt(noise_power)*randn(size(sine_wave));

noisy_sine_wave = sine_wave + noise; % add noise to sine wave

Temp = t;

HeatFlow = noisy_sine_wave;

[TgOnset,TgMid] = TGLine(Temp,HeatFlow);

end

function [TgOnset,TgMid] = TGLine(xdata,ydata)

hLineToDrag = [];

smooth_ydata = sgolayfilt(ydata,3,11);   %Set up initially smoothed y signal

%Create figure window

h_fig = figure;

h_fig.UserData.isButtonDown = false;   %Create flag for mousedown event within figure

%Set up data associated with the figure handle

setappdata(h_fig,'xdata',xdata)

setappdata(h_fig,'ydata1',ydata)

setappdata(h_fig,'ydata2',smooth_ydata)

%Create axes window

h_ax1 = axes('unit','norm','Position',[0.1 0.22 0.85 0.75]);

%Select suitable axes limits and associate the figure handle

yrange = range(ydata);

xl = [min(xdata) max(xdata)];

yl = [min(ydata)-yrange*0.1 max(ydata)+yrange*0.1];

setappdata(h_fig,'xlims',xl);

setappdata(h_fig,'ylims',yl);

setappdata(h_fig,'axes_handle',h_ax1);   %associate axes with figure handle

%Plot data and initialise the draggable vertical lines

updatePlot(h_fig,h_ax1);

initiateVertLines(h_fig,h_ax1)

%Creat button used to save the data and figure

FinalTgButton = uicontrol('units','normalized','Position',[0.65 0.05 0.2 0.05],'String','OKAY',...

    'Callback', @FinaliseTgButton);

TgLinePlot(h_fig)

h_sld = uicontrol('Style', 'slider',...

    'Min',5,'Max',length(ydata)*0.3,'Value',25,...

    'unit','norm',...

    'Tag','Slider',...

    'Position', [0.05 0.05 0.4 0.05],...

    'Callback', @slider_callback);

%

setappdata(h_sld,'xdata',xdata)

setappdata(h_sld,'ydata1',ydata)

setappdata(h_sld,'ydata2',smooth_ydata)

setappdata(h_sld,'fig_handle',h_fig);

setappdata(h_sld,'axes_handle',h_ax1);

Framelengthtext = uicontrol('Style','text','String','Smoothing Framelength:','unit','norm','Position',[0 0.01 0.5 0.05]);

setappdata(h_sld,'valText', Framelengthtext);

set(h_fig, 'WindowButtonDownFcn', @my_downbutton_function);

% Define the persistent variables to store the values of a and b

persistent pTgOnset

persistent pTgMid

if isempty(pTgOnset) || isempty(pTgMid)

    pTgOnset = 0;

    pTgMid = 0;

end

% Wait for the figure to be closed

waitfor(h_fig);

% Return the values of a and b using the nested function

[pTgOnset, pTgMid] = getOutput();

TgOnset = pTgOnset;

TgMid = pTgMid;

    function my_downbutton_function(h_fig,~)

        % This is the callback function that will be called when the mouse button is pressed down on the figure

        % src: the source object that triggered the event (figure or axes handle)

        % event: the event data structure

        % Set a flag to indicate whether the mouse pointer is within the x range

        hVerticalLines = getappdata(h_fig,'VerticalLines');

        xVLC = get(hVerticalLines,'XData');

        xVertLineCoord1 = xVLC{1}(1);

        xVertLineCoord2 = xVLC{2}(1);

        x = getappdata(h_fig,'xdata');

        xrange = range(x);

        xpercentage = 0.00625;

        x_min1 = xVertLineCoord1-xrange*xpercentage;

        x_max1 = xVertLineCoord1+xrange*xpercentage;

        x_min2 = xVertLineCoord2-xrange*xpercentage;

        x_max2 = xVertLineCoord2+xrange*xpercentage;

        % Get the initial mouse press coordinates

        initial_coords = get(gca, 'CurrentPoint');

        initial_x = initial_coords(1,1);

        [~,I] = min(abs([xVertLineCoord1 xVertLineCoord2]-initial_x));

        if (initial_x >= x_min1 && initial_x <= x_max1) || (initial_x >= x_min2 && initial_x <= x_max2)

            in_x_range = true;

            set(h_fig, 'WindowButtonMotionFcn', @motion_callback_function);

            set(h_fig, 'WindowButtonUpFcn', @up_callback_function);

        else

            in_x_range = false;

        end

        function motion_callback_function(h_fig,~)

            % This is the callback function that will be called repeatedly while the mouse button is pressed down and the mouse is moving

            % src: the source object that triggered the event (figure or axes handle)

            % event: the event data structure

            % Get the current mouse coordinates

            current_coords = get(gca, 'CurrentPoint');

            % Check if the mouse is within the y range or has moved out of it

            if (initial_x >= x_min1 && initial_x <= x_max1) || (initial_x >= x_min2 && initial_x <= x_max2)

                in_x_range = false;

            end

            hLineToDrag = hVerticalLines(I);

            set(hLineToDrag,'XData',[current_coords(1, 1) current_coords(1, 1)]);

            updatePlot2(h_fig)

        end

        function up_callback_function(~,~)

            % This is the callback function that will be called when the mouse button is released

            % src: the source object that triggered the event (figure or axes handle)

            % event: the event data structure

            % Reset the 'WindowButtonMotionFcn' and 'WindowButtonUpFcn' callbacks

            set(gcf, 'WindowButtonMotionFcn', '');

            set(gcf, 'WindowButtonUpFcn', '');

            % Reset the in_y_range flag

            in_x_range = false;

        end

    end

    function updatePlot(h_fig,h_ax1)

        x = getappdata(h_fig,'xdata');

        y1 = getappdata(h_fig,'ydata1');

        y2 = getappdata(h_fig,'ydata2');

        xl = getappdata(h_fig,'xlims');

        yl = getappdata(h_fig,'ylims');

        h1 = plot(h_ax1,x,y1,'b');

        setappdata(h_fig,'NoisyLine',h1)

        hold on

        stack = dbstack();

        if numel(stack) > 1 && strcmp(stack(2).name,'TGLine')

            h2 = plot(h_ax1,x,y2,'r');

            setappdata(h_fig,'SmoothLine',h2)

        else

            if numel(stack) > 1 && strcmp(stack(2).name,'TGLine/slider_callback')

                h2 = getappdata(h_fig,'SmoothLine');

                delete(h2);

                h2 = plot(x,y2,'r');

                setappdata(h_fig,'SmoothLine',h2)

            end

        end

        legend([h1, h2],'Original signal','Smoothed signal');

        xlabel('Temperature / °C');

        ylabel('DSC Signal / mW mg^{-1}');

        xlim(xl);

        ylim(yl);

    end

    function initiateVertLines(h_fig,h_ax1)

        stack = dbstack();

        if numel(stack) > 1 && strcmp(stack(2).name,'TGLine')

            x = getappdata(h_fig,'xdata');

            randt = randi([1,round(length(x)/2)-1]);

            hVerticalLines = line([x(randt),x(randt)],get(h_ax1,'Ylim'),'Color','green');

            randt = randi([round(length(x)/2)+1,length(x)]);

            hVerticalLines = [hVerticalLines line([x(randt),x(randt)],get(h_ax1,'Ylim'),'Color','red')];

            setappdata(h_fig,'VerticalLines',hVerticalLines)

        end

    end

    function slider_callback(h_sld,~)

        y1 = getappdata(h_sld,'ydata1');

        h_fig = getappdata(h_sld,'fig_handle');

        h_ax1 = getappdata(h_sld,'axes_handle');

        Framelengthtext = getappdata(h_sld,'valText');

        framelen = floor(h_sld.Value/2)*2 + 1;

        order = 3;

        ymooth = sgolayfilt(y1,order,framelen);

        setappdata(h_fig,'ydata2',ymooth)

        set(Framelengthtext,'String',sprintf('Smoothing Framelength: %.0f', framelen));

        updatePlot(h_fig,h_ax1);

        updatePlot2(h_fig)

    end

    function TgLinePlot(h_fig)

        hVerticalLines = getappdata(h_fig,'VerticalLines');

        xl = getappdata(h_fig,'xlims');

        yl = getappdata(h_fig,'ylims');

        xx = getappdata(h_fig,'xdata');

        yy = getappdata(h_fig,'ydata2');

        %Find the gradient (FX)

        FX = zeros(length(xx),1);

        FX(1:length(xx)-1) = diff(yy)./diff(xx);

        FX(end) = FX(end-1);

        % Find equations for tangential lines at onset and end of Tg

        for i = 1:length(hVerticalLines)

            xVLC(i,:) = get(hVerticalLines(i),'XData');        %x coordinate of vertical lines

        end

        xVertLineCoord = xVLC(:,1);

        [~,I1] = min(abs(xx-xVertLineCoord(1)));       %index of vertical line 1

        [~,I2] = min(abs(xx-xVertLineCoord(2)));       %index of vertical line 2

        AvWinPM = 10;                                   %plus minus widow for gradient either side of index

        if I1 < AvWinPM+1

            Grad1 = mean(FX(1:I1+AvWinPM));

        else

            Grad1 = mean(FX(I1-AvWinPM:I1+AvWinPM));

        end

        if I2 > length(xx)-AvWinPM

            Grad2 = mean(FX(I2-AvWinPM:end));

        else

            Grad2 = mean(FX(I2-AvWinPM:I2+AvWinPM));

        end

        Int1 = yy(I1)-(xx(I1)*Grad1);     %tangent at index of line 1 intercept

        Int2 = yy(I2)-(xx(I2)*Grad2);     %tangent at index of line 2 intercept

        f1 = @(x) (Grad1*x)+Int1;         %function of tangent line 1

        f2 = @(x) (Grad2*x)+Int2;         %function of tangent line 2

        % Find equation for middle line

        % [M3,Ihalf] = min(abs(yy(I1:I2)-mean([yy(I1) yy(I2)])));      %find the index of the point that is closest to halfway between yy at I1 and I2

        [~,Ihalf] = max(abs(FX(I1:I2)));                           %find the point with highest gradient

        I3 = I1+Ihalf;

        if I3 < AvWinPM+1

            Grad3 = mean(FX(1:I3+AvWinPM));

        else

            if I3 > length(xx)-AvWinPM

                Grad3 = mean(FX(I3-AvWinPM:end));

            else

                Grad3 = mean(FX(I3-AvWinPM:I3+AvWinPM));       %find the gradient at that point

            end

        end

        Int3 = yy((I3))-(xx((I3))*Grad3);   %find the y intercept of middle line

        f3 = @(x) (Grad3*x)+Int3;     %function of middle line

        line1 = fplot(f1,[xx(1) xx(I2)],'Color','k','HandleVisibility','off');

        line2 = fplot(f2,[xx(I1) xx(end)],'Color','k','HandleVisibility','off');

        line3 = fplot(f3,[xx(I1) xx(I2)],'Color','k','HandleVisibility','off');

        x = sym('x');

        f4 = @(x) f1(x)-f3(x) == 0;

        ponsetx = double(solve(f4,x));

        ponsety = double(f1(ponsetx));

        f5 = @(x) f2(x)-f3(x) == 0;

        pfinishx = double(solve(f5,x));

        pfinishy = double(f2(pfinishx));

        ponset = plot(ponsetx,ponsety,'r*','HandleVisibility','off');

        pfinish = plot(pfinishx,pfinishy,'r*','HandleVisibility','off');

        %%IF USING THE MIDPOINT

        % pmidx = mean([ponsetx pfinishx]);

        % pmidy = mean([ponsety pfinishy]);

        %%IF USING THE MAX GRADIENT

        pmidx = xx(I3);

        pmidy = yy(I3);

        pmid = plot(pmidx,pmidy,'r*','HandleVisibility','off');

        OnsetAnnot = text(ponsetx,ponsety,['\leftarrow ''Onset = ' num2str(ponsetx,'%.1f') ' °C']);

        MidAnnot = text(pmidx,pmidy,['\leftarrow ''Mid = ' num2str(pmidx,'%.1f') ' °C']);

        xlim(xl);

        ylim(yl);

        setappdata(h_fig,'line1',line1)

        setappdata(h_fig,'line2',line2)

        setappdata(h_fig,'line3',line3)

        setappdata(h_fig,'ponset',ponset)

        setappdata(h_fig,'pfinish',pfinish)

        setappdata(h_fig,'pmid',pmid)

        setappdata(h_fig,'OnsetAnnot',OnsetAnnot)

        setappdata(h_fig,'MidAnnot',MidAnnot)

        setappdata(h_fig,'ponsetx',ponsetx)

        setappdata(h_fig,'pmidx',pmidx)

    end

    function updatePlot2(h_fig)

        line1 = getappdata(gcf,'line1');

        line2 = getappdata(gcf,'line2');

        line3 = getappdata(gcf,'line3');

        ponset = getappdata(gcf,'ponset');

        pfinish = getappdata(gcf,'pfinish');

        pmid = getappdata(gcf,'pmid');

        OnsetAnnot = getappdata(gcf,'OnsetAnnot');

        MidAnnot = getappdata(gcf,'MidAnnot');

        delete(line1)

        delete(line2)

        delete(line3)

        delete(ponset)

        delete(pfinish)

        delete(pmid)

        delete(OnsetAnnot)

        delete(MidAnnot)

        TgLinePlot(h_fig)

    end

    function FinaliseTgButton(~,~)

        ponsetx = getappdata(gcf,'ponsetx');

        pmidx = getappdata(gcf,'pmidx');

        pTgOnset = ponsetx;

        pTgMid = pmidx;

        % ResultsDir = uigetdir;

        % prompt = 'Enter filename to save';

        % dlgtitle = 'Input';

        % dims = [1 35];

        % savename = inputdlg(prompt,dlgtitle,dims);

        % savefig([ResultsDir '\' savename{1,1} '.fig'])

        close all

    end

    function [pTgOnsetOut, pTgMidOut] = getOutput()

        % Return the values of a and b

        pTgOnsetOut = pTgOnset;

        pTgMidOut = pTgMid;

    end

end

⛄ 运行结果

⛄ 参考文献

[1]林达儒, 谭艳娥, 龚丹雷,等. 利用DSC测定LED封装环氧树脂玻璃化转变温度[J]. 电子与封装, 2012, 12(10):5.

[2]蒙根, 许中强, 朱海燕. DSC法测定SMA共聚物玻璃化转变温度的影响因素[C]// 中国化工学会2008年学术年会. 0.

❤️部分理论引用网络文献,若有侵权联系博主删除

❤️ 关注我领取海量matlab电子书和数学建模资料

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

matlab科研助手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值