综合测控实验
班级:
组员:
铂电阻温度测量实验
一、实验目的
1、了解铂电阻的温度特性与曲线,学会用铂电阻测量温度
2、学会使用matlab编程,采集电压信号波形并显示在面板上
3、了解并掌握信号处理方法,将采集到的电压信号转换成温度信号显示出来
二、实验原理
1、铂电阻测温原理。
金属铂电阻的性能十分稳定,在-260°C~+630°C之间,铂热电阻用作标准温度计,在0~630°C之间铂电阻与温度呈如下关系:
Rt=R0(1+AT+BT²)
式中:R0=1000Ω,A=0.3973973*10-²,B=-0.58973*10-6
恒压型的铂电阻测温电路如图所示,该电路也是常用的测温电路之一,其中Vin
为恒定输入电压,W1用于零点调整,W2用于范围调整,该电路的输出电压Vout
为:
Vout=R1ΔR*Vin/(R1+R0+ΔR)(R1+R0)
由式可知,在恒压条件下,其输出电压取决于Vin和R1。当R1=22KΩ,Vin=12V
时,在0~100°C范围内,电路灵敏度为1.89mV/°C.
本实验采用铂电阻PT100,它在0°时候对应的电阻为1K,可以用其分度表查询
阻值对应的温度,可以发现其温度几乎呈线性变化。
2、数据采集与操作。
利用matlab编程,将采集到的电压信号波形显示出来,并将其电压对应的温度
计算后显示出来。调节试验箱的变阻器以使电路的电压对应的温度值等于实时温
度以进行标定再列出温度电压关系。具体步骤分为:
1、SIMULINK动态仿真。
Simulink模块包括一系列输入、状态和输出。输出是采样时间、输入、模块状态
的函数,它执行仿真的步骤如下图所示:
1、数据采集程序设计。
2、数据处理及数据的可视化和界面处理。
三、实验步骤
1、硬件连线。
根据实验指导书,连接线路,将因温度变化引起的电阻变化通过电路放大以电压
的变化表现出来。为确认连线无误及元件的好坏,将线路连好后打开电源,用万
用电表测输出电压端的电压变化,调节变阻器,观察电压是否随之变化,用手握
住铂电阻,使其升温,观察电压是否变化,若都变化,则可以开始下一步。实验
会温度大约为26°,对应电压值大约为50mV。
2、软件编程。
1、数据采集。
新建一个文件夹,选择为当前目录 ,打开simulink,选择User-Defined
Functions/S-Function Examples/C-files S-Function//Basic C-MEX Template,根
据所定义模块的功能,将该自动生成的文件重命名,并存入你指定的文件夹中 将
模版的c文件另存,文件名Myon.cpp。将Function改成和文件名一样。得到的
cpp文件如下:
#define S_FUNCTION_NAME Myon //定义一个新文件Myon
#define S_FUNCTION_LEVEL 2 //定义文件为level-2格式
/*
* Need to include simstruc.h for the definition of the SimStruct and
* its associated macro definitions.
*/
• #include "simstruc.h"
• #include "abc.h"
• double buffer[5000]; //定义全局变量,通道的缓存
buffer
• double buffer1[5000]; //定义另一个全局变量buffer1
• int pnum; //读取指针数
• char ch[8] ; //读取8通道2进制表示值
• static void mdlInitializeSizes(SimStruct *S)
//查询S-function模块的输入输出端口数,
端口容量,以及S-function所需的其他对象(如,状态个数等)。
• {
• /* See sfuntmpl_doc.c for more details on the macros below */
•
• ssSetNumSFcnParams(S, 0); //期望参数数目
• /* Number of expected parameters */
• if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S))
• //期望参数数目不等于实
际参数数目时
• {
• /* Return if number of expected != number of actual
parameters */
• return;
• }
•
• ssSetNumContStates(S, 0); //设置连续状态个数
• ssSetNumDiscStates(S, 0); //设置非连续状态个数
•
• if (!ssSetNumInputPorts(S,3)) return;//第一个参数为模块的数据结
构,第二个参数指定模块有几个输入接口
• ssSetInputPortWidth(S, 0, 1); //第一个参数为模块的一个
数据结构,第二个参数为接口编号,第三个参数指定第二个参数所指定接
口的宽度
• ssSetInputPortRequiredContiguous(S, 0, true); /*direct input signal
access*/
• ssSetInputPortWidth(S, 1, 1);
• ssSetInputPortRequiredContiguous(S, 1, true);
• ssSetInputPortWidth(S, 2, 1);
• ssSetInputPortRequiredContiguous(S, 2, true);//三个输入
• /*
• * Set direct feedthrough flag (1=yes, 0=no).
• * A port has direct feedthrough if the input is used in either
• * the mdlOutputs or mdlGetTimeOfNextVarHit functions.
• * See matlabroot/simulink/src/sfuntmpl_directfeed.txt.
• */
• ssSetInputPortDirectFeedThrough(S, 0, 1);
• ssSetInputPortDirectFeedThrough(S, 1, 1);
• ssSetInputPortDirectFeedThrough(S, 2, 1);//第一个参数为模块的数 据结构,第二个为接口的编号,第三个用于指定接口的输入数据是否能在
mdloutputs中调用
• if (!ssSetNumOutputPorts(S, 1)) return;//输出函数的参数意义同上 • ssSetOutputPortWidth(S, 0, 1);
• ssSetNumSampleTimes(S, 1);
• ssSetNumRWork(S, 0);
• ssSetNumIWork(S, 0);
• ssSetNumPWork(S, 0);
• ssSetNumModes(S, 0);
• ssSetNumNonsampledZCs(S, 0);
• ssSetOptions(S, 0);
• }
• /* Function: mdlInitializeSampleTimes
=========================================
• * Abstract:
• * This function is used to specify the sample time(s) for your
• * S-function. You must register the same number of sample times as
• * specified in ssSetNumSampleTimes.
• */
• static void mdlInitializeSampleTimes(SimStruct *S)//设置采样时间 • {
• ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); • ssSetOffsetTime(S, 0, 0.0);
• }
• #define MDL_INITIALIZE_CONDITIONS /* Change to #undef to remove function */
• #if defined(MDL_INITIALIZE_CONDITIONS)
• /* Function: mdlInitializeConditions
========================================
• * Abstract:
• * In this function, you should initialize the continuous and discrete
• * states for your S-function block. The initial states are placed • * in the state vector, ssGetContStates(S) or
ssGetRealDiscStates(S).
• * You can also perform any other initialization activities that your • * S-function may require. Note, this routine will be called at the • * start of simulation and if it is present in an enabled subsystem • * configured to reset states, it will be call when the enabled subsystem
• * restarts execution to reset the states.
• */
• static void mdlInitializeConditions(SimStruct *S)
• {
• }
• #endif /* MDL_INITIALIZE_CONDITIONS */
• #define MDL_START /* Change to #undef to remove function */
• #if defined(MDL_START)
• /* Function: mdlStart
======================================================
=
• * Abstract:
• * This function is called once at start of model execution. If you
• * have states that should be initialized once, this is the place
• * to do it.
• */
• static void mdlStart(SimStruct *S)//添加采集卡初始化以及开启采集任
务
• {
• if(ADCardInit()!=1) //初始化采集卡,如果成功则返
回1
• {
• ssSetErrorStatus(S, "Can't find the DAQCard!");
• }
•
• DAQ1(0x10, 5000, 1024*4, buffer); //对5通道进行采集
• pnum=0;
• }
• #endif /* MDL_START */
• /* Function: mdlOutputs
======================================================
=
• * Abstract:
• * In this function, you compute the outputs of your S-function
• * block. Generally outputs are placed in the output vector,
ssGetY(S).
• */
• static void mdlOutputs(SimStruct *S, int_T tid)
• {
• int Length=1024*4; //读取buffer长度
• ReadDaq(5,Length,buffer); //从采集卡中读取buffer
• real_T *y = ssGetOutputPortRealSignal(S,0); //获取输出指针
• if(pnum>=Length) pnum=0; //判断指针是否已满
• *y=buffer[pnum]; //指出第pnum个点的值
• pnum++; //指针加1
• }
• #define MDL_UPDATE /* Change to #undef to remove function */
• #if defined(MDL_UPDATE) //定义更新函数
• /* Function: mdlUpdate
======================================================
• * Abstract:
• * This function is called once for every major integration time
step.
• * Discrete states are typically updated here, but this function is
useful
• * for performing any tasks that should only take place once per
• * integration step.
• */
• static void mdlUpdate(SimStruct *S, int_T tid)
• {
• }
• #endif /* MDL_UPDATE */
• #define MDL_DERIVATIVES /* Change to #undef to remove function
*/
• #if defined(MDL_DERIVATIVES)
• /* Function: mdlDerivatives
=================================================
• * Abstract:
• * In this function, you compute the S-function block's derivatives.
• * The derivatives are placed in the derivative vector,
ssGetdX(S).
• */
• static void mdlDerivatives(SimStruct *S)
• {
• }
• #endif /* MDL_DERIVATIVES */
• /* Function: mdlTerminate
=====================================================
• * Abstract:
• * In this function, you should perform any actions that are
necessary
• * at the termination of a simulation. For example, if memory was
• * allocated in mdlStart, this is the place to free it.
• */
• static void mdlTerminate(SimStruct *S)
• {
• ADCardQuit();
• } //退出采集卡
• /*====================================================
==*
• * See sfuntmpl_doc.c for the optional S-function methods *
•
*=====================================================
=*/
•
• /*=============================*
• * Required S-function trailer *
• *=============================*/
•
• #ifdef MATLAB_MEX_FILE /* Is this file being compiled as a
MEX-file? */
• #include "simulink.c" /* MEX-file interface mechanism */
• #else
• #include "cg_sfun.h" /* Code generation registration function */
• #endif
对文件作出一些系应该,使其能满足本次试验的需要,将输入输出设置为适应本
实验需要的参数,本次试验采取3个输入接口,设置好了之后还有进行标注:
得到mytemp1.mdl文件
采集卡初始化及数据采集中,试验采用单通道,选择5通道。修改相应语句。
2、数据的可视化和界面处理。
Matlab提供了丰富的绘图功能和界面处理方法,都是通过语句控制以生成界面。
我们小组爱用的是matlab自带的GUI直接生成的模块库选择相应的需要的模块
生成一个界面,当模块保存后会自动生成一个m文件。界面如下:
生成m文件如下:
function varargout = mytest(varargin)//输出参数的个数等于输入参数的个数
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @mytest_OpeningFcn, ...
'gui_OutputFcn', @mytest_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);//GUI初始界面代码
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before mytest is made visible.
function mytest_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to mytest (see VARARGIN)
% Choose default command line output for mytest
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes mytest wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = mytest_OutputFcn(hObject, eventdata, handles) //得到可变个数返回值
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output; //指出参数个数
function edit1_Callback(hObject, eventdata, handles)
//设置第一个动态文本框回调属性 % hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit1 as text
% str2double(get(hObject,'String')) returns contents of edit1 as a double
% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
//创建一个动态文本框
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc
set(hObject,'BackgroundColor','white');
else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
function edit2_Callback(hObject, eventdata, handles)
//设置文本框回调属性
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit2 as text
% str2double(get(hObject,'String')) returns contents of edit2 as a double
% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
//创建第二个动态文本框
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc
set(hObject,'BackgroundColor','white');
else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
//设置按钮1 的回调属性
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% --- Executes on button press in pushbutton2.
%set(handles.pushbutton1,'callback',[...
% 'set_param("mytemp1","SimulationCommand","start"),',...
%
't=timer("TimerFcn","getdata","period",1,"ExecutionMode","fixedSpacing","TasksToExecute",inf),',...
% 'pause(2);start(t);',...
% ]);
function pushbutton2_Callback(hObject, eventdata, handles)
//设置按钮2 的回调属性
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) %stop(t);
%set_param('mytemp1','SimulationCommand','stop');
这个面板只是一个图形,还无法与采集的图像形成联系,因此需要对m文件作出一些修改,设置“计算”按钮和“采集”按钮的回调属性使其能和输出电压相关联。
因此需要加下列语句:
采集按钮
y=evalin('base','simout.signals.values');
//读取保存到工作空间的信号并绘制 axes(handles.axes1);
axis([0 50 0 100]); //设定轴的范围
plot(y); //在波形图中绘制波形
xlable('t'); //横轴是时间t
ylable('V'); //纵轴是电压v
计算按钮
y=evalin('base','simout.signals.values');
//读取保存到工作空间的信号并绘制
V=mean(y/3.5);
C=V/1.89; //通过电压计算温度
strc=num2str(C);
strv=num2str(V); //将数值转换为字符
set(handles.edit1,'String',strv);
set(handles.edit2,'String',strc);// 计算得到的数值填到编辑框内
该采集面板的功能是显示电压波形,当按下计算按钮时候,电压和温度栏会显示对应的电压和温度。
3数据处理。将采集到的电压信号转换成温度。由试验原理可知:温度和电压的
关系是,电路灵敏度为1.89mV/°C,可得数据处理m文件为
4连接实验箱和电脑,开始采集,得如下结果
电压与温度远远的不符合事实 需要重新标定,以得到合适的温度,根据铂电阻温度电压关系表可知,26度时候的电阻值为1017.3.对应的电压为50mv。
握住铂电阻,电压发生变化:
四、实验总结
工作台实验
一、实验目的
在PC端通过MATLAB中的Simulink模块编制程序控制工作台的运动切换,在一个循环控制中实现工作台的快进、工进、快退三级运动自动切换,顺序为先快进,再工进,再快退。对运动状态切换的位置不做具体要求。
二、实验原理
1、 Simulink的基本概念和工作原理
Simulink是MATLAB中的一种可视化仿真工具, 是一种基于MATLAB的框图设计环境,是实现动态系统建模、仿真和分析的一个软件包,被广泛应用于线性系统、非线性系统、数字控制及数字信号处理的建模和仿真中。
Simulink可以用连续采样时间、离散采样时间或两种混合的采样时间进行建模,它也支持多速率系统,也就是系统中的不同部分具有不同的采样速率。为了创建动态系统模型,Simulink提供了一个建立模型方块图的图形用户接口(GUI) ,这个创建过程只需单击和拖动鼠标操作就能完成,它提供了一种更快捷、直接明了的方式,而且用户可以立即看到系统的仿真结果。
Simulink是用于动态系统和嵌入式系统的多领域仿真和基于模型的设计工具。对各种时变系统,包括通讯、控制、信号处理、视频处理和图像处理系统,Simulink提供了交互式图形化环境和可定制模块库来对其进行设计、仿真、执行和测试。
构架在Simulink基础之上的其他产品扩展了Simulink多领域建模功能,也提供了用于设计、执行、验证和确认任务的相应工具。Simulink与MATLAB紧密集成,可以直接访问MATLAB大量的工具来进行算法研发、仿真的分析和可视化、批处理脚本的创建、建模环境的定制以及信号参数和测试数据的定义。
2、程序内置函数
程序内置了几种基本运动单独实现的现成模块,方便我们从中学习Simulink的基本原理,并通过增添修改来完成自编框图。在Matlab命令窗口输入'timere'命令即会弹出时间响应实验界面,其中已经内置'Go2Center'、'control'、'Step'、'Impulse'、'Ramp'几个运动控制模块。
各自实现的功能为:
'Go2Center':行至中间
'control' :前进后退切换
'Step' :步进
'Impulse' :加速运动
'Ramp' :匀速运动
其中在实验过程中为方便控制工作台后退并进行自主编程我们经常用到的是'control'和'Ramp'
'control'连线图如下:
'Ramp'连线图如下:
三、实验步骤
1、实验中用到的基本模块
(1)'S-Function'函数
S-Function函数具有四个外部接口:
'Vel':接口输入信号控制工作台运行速度
'Acc':接口输入信号控制工作台加速度
'Pos':接口输入信号控制工作台运行终点位置
'ErrBit':接口与示波器相连负责输出运动波形
(2)一个已有控制模块
此模块取自'Ramp'函数,在此次实验过程中为方便连线直接拿来使用:
'Ramp'
软件自带英文解释:用于产生持续增加或减少的斜坡信号
'Gain'
软件自带英文解释:处理'ramp'输出的斜坡信号
(3)'Switch'开关
软件自带英文解释:'Switch'的输出为第一个接口或第三个接口的输入,并且取决于第二个接口的输入。'Switch'为此次实验中最为重要的元件之一。
2、自编框图
(1)框图
(2)具体描述
1、参数设定
速度设定:
快进速度:100000
工进速度:5000
快退速度:100000
位置设定:
Switch :控制快进与工进切换,参数设定为
250000
Switch1:控制速度由工进速度切换为快退速度,参数设定为500000 Switch2:控制前进与后退切换,参数设定为500000
STP: 快退结束位置为0点,控制信号为STP=0
2、运动过程
Switch信号由PID输出端引出用于控制。Pos≥250000时快进切换为工进,同时Speed1切换为Speed2,Pos≥500000时工进切换为快退,同时运动速度Speed2切换Speed3。
输出图线:
四.实验中遇到的问题和分析
框图理论可以实现全过程自动切换,但是在快进与工进切换过程中存在震荡
不稳定现象,由于连线和参数的设定的经检查后没有发现问题,故在同学之间讨论和分析之后判断问题出在PID部分。可能是由于PID的中间计算导致输出信号不稳定,造成部分逻辑问题。故去除PID,直接将经过Gain处理后的斜坡信号与GetCurPos得到的当前工作台位置信号进行合成输出,未再发生震荡现象。
程序开始,工作台处于0位置,GetCurPos输出为0,同时Ramp产生一个由0开始递增的信号与GetCurPos作差,随着Ramp递增,所得差值也就越大,所以经过Add运算后的信号为一个非线性的递增信号,但是由于工作台速度始终小于这个递增值,那么工作台始终能保持匀速运动,这样就可以保证工作台不管在快进、工进还是快退都能匀速,从而去除PID是合理的,并且实验证明去除PID后系统更加稳定,也是验证了这一结论。最后得知PID的功能是控制运动成型,控制工作台更快的到达预定状态,在程序中反而会造成运动不稳定。同时由于Add运算输出的信号与工作台位置存在一个确定的函数关系式,所以依据这一关系式可以推出Switch控制信号与工作台位置的关系,也即通过调整Switch的控制信号控制工作台运动切换位置点是完全没有问题的,即使是精确控制也是可以的。另外正是因为Add运算后输出信号是一非线性递增信号,所以正好可以利用这一特性来做为Switch的控制信号,整个运动过程中每个Switch开关都跳转一次,相应实现快进、工进、快退、停止这一系列动作,实现了自动控制。
五、心得体会
综合测控实验
班级:
组员:
铂电阻温度测量实验
一、实验目的
1、了解铂电阻的温度特性与曲线,学会用铂电阻测量温度
2、学会使用matlab编程,采集电压信号波形并显示在面板上
3、了解并掌握信号处理方法,将采集到的电压信号转换成温度信号显示出来
二、实验原理
1、铂电阻测温原理。
金属铂电阻的性能十分稳定,在-260°C~+630°C之间,铂热电阻用作标准温度计,在0~630°C之间铂电阻与温度呈如下关系:
Rt=R0(1+AT+BT²)
式中:R0=1000Ω,A=0.3973973*10-²,B=-0.58973*10-6
恒压型的铂电阻测温电路如图所示,该电路也是常用的测温电路之一,其中Vin
为恒定输入电压,W1用于零点调整,W2用于范围调整,该电路的输出电压Vout
为:
Vout=R1ΔR*Vin/(R1+R0+ΔR)(R1+R0)
由式可知,在恒压条件下,其输出电压取决于Vin和R1。当R1=22KΩ,Vin=12V
时,在0~100°C范围内,电路灵敏度为1.89mV/°C.
本实验采用铂电阻PT100,它在0°时候对应的电阻为1K,可以用其分度表查询
阻值对应的温度,可以发现其温度几乎呈线性变化。
2、数据采集与操作。
利用matlab编程,将采集到的电压信号波形显示出来,并将其电压对应的温度
计算后显示出来。调节试验箱的变阻器以使电路的电压对应的温度值等于实时温
度以进行标定再列出温度电压关系。具体步骤分为:
1、SIMULINK动态仿真。
Simulink模块包括一系列输入、状态和输出。输出是采样时间、输入、模块状态
的函数,它执行仿真的步骤如下图所示:
1、数据采集程序设计。
2、数据处理及数据的可视化和界面处理。
三、实验步骤
1、硬件连线。
根据实验指导书,连接线路,将因温度变化引起的电阻变化通过电路放大以电压
的变化表现出来。为确认连线无误及元件的好坏,将线路连好后打开电源,用万
用电表测输出电压端的电压变化,调节变阻器,观察电压是否随之变化,用手握
住铂电阻,使其升温,观察电压是否变化,若都变化,则可以开始下一步。实验
会温度大约为26°,对应电压值大约为50mV。
2、软件编程。
1、数据采集。
新建一个文件夹,选择为当前目录 ,打开simulink,选择User-Defined
Functions/S-Function Examples/C-files S-Function//Basic C-MEX Template,根
据所定义模块的功能,将该自动生成的文件重命名,并存入你指定的文件夹中 将
模版的c文件另存,文件名Myon.cpp。将Function改成和文件名一样。得到的
cpp文件如下:
#define S_FUNCTION_NAME Myon //定义一个新文件Myon
#define S_FUNCTION_LEVEL 2 //定义文件为level-2格式
/*
* Need to include simstruc.h for the definition of the SimStruct and
* its associated macro definitions.
*/
• #include "simstruc.h"
• #include "abc.h"
• double buffer[5000]; //定义全局变量,通道的缓存
buffer
• double buffer1[5000]; //定义另一个全局变量buffer1
• int pnum; //读取指针数
• char ch[8] ; //读取8通道2进制表示值
• static void mdlInitializeSizes(SimStruct *S)
//查询S-function模块的输入输出端口数,
端口容量,以及S-function所需的其他对象(如,状态个数等)。
• {
• /* See sfuntmpl_doc.c for more details on the macros below */
•
• ssSetNumSFcnParams(S, 0); //期望参数数目
• /* Number of expected parameters */
• if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S))
• //期望参数数目不等于实
际参数数目时
• {
• /* Return if number of expected != number of actual
parameters */
• return;
• }
•
• ssSetNumContStates(S, 0); //设置连续状态个数
• ssSetNumDiscStates(S, 0); //设置非连续状态个数
•
• if (!ssSetNumInputPorts(S,3)) return;//第一个参数为模块的数据结
构,第二个参数指定模块有几个输入接口
• ssSetInputPortWidth(S, 0, 1); //第一个参数为模块的一个
数据结构,第二个参数为接口编号,第三个参数指定第二个参数所指定接
口的宽度
• ssSetInputPortRequiredContiguous(S, 0, true); /*direct input signal
access*/
• ssSetInputPortWidth(S, 1, 1);
• ssSetInputPortRequiredContiguous(S, 1, true);
• ssSetInputPortWidth(S, 2, 1);
• ssSetInputPortRequiredContiguous(S, 2, true);//三个输入
• /*
• * Set direct feedthrough flag (1=yes, 0=no).
• * A port has direct feedthrough if the input is used in either
• * the mdlOutputs or mdlGetTimeOfNextVarHit functions.
• * See matlabroot/simulink/src/sfuntmpl_directfeed.txt.
• */
• ssSetInputPortDirectFeedThrough(S, 0, 1);
• ssSetInputPortDirectFeedThrough(S, 1, 1);
• ssSetInputPortDirectFeedThrough(S, 2, 1);//第一个参数为模块的数 据结构,第二个为接口的编号,第三个用于指定接口的输入数据是否能在
mdloutputs中调用
• if (!ssSetNumOutputPorts(S, 1)) return;//输出函数的参数意义同上 • ssSetOutputPortWidth(S, 0, 1);
• ssSetNumSampleTimes(S, 1);
• ssSetNumRWork(S, 0);
• ssSetNumIWork(S, 0);
• ssSetNumPWork(S, 0);
• ssSetNumModes(S, 0);
• ssSetNumNonsampledZCs(S, 0);
• ssSetOptions(S, 0);
• }
• /* Function: mdlInitializeSampleTimes
=========================================
• * Abstract:
• * This function is used to specify the sample time(s) for your
• * S-function. You must register the same number of sample times as
• * specified in ssSetNumSampleTimes.
• */
• static void mdlInitializeSampleTimes(SimStruct *S)//设置采样时间 • {
• ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); • ssSetOffsetTime(S, 0, 0.0);
• }
• #define MDL_INITIALIZE_CONDITIONS /* Change to #undef to remove function */
• #if defined(MDL_INITIALIZE_CONDITIONS)
• /* Function: mdlInitializeConditions
========================================
• * Abstract:
• * In this function, you should initialize the continuous and discrete
• * states for your S-function block. The initial states are placed • * in the state vector, ssGetContStates(S) or
ssGetRealDiscStates(S).
• * You can also perform any other initialization activities that your • * S-function may require. Note, this routine will be called at the • * start of simulation and if it is present in an enabled subsystem • * configured to reset states, it will be call when the enabled subsystem
• * restarts execution to reset the states.
• */
• static void mdlInitializeConditions(SimStruct *S)
• {
• }
• #endif /* MDL_INITIALIZE_CONDITIONS */
• #define MDL_START /* Change to #undef to remove function */
• #if defined(MDL_START)
• /* Function: mdlStart
======================================================
=
• * Abstract:
• * This function is called once at start of model execution. If you
• * have states that should be initialized once, this is the place
• * to do it.
• */
• static void mdlStart(SimStruct *S)//添加采集卡初始化以及开启采集任
务
• {
• if(ADCardInit()!=1) //初始化采集卡,如果成功则返
回1
• {
• ssSetErrorStatus(S, "Can't find the DAQCard!");
• }
•
• DAQ1(0x10, 5000, 1024*4, buffer); //对5通道进行采集
• pnum=0;
• }
• #endif /* MDL_START */
• /* Function: mdlOutputs
======================================================
=
• * Abstract:
• * In this function, you compute the outputs of your S-function
• * block. Generally outputs are placed in the output vector,
ssGetY(S).
• */
• static void mdlOutputs(SimStruct *S, int_T tid)
• {
• int Length=1024*4; //读取buffer长度
• ReadDaq(5,Length,buffer); //从采集卡中读取buffer
• real_T *y = ssGetOutputPortRealSignal(S,0); //获取输出指针
• if(pnum>=Length) pnum=0; //判断指针是否已满
• *y=buffer[pnum]; //指出第pnum个点的值
• pnum++; //指针加1
• }
• #define MDL_UPDATE /* Change to #undef to remove function */
• #if defined(MDL_UPDATE) //定义更新函数
• /* Function: mdlUpdate
======================================================
• * Abstract:
• * This function is called once for every major integration time
step.
• * Discrete states are typically updated here, but this function is
useful
• * for performing any tasks that should only take place once per
• * integration step.
• */
• static void mdlUpdate(SimStruct *S, int_T tid)
• {
• }
• #endif /* MDL_UPDATE */
• #define MDL_DERIVATIVES /* Change to #undef to remove function
*/
• #if defined(MDL_DERIVATIVES)
• /* Function: mdlDerivatives
=================================================
• * Abstract:
• * In this function, you compute the S-function block's derivatives.
• * The derivatives are placed in the derivative vector,
ssGetdX(S).
• */
• static void mdlDerivatives(SimStruct *S)
• {
• }
• #endif /* MDL_DERIVATIVES */
• /* Function: mdlTerminate
=====================================================
• * Abstract:
• * In this function, you should perform any actions that are
necessary
• * at the termination of a simulation. For example, if memory was
• * allocated in mdlStart, this is the place to free it.
• */
• static void mdlTerminate(SimStruct *S)
• {
• ADCardQuit();
• } //退出采集卡
• /*====================================================
==*
• * See sfuntmpl_doc.c for the optional S-function methods *
•
*=====================================================
=*/
•
• /*=============================*
• * Required S-function trailer *
• *=============================*/
•
• #ifdef MATLAB_MEX_FILE /* Is this file being compiled as a
MEX-file? */
• #include "simulink.c" /* MEX-file interface mechanism */
• #else
• #include "cg_sfun.h" /* Code generation registration function */
• #endif
对文件作出一些系应该,使其能满足本次试验的需要,将输入输出设置为适应本
实验需要的参数,本次试验采取3个输入接口,设置好了之后还有进行标注:
得到mytemp1.mdl文件
采集卡初始化及数据采集中,试验采用单通道,选择5通道。修改相应语句。
2、数据的可视化和界面处理。
Matlab提供了丰富的绘图功能和界面处理方法,都是通过语句控制以生成界面。
我们小组爱用的是matlab自带的GUI直接生成的模块库选择相应的需要的模块
生成一个界面,当模块保存后会自动生成一个m文件。界面如下:
生成m文件如下:
function varargout = mytest(varargin)//输出参数的个数等于输入参数的个数
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @mytest_OpeningFcn, ...
'gui_OutputFcn', @mytest_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);//GUI初始界面代码
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before mytest is made visible.
function mytest_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to mytest (see VARARGIN)
% Choose default command line output for mytest
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes mytest wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = mytest_OutputFcn(hObject, eventdata, handles) //得到可变个数返回值
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output; //指出参数个数
function edit1_Callback(hObject, eventdata, handles)
//设置第一个动态文本框回调属性 % hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit1 as text
% str2double(get(hObject,'String')) returns contents of edit1 as a double
% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
//创建一个动态文本框
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc
set(hObject,'BackgroundColor','white');
else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
function edit2_Callback(hObject, eventdata, handles)
//设置文本框回调属性
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit2 as text
% str2double(get(hObject,'String')) returns contents of edit2 as a double
% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
//创建第二个动态文本框
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc
set(hObject,'BackgroundColor','white');
else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
//设置按钮1 的回调属性
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% --- Executes on button press in pushbutton2.
%set(handles.pushbutton1,'callback',[...
% 'set_param("mytemp1","SimulationCommand","start"),',...
%
't=timer("TimerFcn","getdata","period",1,"ExecutionMode","fixedSpacing","TasksToExecute",inf),',...
% 'pause(2);start(t);',...
% ]);
function pushbutton2_Callback(hObject, eventdata, handles)
//设置按钮2 的回调属性
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) %stop(t);
%set_param('mytemp1','SimulationCommand','stop');
这个面板只是一个图形,还无法与采集的图像形成联系,因此需要对m文件作出一些修改,设置“计算”按钮和“采集”按钮的回调属性使其能和输出电压相关联。
因此需要加下列语句:
采集按钮
y=evalin('base','simout.signals.values');
//读取保存到工作空间的信号并绘制 axes(handles.axes1);
axis([0 50 0 100]); //设定轴的范围
plot(y); //在波形图中绘制波形
xlable('t'); //横轴是时间t
ylable('V'); //纵轴是电压v
计算按钮
y=evalin('base','simout.signals.values');
//读取保存到工作空间的信号并绘制
V=mean(y/3.5);
C=V/1.89; //通过电压计算温度
strc=num2str(C);
strv=num2str(V); //将数值转换为字符
set(handles.edit1,'String',strv);
set(handles.edit2,'String',strc);// 计算得到的数值填到编辑框内
该采集面板的功能是显示电压波形,当按下计算按钮时候,电压和温度栏会显示对应的电压和温度。
3数据处理。将采集到的电压信号转换成温度。由试验原理可知:温度和电压的
关系是,电路灵敏度为1.89mV/°C,可得数据处理m文件为
4连接实验箱和电脑,开始采集,得如下结果
电压与温度远远的不符合事实 需要重新标定,以得到合适的温度,根据铂电阻温度电压关系表可知,26度时候的电阻值为1017.3.对应的电压为50mv。
握住铂电阻,电压发生变化:
四、实验总结
工作台实验
一、实验目的
在PC端通过MATLAB中的Simulink模块编制程序控制工作台的运动切换,在一个循环控制中实现工作台的快进、工进、快退三级运动自动切换,顺序为先快进,再工进,再快退。对运动状态切换的位置不做具体要求。
二、实验原理
1、 Simulink的基本概念和工作原理
Simulink是MATLAB中的一种可视化仿真工具, 是一种基于MATLAB的框图设计环境,是实现动态系统建模、仿真和分析的一个软件包,被广泛应用于线性系统、非线性系统、数字控制及数字信号处理的建模和仿真中。
Simulink可以用连续采样时间、离散采样时间或两种混合的采样时间进行建模,它也支持多速率系统,也就是系统中的不同部分具有不同的采样速率。为了创建动态系统模型,Simulink提供了一个建立模型方块图的图形用户接口(GUI) ,这个创建过程只需单击和拖动鼠标操作就能完成,它提供了一种更快捷、直接明了的方式,而且用户可以立即看到系统的仿真结果。
Simulink是用于动态系统和嵌入式系统的多领域仿真和基于模型的设计工具。对各种时变系统,包括通讯、控制、信号处理、视频处理和图像处理系统,Simulink提供了交互式图形化环境和可定制模块库来对其进行设计、仿真、执行和测试。
构架在Simulink基础之上的其他产品扩展了Simulink多领域建模功能,也提供了用于设计、执行、验证和确认任务的相应工具。Simulink与MATLAB紧密集成,可以直接访问MATLAB大量的工具来进行算法研发、仿真的分析和可视化、批处理脚本的创建、建模环境的定制以及信号参数和测试数据的定义。
2、程序内置函数
程序内置了几种基本运动单独实现的现成模块,方便我们从中学习Simulink的基本原理,并通过增添修改来完成自编框图。在Matlab命令窗口输入'timere'命令即会弹出时间响应实验界面,其中已经内置'Go2Center'、'control'、'Step'、'Impulse'、'Ramp'几个运动控制模块。
各自实现的功能为:
'Go2Center':行至中间
'control' :前进后退切换
'Step' :步进
'Impulse' :加速运动
'Ramp' :匀速运动
其中在实验过程中为方便控制工作台后退并进行自主编程我们经常用到的是'control'和'Ramp'
'control'连线图如下:
'Ramp'连线图如下:
三、实验步骤
1、实验中用到的基本模块
(1)'S-Function'函数
S-Function函数具有四个外部接口:
'Vel':接口输入信号控制工作台运行速度
'Acc':接口输入信号控制工作台加速度
'Pos':接口输入信号控制工作台运行终点位置
'ErrBit':接口与示波器相连负责输出运动波形
(2)一个已有控制模块
此模块取自'Ramp'函数,在此次实验过程中为方便连线直接拿来使用:
'Ramp'
软件自带英文解释:用于产生持续增加或减少的斜坡信号
'Gain'
软件自带英文解释:处理'ramp'输出的斜坡信号
(3)'Switch'开关
软件自带英文解释:'Switch'的输出为第一个接口或第三个接口的输入,并且取决于第二个接口的输入。'Switch'为此次实验中最为重要的元件之一。
2、自编框图
(1)框图
(2)具体描述
1、参数设定
速度设定:
快进速度:100000
工进速度:5000
快退速度:100000
位置设定:
Switch :控制快进与工进切换,参数设定为
250000
Switch1:控制速度由工进速度切换为快退速度,参数设定为500000 Switch2:控制前进与后退切换,参数设定为500000
STP: 快退结束位置为0点,控制信号为STP=0
2、运动过程
Switch信号由PID输出端引出用于控制。Pos≥250000时快进切换为工进,同时Speed1切换为Speed2,Pos≥500000时工进切换为快退,同时运动速度Speed2切换Speed3。
输出图线:
四.实验中遇到的问题和分析
框图理论可以实现全过程自动切换,但是在快进与工进切换过程中存在震荡
不稳定现象,由于连线和参数的设定的经检查后没有发现问题,故在同学之间讨论和分析之后判断问题出在PID部分。可能是由于PID的中间计算导致输出信号不稳定,造成部分逻辑问题。故去除PID,直接将经过Gain处理后的斜坡信号与GetCurPos得到的当前工作台位置信号进行合成输出,未再发生震荡现象。
程序开始,工作台处于0位置,GetCurPos输出为0,同时Ramp产生一个由0开始递增的信号与GetCurPos作差,随着Ramp递增,所得差值也就越大,所以经过Add运算后的信号为一个非线性的递增信号,但是由于工作台速度始终小于这个递增值,那么工作台始终能保持匀速运动,这样就可以保证工作台不管在快进、工进还是快退都能匀速,从而去除PID是合理的,并且实验证明去除PID后系统更加稳定,也是验证了这一结论。最后得知PID的功能是控制运动成型,控制工作台更快的到达预定状态,在程序中反而会造成运动不稳定。同时由于Add运算输出的信号与工作台位置存在一个确定的函数关系式,所以依据这一关系式可以推出Switch控制信号与工作台位置的关系,也即通过调整Switch的控制信号控制工作台运动切换位置点是完全没有问题的,即使是精确控制也是可以的。另外正是因为Add运算后输出信号是一非线性递增信号,所以正好可以利用这一特性来做为Switch的控制信号,整个运动过程中每个Switch开关都跳转一次,相应实现快进、工进、快退、停止这一系列动作,实现了自动控制。
五、心得体会