matlaboscilloscope

Collect more than 10,000 data points from a Tektronix oscilloscope?


I am building a MATLAB GUI to do data collection from a Tektronix DPO4104 oscilloscope (MATLAB driver here).

I am playing around with tmtool and with my GUI code and have found that the driver can only collect 10,000 data points, regardless of if the oscilloscope is set to show more than 10k points. I found this post on in CCSM but it hasn't been terribly helpful. (I'm the last post on there if you care to read it.) I am using the DPO4104 driver, whereas this post discusses use of the DPO4100 driver, I believe.

As far as I can tell, the steps are:

  1. Edit driver's readwaveform function to account for the current recordLength - in my case, 100,000 points, say.
  2. Manually edit the driver's MaxNumberPoint from 10,000 to 100,000. (In my case, the default number was 0.. I changed this to 100,000).
  3. Manually edit EndingPoint. I set this to 100,000 also.
  4. Before creating a device object, set(interfaceObj, 'InputBufferLength', 2.5*recordLength), that is, make sure the input buffer can fit more than 100,000 points. It's recommended to use at least double the expected buffer. I used 2.5 just because.
  5. Build device object and waveform object, connect() to it, and readwaveform. Profit.

I am still unable to collect more than 10,000 points, either through tmtool or through my GUI. Any help would be appreciated.


Solution

  • I figured it out! I think. Taking a couple weeks to step back and refresh really helped. Here's what I did:

    1) Edit the driver's init function to configure a larger buffer size. Complete init code:

    function init(obj)
    % This method is called after the object is created.
    % OBJ is the device object.
    % End of function definition - DO NOT EDIT
    
    % Extract the interface object.
    interface = get(obj, 'Interface');
    
    fclose(interface);
    
    % Configure the buffer size to allow for waveform transfer.
    set(interface, 'InputBufferSize', 12e6);
    set(interface, 'OutputBufferSize', 12e6); % Originally is set to 50,000
    

    I originally tried to set the the buffer sizes to 22e6 (I wanted to get 10 million points) but I got out-of-memory errors. Supposedly the buffer should be a little more than double what you expect to get out, plus space for headers. I probably don't need 2 million points worth of "header", but eh.

    2) Edit the driver's readwaveform() to first query what the user-settable number of points to collect should be. Then, write SCPI commands to the scope to ensure that the number of data points to be transferred is equal to the number of points the user desires. The following snippet will do the trick in readwaveform:

    try 
        % Specify source
        fprintf(interface,['DATA:SOURCE ' trueSource]);
    
        %----------BEGIN CODE TO HANDLE MORE THAN 10k POINTS----------
        recordLength = query(interface, 'HORizontal:RECordlength?');
        fprintf(interface, 'DATA:START 1');
        fprintf(interface, 'DATA:STOP %d', str2num(recordLength));
        %----------END CODE TO HANDLE MORE THAN 10k POINTS----------
    
        % Issue the curve transfer command.
        fprintf(interface, 'CURVE?');
    
        raw = binblockread(interface, 'int16');
    
        % Tektronix scopes send and extra terminator after the binblock.
        fread(interface, 1);
    

    3) In the user code, set a SCPI command to change the record size to the underlying interface object:

    % interfaceObj is a VISA object.
    fprintf(interfaceObj, 'HORizontal:RECordlength 5000000');
    

    There you have it. Hopefully this helps out anyone else that's trying to figure out this issue.