✅作者简介:热爱科研的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.