plccodesysstructured-text

Prevent the XY Chart from drawing a line from the most recent value to the origin in CODESYS visualization?


I am using CODESYS to plot an array of voltage values in an XY chart in the visualization. The voltage values are updated every second, but I am encountering an issue where the XY chart connects the most recent value to (0,0), causing a line to appear between the current value and the origin. This line is not desired and makes the plot look incorrect. I tried to initialize the array with 5, the effect is, that the line unwanted lie is drawn to (0,5) instead of (0,0)

How can I fix this?

Here is my code:

PROGRAM PLC_PRG
    VAR
        // *** Constants and Parameters ***
        Max_Samples   : INT := 20;                 // Maximum number of samples to be collected

        // *** ADC Input Reading ***
        ADC_1         : INT;                       // Raw ADC value from the input

        // *** Data Storage Arrays ***
        arr_Voltages  : ARRAY[0..20] OF REAL;      // Array initialized with NaN (Not-a-Number) values
        arr_Time      : ARRAY[0..20] OF INT;       // Array to store time-related sample indices

        // *** Timer and Counters ***
        Sample_Timer  : TON;                       // Timer instance for sampling intervals (TON type)
        Sample_Time   : TIME := T#1s;              // Sampling interval duration (1 second)
        sample_index  : INT := 0;                  // Current index for writing data into arrays
        start_Timing  : BOOL;                      // Control signal to start or stop the timer
        i             : INT;                       // General counter variable

        // *** Web Visualization Variables ***
        start_Measurement : BOOL := FALSE;         // Control flag for starting the measurement process
        reset_Visu        : BOOL := FALSE;         // Control flag for resetting the visualization
        status_LED        : BOOL := FALSE;         // Status indicator (e.g., for LED on the Web Visu)
    END_VAR

    // Timer configuration: The timer is controlled by 'start_Timing' and runs for 'Sample_Time'.
    Sample_Timer(IN := start_Timing, PT := Sample_Time); // Timer runs with a duration of 1 second.

    IF start_Measurement THEN   // Check if measurement should start.
        start_Timing := TRUE;   // Activate the timer to begin the sampling process.
        status_LED := TRUE;
    END_IF
  
    IF Sample_Timer.Q THEN  // Check if the timer has completed (Q = TRUE indicates the timer is done).
        start_Timing := FALSE;          // Stop the timer to reset its state.
        Sample_Timer(IN := FALSE);      // Explicitly reset the timer to prepare for the next interval.

        IF sample_index <= Max_Samples THEN  // Ensure the index is within the allowed range.
            arr_Time[sample_index] := sample_index;       // Store the current index as the timestamp.
            arr_Voltages[sample_index] := get_Voltage(ADC_1); // Record the measured voltage from the ADC.
            sample_index := sample_index + 1;            // Increment the sample index for the next measurement.
        ELSE
            sample_index := 0;            // Reset the sample index to the beginning.
            start_Measurement := FALSE;  // Stop the measurement process as the maximum samples are reached.
            status_LED := FALSE;
        END_IF
    END_IF

    IF reset_Visu THEN
        // Reset all elements of arr_Time to 0
        FOR i := 0 TO Max_Samples DO
            arr_Time[i] := 0;
            arr_Voltages[i] := 0.0; // Use 0.0 for REAL array elements
        END_FOR

        sample_index := 0;          // Reset the sample index
    END_IF

The Plot: XY Chart

EDIT

Specific solution

I added a variable to plot the curve and added it to the Array Indexes Maximum.

plot_Index := sample_index-1;

The -1 adjustment was necessary because the first array index is 0 but the sample_index is incremented to 1. So without this, the unwanted line back to the origin would still be plotted.

Additionally, are arrays in Codesys automatically initialized to 0? I simply declared my array, and all values seem to default to 0. Thanks for the help.

Fixed Plot

Setting in Plot


Solution

  • The XY Chart doesn't require the data on X axis be ordered, in other words the line can go both right and left. Also, by default, the Chart takes all elements of your arrays and plots them. This means that, in your case, since all elements are initialized as zeroes, when the sample_index is less than the array upper bound, there are [0,0] elements at the end of the array, resulting in the chart plotting several points at the origin ([0,0]).

    To solve this, you need to tell the Chart which elements to plot. You can do this by specifying the start and end indexes:

    Inside the XY Chart settings, under the Curve Settings, the Array Indexes section are the Minimum and Maximum parameters

    In your case, the starting index would be fixed at 0, and the end index would increase as you add new samples to the array.

    A possible solution:

    Example of the Minimum and Maximum parameters

    PROGRAM PLC_PRG
        VAR
            ...
            sample_index  : INT := 0;                  // Current index for writing data into arrays
            plot_Index    : INT := 0;                  // Current index of the last valid element
            ...
        END_VAR
    
        ...
      
        IF Sample_Timer.Q THEN
            ...
    
            IF sample_index <= Max_Samples THEN
                ...
                plot_Index := sample_index;                  // Set plot_Index to sample_index which is the index of the last written data
                sample_index := sample_index + 1;            // Increment the sample index for the next measurement.
            ELSE
                sample_index := 0;            // Reset the sample index to the beginning.
                plot_Index := Max_Samples;
                ...
            END_IF
        END_IF
    
        IF reset_Visu THEN
            ...
    
            sample_index := 0;          // Reset the sample index
            plot_Index := 0;
        END_IF