reading ASCII data in s-function from a file
Show older comments
Hello all,
I am interested in reading ASCII data in s-function from a file. I am trying to read the data [21;77;46;183;202;84;199;198;27;84] from the file datafile.dat. I am trying to display the data in Scope using *z = ssGetOutputPortSignal(S,0); . But when I run the corresponding Model I could see that only first 5 numbers are read i.e. 21;77;46;183;202. Following is the code:
#define S_FUNCTION_NAME sfunread
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
#include <stdio.h>
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 0);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return;
}
ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 0);
if (!ssSetNumInputPorts(S, 0)) return;
if (!ssSetNumOutputPorts(S, 1)) return;
ssSetOutputPortWidth(S, 0, 10);
ssSetOutputPortDataType(S,0,SS_SINGLE);
ssSetNumPWork(S,1);
ssSetNumSampleTimes(S, 1);
}
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, 1.0);
ssSetOffsetTime(S, 0, 0.0);
}
#define MDL_START
#if defined(MDL_START)
static void mdlStart(SimStruct *S)
{
void** pwork = ssGetPWork(S);
FILE *datafile;
datafile = fopen("datafile.dat","r");
pwork[0] = datafile;
}
#endif /* MDL_START */
static void mdlOutputs(SimStruct *S, int_T tid)
{
int l;
real_T *z = ssGetOutputPortSignal(S,0);
void** pwork = ssGetPWork(S);
for (l=0;l<10;l++){
real_T temp;
fscanf(pwork[0],"%f",&temp);
z[l]=temp;
}
static void mdlTerminate(SimStruct *S)
{
void** pwork = ssGetPWork(S);
FILE *datafile;
datafile = pwork[0];
fclose(datafile);
}
#ifdef MATLAB_MEX_FILE
#include "simulink.c"
#else
#include "cg_sfun.h"
#endif
Please let me know if I am using the correct way to read the ASCII data from a file.
Tushar
2 Comments
Kaustubha Govind
on 7 Apr 2011
How is the data in your file delimited? Are there spaces between the numbers?
Tushar
on 11 Apr 2011
Answers (2)
Jarrod Rivituso
on 7 Apr 2011
0 votes
Your overall approach looks good. I would suggest debugging the S-function so you can step through it. There are steps on how to do that here:
Also, did you copy and paste that code directly? There seems to be a missing } to end your for loop. I was looking for something subtle in your code and noticed that (I doubt that is the problem, but it makes me suspicious of whether this code actually contains the problem).
Tushar
on 13 Apr 2011
0 votes
5 Comments
Walter Roberson
on 13 Apr 2011
That #DEN indicates that the number is a "denormalized" number.
The problem appears to be that you are using "%f" to read the numbers. In C, a %f format indicates that the result is to be stored as a single precision number. Change the format to "%lf" to read a double precision number.
Jarrod Rivituso
on 13 Apr 2011
Interesting, and good catch Walter.
Tushar, I believe you could set the variables tmp and z in your code to either real32_T or real64_T explicitly to try and match the desired C data type. I notice you have set your output to single precision floating point.
Kaustubha Govind
on 13 Apr 2011
Tushar: You might also want to check the output of fscanf for EOF, and assign temp to 0 in that case, so you don't attempt to read past the end.
Tushar
on 15 Apr 2011
Jarrod Rivituso
on 17 Apr 2011
I think for most 32-bit machines the mappings from Simulink S-function typedefs to the actual C data types goes as
real32_t - float
real64_T - double
real_T - double
So, real_T shouldn't work for integer type data.
Categories
Find more on Data Type Identification in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!