Minimize Data Gaps with Two Scopes

With two scopes, you can minimize data overlap or gaps. The first scope acquires data up to sample N, then stops. The second scope begins to acquire data at sample N+1.

In this example, the TriggerMode property of Scope 1 is set to 'Scope', but it is explicitly triggered with the MATLAB® function trigger(sc1).

You can use the trigger function to force real-time scopes to trigger, regardless of trigger mode setting and regardless of whether the triggering criteria were met.

To minimize gaps by acquiring data with two scopes:

  1. Build and download the Simulink® model xpcosc to the target computer.

  2. In the MATLAB Command Window, assign tg to the target computer and set the StopTime property to 10.

    tg = slrt;
    tg.StopTime = 10;
  3. Add a vector of two host scopes to the real-time application. Use the vector index to switch from one scope to the other.

    sc = addscope(tg,'host', [1 2]);
  4. Add signals 4 and 5 to both scopes.

    addsignal(sc,[4 5]);
    
  5. Set the NumSamples property for both scopes to 500 and the TriggerSample property for both scopes to -1. With this property setting, each scope triggers the next scope at the end of its 500 sample acquisition.

    sc(1).NumSamples = 500;
    sc(1).TriggerSample = -1;
    
    sc(2).NumSamples = 500;
    sc(2).TriggerSample = -1;
    
  6. Set the TriggerMode property for scopes 1 and 2 to 'Scope'. Set the TriggerScope property such that each scope triggers the other.

    sc(1).TriggerMode = 'Scope';
    sc(1).TriggerScope = 2;
    
    sc(2).TriggerMode = 'Scope';
    sc(2).TriggerScope = 1;
  7. Set up storage for time, t, and signal, data acquisition.

    t = [];
    data = zeros(0, 2);
  8. Start both scopes and the model.

    start(sc);
    start(tg);

    Both scopes receive the same signals, 4 and 5.

  9. To start acquiring data, explicitly trigger scope 1.

    scNum = 1;
    trigger(sc(scNum));

    Setting scNum to 1 indicates that Scope 1 acquires data first.

  10. Start acquiring data using the two scopes to double buffer the data.

    while (1)
    
      % Busy wait until this scope has finished acquiring 500 samples
      % or the model stops (scope is interrupted).
      while ~(strcmp(sc(scNum).Status, 'Finished') || ...
              strcmp(sc(scNum).Status, 'Interrupted')) 
      end
    
      % Stop buffering data when the model stops.
      % Pause to be certain that the status property has been updated.
      
      pause(0.1)
      
      if strcmp(tg.Status, 'stopped')
        break
      end
      
      % Save the data.
      t(   end + 1 : end + 500)    = sc(scNum).Time;
      data(end + 1 : end + 500, :) = sc(scNum).Data;
    
      % Restart this scope.
      start(sc(scNum)); 
    
      % Switch to the next scope.
      if(scNum == 1) scNum = 2;
      else scNum = 1;
      end
      
    end
  11. When done, remove the scopes.

    % Remove the scopes we added.
    remscope(tg,[1 2]);
  12. Plot the data.

    plot(t,data); 
    grid on; 
    legend('Signal 4','Signal 5');
    

Following is a complete code listing for the preceding double-buffering data acquisition procedure. After you download the model (xpcosc) to the target computer, you can copy and paste this code into a MATLAB file and run it. Communication between the development and target computers must be fast enough to transmit the entire set of samples before the next acquisition cycle starts. In a similar way, you can use more than two scopes to implement a triple- or quadruple-buffering scheme.

% Assumes model xpcosc program text has been
% built and loaded on the target computer.

% Attach to the target computer and set StopTime to 10 sec.
tg = slrt;
tg.StopTime = 10;

% Add two host scopes.
sc = addscope(tg,'host', [1 2]);

% [4 5] are the signals of interest. Add to both scopes.
addsignal(sc,[4 5]);

% Each scope triggers the next scope at end of a 500 sample acquisition.
sc(1).NumSamples = 500;
sc(1).TriggerSample = -1;

sc(2).NumSamples = 500;
sc(2).TriggerSample = -1;

sc(1).TriggerMode = 'Scope';
sc(1).TriggerScope = 2;

sc(2).TriggerMode = 'Scope';
sc(2).TriggerScope = 1;

% Initialize time and data log.
t = [];
data = zeros(0, 2);

% Start the scopes and the model.
start(sc);
start(tg);

% To start the capture, explicitly trigger scope 1.
scNum = 1; 
trigger(sc(scNum)); 

% Use the two scopes as a double buffer to log the data.
while (1)

  % Busy wait until this scope has finished acquiring 500 samples
  % or the model stops (scope is interrupted).
  while ~(strcmp(sc(scNum).Status, 'Finished') || ...
          strcmp(sc(scNum).Status, 'Interrupted')) 
  end

  % Stop buffering data when the model stops.
  % Pause to be certain that the status property has been updated.
  
  pause(0.1)
  
  if strcmp(tg.Status, 'stopped')
    break
  end
  
  % Save the data.
  t(   end + 1 : end + 500)    = sc(scNum).Time;
  data(end + 1 : end + 500, :) = sc(scNum).Data;

  % Restart this scope.
  start(sc(scNum)); 

  % Switch to the next scope.
  if(scNum == 1) scNum = 2;
  else scNum = 1;
  end
  
end

% Remove the scopes we added.
remscope(tg,[1 2]);

% Plot the data.
plot(t,data); 
grid on; 
legend('Signal 4','Signal 5');