Matlab S-Function Beispiel: Double-Eingabe lesen und in Datei schreiben

Dies ist ein Beispiel für eine Matlab Level-2 S-Funktion, die eine einzelne kontinuierliche Eingabe vom Typ double liest und sie in die Datei out.txt als CSV time,value schreibt. Die Datei wird in der Funktion mdlStart geöffnet und in der Funktion mdlTerminate geschlossen. Der Eingabewert wird in der Funktion mdlUpdate gelesen.

Siehe auch Matlab Level 2 S-Function Beispiel: Sinuswelle (kontinuierliche Ausgabe).

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

// Define constants
#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 input port with 1 element
    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

    // No output ports
    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

    // Make the S-function block capable of being used in a Real-Time Workshop-generated model
    ssSetOptions(S, 0);
}

#define MDL_START
static void mdlStart(SimStruct *S) {
    // Open the file "out.txt" for writing
    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:
//    Initialize the sample times to be 1ms (1kHz)
static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, 1.0 / SAMPLING_RATE);  // 1kHz sampling rate
    ssSetOffsetTime(S, 0, 0.0);
}

// Not needed for this example
static void mdlOutputs(SimStruct *S, int_T tid) {
    // Do nothing
}

#define MDL_UPDATE
static void mdlUpdate(SimStruct *S, int_T tid)
{
    real_T time = ssGetT(S);  // Get the current simulation time

    // Get the input value
    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

    // Get the file pointer from the 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)
{
    // Close the file
    FILE *file = (FILE*) ssGetPWorkValue(S, 0);
    if (file != NULL) {
        fclose(file);
    }
}

// Required S-function trailer
#ifdef MATLAB_MEX_FILE
#include "simulink.c"   // MEX-file interface mechanism
#else
#include "cg_sfun.h"    // Code generation interface
#endif

Check out similar posts by category: