⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 phd_to_matlab.c

📁 本例利用C MEX及API文件实现matlab与PHD只见的通讯.能实现数据的存取。
💻 C
字号:
/*
---------------
PHD_TO_MATLAB.C
Tested for PHD release 150 (server) and PHD release 160 (client software)
Version 2
11-feb-2002
---------------

Program to take data of a PHD-system and store them into matlab.
PHD = Process History Database, a Honeywell-database to store data of a chemical plant

Author : Hans Vereecken
Control engineer
tel : 00.32.3.561.3411
hans.vereecken@notes.basant.be
Please inform me what you think of this routine

BASF Antwerp Belgium
Can be distributed freely.


To compile in matlab via "mex phd_to_matlab.c netapishr.lib"

netapishr.lib is the library file of the PHD system. "PHDuser.h" is a header file of the PHD-system.
These files should be on your harddisc (after installing the PHD-client software).

The files "PHDuser.h", "PHDPARAM.H", "PHDSTS.h" and "netapishr.lib" and this one must all be in the same directory,
before compiling via the mex-routine. The matlab-path should also point to this directory


to call the mexfunction in Matlab, use :
[time_vector,value_vector,conf_vector,ITIME of startingdate,ITIME of ref_time]
= PHD_to_matlab(tagname,begintime,endtime,reference time,method,sampling or average time);

e.g. [t,v,conf,start,ref]=phd_to_matlab(tag,t1,t2,t_ref,'S',60);

if Method = 'S' --> snapshots
if sampling time == 0 --> RAW DATA (you get all the data of the database)
      Because PHD stores data on irregular timestamps (storing data depends on the tolerance of a tag),
	  the timestamps are not uniformaly spaced.
	  What is stored, is what you get.
if sampling time != 0 --> RESAMPLED DATA
	If a timestamp falls between two stored points, the points are linearly interpolated (you get
	the average of the two points)
--> resampling time in seconds

if Method = 'A' --> You want the averages
time == 60 --> 1 minute-averages
The returned timestamp is the mid of the averaged interval.
The first and the last points are of course treated differently (because there is no mid).
if time == 60 ; the first point (time = 0) is the average of time = 0 to 30
the second point (time = 1 minute) is the average of time 30 s - 90 s

ITIME = seconds after 01/01/1970

Time format like this : 16-MAY-2001 00:00:00 ; characters in MATLAB and in C++
ITIME is the time in seconds since 1/1/1970 00:00:00

t_ref becomes time = 0 hours in Matlab

First login using PHD_connect(...)
Is another routine, called once to connect to the database

*/

#include "PHDUSER.H" /* PHD-header ; is on your hard-disc */
#include "mex.h" /* Matlab header */
#include <stdio.h>
#include <string.h>
#include "matrix.h"

void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])

/*	Calling convention of Matlab
	nlhs : number of left hand side arguments (5 in this case)
	plhs : pointer to the left hand side arguments
	nrhs : number of right hand side arguments (6 in this case)
	plhs : pointer to the right hand side arguments
*/

