Este es un ejemplo de una S-Function de Matlab Level-2 que lee una sola entrada continua de tipo double y la escribe al archivo out.txt como CSV time,value. El archivo se abre en la función mdlStart y se cierra en la función mdlTerminate. El valor de entrada se lee en la función mdlUpdate.
Ver también Ejemplo de Matlab Level 2 S-Function: Onda senoidal (salida continua).
single_input_write_to_file.cpp
#define S_FUNCTION_NAME single_input_write_to_file
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
#include <cstdio> // For file handling
// Definir constantes
#define SAMPLING_RATE 1000 // 1kHz
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 0); // No parameters
ssSetNumContStates(S, 0); // No continuous states
ssSetNumDiscStates(S, 0); // No discrete states
// 1 puerto de entrada con 1 elemento
if (!ssSetNumInputPorts(S, 1)) return;
ssSetInputPortWidth(S, 0, 1); // Input port width = 1
ssSetInputPortDataType(S, 0, SS_DOUBLE);
ssSetInputPortComplexSignal(S, 0, COMPLEX_NO);
ssSetInputPortRequiredContiguous(S, 0, 1); // Require contiguous input port memory
// ssSetInputPortDirectFeedThrough(S, 0, 1); // Direct feedthrough
// Sin puertos de salida
if (!ssSetNumOutputPorts(S, 0)) return;
// Sample times
ssSetNumSampleTimes(S, 1); // Single sample time
// Work vectors
ssSetNumRWork(S, 0); // Real work vector
ssSetNumIWork(S, 0); // Integer work vector
ssSetNumPWork(S, 1); // Pointer work vector for file pointer
ssSetNumModes(S, 0); // Mode vector
ssSetNumNonsampledZCs(S, 0); // Zero crossings
// Hacer el bloque S-function capaz de ser usado en un modelo generado por Real-Time Workshop
ssSetOptions(S, 0);
}
#define MDL_START
static void mdlStart(SimStruct *S) {
// Abrir el archivo "out.txt" para escritura
FILE *file = fopen("out.txt", "w");
if (file == NULL) {
ssSetErrorStatus(S, "Failed to open file 'out.txt'");
return;
}
const real_T *u = (const real_T*) ssGetInputPortSignal(S, 0); // Input pointer
real_T input_value = u == nullptr ? -1 : u[0]; // Read the input value
ssSetPWorkValue(S, 0, file);
}
// Function: mdlInitializeSampleTimes =========================================
// Abstract:
// Inicializar los sample times a 1ms (1kHz)
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, 1.0 / SAMPLING_RATE); // 1kHz sampling rate
ssSetOffsetTime(S, 0, 0.0);
}
// No necesario para este ejemplo
static void mdlOutputs(SimStruct *S, int_T tid) {
// No hacer nada
}
#define MDL_UPDATE
static void mdlUpdate(SimStruct *S, int_T tid)
{
real_T time = ssGetT(S); // Get the current simulation time
// Obtener el valor de entrada
const real_T *u = (const real_T*) ssGetInputPortRealSignal(S, 0); // Input pointer
real_T input_value = u == nullptr ? -1 : u[0]; // Read the input value
// Obtener el puntero de archivo del work vector
FILE *file = (FILE*) ssGetPWorkValue(S, 0);
if (file != NULL) {
fprintf(file, "%f,%f\n", time, input_value); // Write the input value to the file
}
}
static void mdlTerminate(SimStruct *S)
{
// Cerrar el archivo
FILE *file = (FILE*) ssGetPWorkValue(S, 0);
if (file != NULL) {
fclose(file);
}
}
// Trailer requerido de S-function
#ifdef MATLAB_MEX_FILE
#include "simulink.c" // MEX-file interface mechanism
#else
#include "cg_sfun.h" // Code generation interface
#endif
Echa un vistazo a artículos similares por categoría:
Si este artículo te ha ayudado, considera invitarme a un café o hacer una donación vía PayPal para apoyar la investigación y publicación de nuevos artículos en TechOverflow