APIs, concepts, guides, and more
Recorder

Utilize the Recorder to capture and store controller data like positions, velocities, etc, supporting condition-based or continuous recording for in-depth analysis.

๐Ÿ”น What is a Recorder?

A Recorder object provides a mechanism to collect and buffer any data (positions, velocities, etc) in the controllerโ€™s memory. After a recorder is configured and started, the controller copies the data (positions, velocities, etc) from the specified addresses to a local buffer for every โ€œNโ€ sample. Later, the host can collect the data by polling or via interrupt-based events.

๐Ÿ”น How Many Data Objects Can a Recorder Hold?

The controller supports up to 64 data recorders, which can each record data from up to a total of 32 addresses in each sample. The buffers can be dynamically allocated. A larger data recorder buffer may be required for higher sample rates, slow host computers, when running via client/server, or when a large number of data fields are being recorded.

In case the data recording length is greater than the memory available to the recorder, the recorder can be configured to use a circular buffer and the host PC is only required to copy the recorded data to RAM faster than the recorder circular buffer rolls over. On most systems**,** this is not an issue.

๐Ÿ”น Can I Trigger a Recorder When a Condition is Met?

A recorder can be started or stopped from the host application or from the controller by configuring a data recorder trigger. When the trigger conditions are met, the controller will automatically start or stop a data recorder. This is very useful for logging relevant variables during the period preceding a fault or error. Normally, the recorder stops collecting data when the buffer is full. It can also be configured to continuously collect data, overwriting the previous data until it is commanded to stop. This is useful for trapping a recent history of controller data.

๐Ÿ“œ Sample Code

Basic Recorder Usage

  • C#

    const int VALUES_PER_RECORD = 2; // How many values to store in each record.
    const int RECORD_PERIOD_SAMPLES = 1; // How often to record data. (samples between consecutive records)
    const int RECORD_TIME = 250; // How long to record. (in milliseconds)
    const int INPUT_INDEX = 0;
    // Get the host controller addresses for the values we want to record
    // Number of processed Recorders in the controller.
    controller.RecorderCountSet(1);
    controller.AxisCountSet(1);
    Axis axis = CreateAndReadyAxis(Constants.AXIS_NUMBER); // Helper function to setup an axis
    UInt64 userBufferAddress = controller.AddressGet(RSIControllerAddressType.RSIControllerAddressTypeUSER_BUFFER, 0); // Grabing an memory address to store a simulated IO point.
    // Instead of using physical IO we will use simulated IO using a memory address as simulated IO. See the IO sample apps to see how to use a physical IO instead.
    IOPoint input = IOPoint.CreateDigitalInput(controller, userBufferAddress, INPUT_INDEX); // Create a simulated IOpoint using userBuffer memory.
    if (controller.RecorderEnabledGet() == true) // Check if the recorder is running already. If it is, stop it.
    {
    controller.RecorderStop(); // Stop recording.
    controller.RecorderReset(); // Reset controller.
    }
    controller.RecorderPeriodSet(RECORD_PERIOD_SAMPLES); // Configure recorder to record every 'n' samples (Every 'n' ms)
    controller.RecorderCircularBufferSet(false); // Do not use a circular buffer
    controller.RecorderDataCountSet(VALUES_PER_RECORD); // Configure the number of values for each record. (how many things to record)
    controller.RecorderDataAddressSet(0, axis.AddressGet(RSIAxisAddressType.RSIAxisAddressTypeACTUAL_POSITION)); // Configure the recoder to record values from this address (1st recorded address)
    controller.RecorderDataAddressSet(1, input.AddressGet()); // Configure the recoder to record values from this address (2nd recorded address)
    controller.RecorderStart(); // Start recording.
    controller.OS.Sleep(RECORD_TIME); // Put this thread to sleep for some milliseconds.
    int recordsAvailable = controller.RecorderRecordCountGet(); // find out how many records were recorded. (Get the number of records that are stored and ready for reading)
    Console.WriteLine("There are {0} Records available.", recordsAvailable); // Print the number of records recorded.
    for (int i = 0; i < recordsAvailable; i++) // Check every record recorded.
    {
    controller.RecorderRecordDataRetrieve(); // Retrieve one record of recorded data.
    double positionRecord = controller.RecorderRecordDataDoubleGet(0); // Get the value from the 1st specified address. /use double
    var digitalInputsValue = controller.RecorderRecordDataValueGet(1); // Get the value from the 2nd specified address.
    if ((digitalInputsValue & input.MaskGet()) == input.MaskGet()) // We are checking to see if the digital input 1 bit changes. If it does then we record the position when that input went high.
    {
    i = recordsAvailable; // break from loop.
    Console.WriteLine("Your encoder position was: " + positionRecord + " when the input triggered.");
    }
    }
    controller.RecorderStop(); // Stop recording.
    controller.RecorderReset(); // Reset controller.

Recording Performance Metrics