{
int   buflen;
int k; /* counter for for-loops */
char *input_tagname; 
char *input_start_time; 
char *input_end_time; 
char *input_ref_time; // t_ref becomes time = 0 hours in Matlab
double *pind_v,*pind_t,*pind_itime,*pind_itime_ref; 
double *pind_c;

TAGNO tagno; // Description of TAGNO : see PHD-headers
PHDATA *pr_data; /* pointer to the data structure of PHD */
PHSPEC spec; /* PHD-structure for the specifications */

ISTAT status;
INT4 tformat; /* integer for the time format ; 1 = time format like 16-MAR-2001 00:00:00 */
// This format MUST be used in Matlab
ITIME itime_start; /* starting time , converted to seconds since 1/1/1970 00:00:00 */
ITIME itime_ref; /* reference time , converted to seconds since 1/1/1970 00:00:00 */
char *method; // input 5 ; 'S' = Snapshots or 'A' = Averages
// Capital letters only

/*------------------------------------------------------------------------------------------*/

/* Error checking*/
/* check for proper number of arguments */
    if(nrhs!=6) 
      mexErrMsgTxt("6 inputs required.");
    else if(nlhs != 5) 
      mexErrMsgTxt("5 output arguments required.");


/* First input must be a string (the tagname) */
    if ( mxIsChar(prhs[0]) != 1)
      mexErrMsgTxt("The tagname (first input) must be a string.");

/* It must be a row vector */
    if (mxGetM(prhs[0])!=1)
      mexErrMsgTxt("The tagname must be a row vector.");
    
/* Get the length of the input string */
    buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1;

/* allocate memory for input string */
    input_tagname=mxCalloc(buflen, sizeof(char));

/* copy the string data from prhs[0] into a C string.*/
    status = mxGetString(prhs[0], input_tagname, buflen);
    if(status != 0) 
      mexWarnMsgTxt("Not enough space. first string (the tagname) is truncated.");


tformat=1; /* like this : "16-NOV-1999 00:00:00" */


/* Second input must be a string (the begindate) */
    if ( mxIsChar(prhs[1]) != 1)
      mexErrMsgTxt("The begindate (second input) must be a string.");

/* It must be a row vector */
    if (mxGetM(prhs[1])!=1)
      mexErrMsgTxt("The begindate must be a row vector.");
    
/* Get the length of the input string */
    buflen = (mxGetM(prhs[1]) * mxGetN(prhs[1])) + 1;

/* allocate memory for input string */
    input_start_time=mxCalloc(buflen, sizeof(char));

/* copy the string data from prhs[1] into a C string.*/
    status = mxGetString(prhs[1], input_start_time, buflen);
    if(status != 0) 
      mexWarnMsgTxt("Not enough space. second string (the starting time) is truncated.");


/* third input must be a string (the enddate) */
    if ( mxIsChar(prhs[2]) != 1)
      mexErrMsgTxt("The enddate (third input) must be a string.");

/* It must be a row vector */
    if (mxGetM(prhs[2])!=1)
      mexErrMsgTxt("The enddate must be a row vector.");
    
/* Get the length of the input string */
    buflen = (mxGetM(prhs[2]) * mxGetN(prhs[2])) + 1;

/* allocate memory for input string */
    input_end_time=mxCalloc(buflen, sizeof(char));

/* copy the string data from prhs[2] into a C string.*/
    status = mxGetString(prhs[2], input_end_time, buflen);
    if(status != 0) 
      mexWarnMsgTxt("Not enough space. Third string (the end time) is truncated.");


/* Input 4 must be a string (the reference time) */
    if ( mxIsChar(prhs[3]) != 1)
      mexErrMsgTxt("The reference time (input 4) must be a string.");

/* It must be a row vector */
    if (mxGetM(prhs[3])!=1)
      mexErrMsgTxt("The reference time must be a row vector.");
    
/* Get the length of the input string */
    buflen = (mxGetM(prhs[3]) * mxGetN(prhs[3])) + 1;

/* allocate memory for input string */
    input_ref_time=mxCalloc(buflen, sizeof(char));

/* copy the string data from prhs[3] into a C string.*/
    status = mxGetString(prhs[3], input_ref_time, buflen);
    if(status != 0) 
      mexWarnMsgTxt("Not enough space. string 4 (the reference time) is truncated.");


/* Input 5 must be a string (the method) */
    if ( mxIsChar(prhs[4]) != 1)
      mexErrMsgTxt("The method (input 5) must be a string.");

/* Get the length of the input string */
    buflen = (mxGetM(prhs[4]) * mxGetN(prhs[4])) + 1;

/* allocate memory for input string */
    method=mxCalloc(buflen, sizeof(char));

/* copy the string data from prhs[4] into a C string.*/
    status = mxGetString(prhs[4], method, buflen);
    if(status != 0) 
      mexWarnMsgTxt("Not enough space. string 5 (the method) is truncated.");


/* Input 6 must be a double (the sampling or average time in seconds) */
    if ( mxIsDouble(prhs[5]) != 1)
      mexErrMsgTxt("The sampling/average time (input 6) must be a number.");


// END ERROR CHECKING

tagno=phd_tagno(input_tagname); // gives the tagnumber of a specific tag
// Is a PHD-API routine
mxFree(input_tagname); /* Free the memory*/
if(tagno==0) // error checking
	{
	mexPrintf("Tag does not exist!\n");
	return;
	}

/* Converting the starting time to seconds since midnight 1/1/1970 */
phd_itime(input_start_time, tformat, &itime_start);

/* Converting the reference time to seconds since midnight 1/1/1970 */
phd_itime(input_ref_time, tformat, &itime_ref);
// to make some calculations in MATLAB, not used here


/* Memory allocation of the PHDATA-structure */
pr_data = NULL;
status = phd_newphdata(0,0,&pr_data); // Is a PHD-API routine
if (status != 0)  // error checking
	{
	mexPrintf("Memory allocation error when creating pr_data!\n");
	phd_delphdata(&pr_data); /* deallocate the memory of the pr_data structure */
	/* It is possible that this routine doesn't work after a non succesfull memory allocation */
	return;
	}

/* Memory allocation of the SPEC-structure */
memset(&spec,0,sizeof(spec));

spec.smpsecs = (INT4) mxGetScalar(prhs[5]);
// mxGetScalar returns a double, not a pointer
// the number must be converted to an integer
// Get the sample time from Matlab


if (spec.smpsecs == 0)                       // if the sample time == 0 --> always give RAW DATA
                                             // even if the method is 'A'
            {
			//mexPrintf("Raw Data!\n");
            spec.rawdata = 'X';              /* Return raw data */
            spec.resamp_method = 'S';        /* Direct Sample */
            }
 if ((spec.smpsecs != 0) && (*method =='S')) // DATA-RESAMPLING
			{
			mexPrintf("Resampled data (%d sec.)!\n",spec.smpsecs);
			// if a timestamp falls between two points, the average of the two points is calculated
            spec.rawdata = '\0';			 // no raw data
            spec.resamp_method = 'S';        // Direct Sample
            }
if ((spec.smpsecs != 0) && (*method =='A')) // AVERAGES
            {
			mexPrintf("%d sec. averages!\n",spec.smpsecs);
            spec.rawdata = '\0';			 // No raw data
            spec.resamp_method = 'A';        // Average around ; the timestamp is in the mid of the averaged interval
            }

// AT LAST : GET THE DAMN DATA
status=phd_getdata(tagno,input_start_time,input_end_time,tformat,&spec,&pr_data,NULL);
if(status!=0)
	{
	mexPrintf("Get data failed!\n");
	free(&spec); /* deallocate the memory of the spec-structure */
	phd_delphdata(&pr_data); /* deallocate the memory of the pr_data structure */
	/* It is possible that this routine doesn't work properly after a non succesfull phd_getdata */
	return;
	}

mxFree(input_start_time); /* Free the memory*/
mxFree(input_end_time); /* Free the memory*/

/* Since variable does not yet exist in MATLAB workspace,
   create it and place it in the global workspace. */
	plhs[0]=mxCreateDoubleMatrix(pr_data->nval,1,mxREAL);
	/* No possibility to test the pointer, function doesn't return anything if unsuccesfull
	the mex-file is ended automaticly by matlab if the creation was unsuccesfull 
	Problem = memory allocation of pr_data is not set free in this case
	memory can only be deallocated by closing matlab */
	pind_t=mxGetPr(plhs[0]); /* time vector */
	plhs[1]=mxCreateDoubleMatrix(pr_data->nval,1,mxREAL);
	pind_v=mxGetPr(plhs[1]); /* value vector */
	plhs[2]=mxCreateDoubleMatrix(pr_data->nval,1,mxREAL);
	pind_c=mxGetPr(plhs[2]); /* vector with confidence numbers */



if (pr_data->datatype == 'F') // if the datatype is real (float)
{
for (k=0;k<pr_data->nval;k++)
	{
	pind_v[k]=pr_data->fval[k]; /* floating point values */
	}
}

if (pr_data->datatype == 'I') // if the datatype is integer
{
for (k=0;k<pr_data->nval;k++)
	{
	pind_v[k]=(double) pr_data->ival[k]; /* integer values --> converted to double*/
	}
}

for (k=0;k<pr_data->nval;k++)
	{
	pind_t[k]=pr_data->istamp[k]; /* time stamp in seconds */
	}

for (k=0;k<pr_data->nval;k++)
	{
	pind_c[k]=pr_data->conf[k]; /* confidence values */
	}

plhs[3]=mxCreateDoubleMatrix(1,1,mxREAL);
	pind_itime=mxGetPr(plhs[3]); /* return the ITIME value of the starting time */
	pind_itime[0]=itime_start;   /* in the 4th left hand side parameter when calling the mex routine*/

plhs[4]=mxCreateDoubleMatrix(1,1,mxREAL);
	pind_itime_ref=mxGetPr(plhs[4]); /* return the ITIME value of the reference time */
	pind_itime_ref[0]=itime_ref;   /* in the left hand side parameter no 5 when calling the mex routine*/

free(&spec); /* deallocate the memory of the spec-structure */
phd_delphdata(&pr_data); /* deallocate the memory of the pr_data structure */
mxFree(method); // free the memory of the method-variable

/* The End */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -