SDS5054X MATLAB VISA Acquisition - Page 1
Forum section: electronics / testgear

author: FunJumper
author_rank: Newbie
timestamp: November 03, 2020, 05:36:22 am
content: SDS5054X MATLAB VISA AcquisitionHello.I had a bit of difficulty following the Python example in the SDS5054X PG01-11A Programming Guide for an implementation of an acquisition of scope memory into PC using MATLAB abd VISA. The guide was dificult to interpret around the Waveform Preamble, and so I used commands, and saw that tis is an approach in PG01-E02B. Further, all the other sections of the SDS5054X PG01-11A Programming Guide seem to force a save of the data to a USB memory connected to the SDS5054X. I wanted to get the data into the PC using MATLAB.Follow the NI VISA instructions in SDS5054X PG01-11A Programming Guide. Or, as it workrd for me since I had the MATLA Instrument Control App, it used a VISA installed with MATLAB.Connect a signal such as the probe compensation to channel one, and run the script. It should capture your signal, and save/plot it in MATLAB. I created a complex waveform in MALAB and played it out the PC headset jack and used channel 1 to connect to it. See captured and plotted waveform, if I can place an image in EEVBOL Forum.I hope this is useful for someone.Thanks.FunJumperScript:%% SDS5054X_try_05 Test Script for Communicating/Controlling SDS5054X.%% Main Steps:% 1. Instrument Connection% 2. Instrument Configuration and Control% 3. Disconnect and Clean Up%% To SDS5054X_try_05 Test Script, type the name of the file,% SDS5054X_try_05, at the MATLAB command prompt.%% The file, SDS5054X_try_05.m must be on your MATLAB PATH. For additional information% on setting your MATLAB PATH, type 'help addpath' at the MATLAB command% prompt.%% Example:% SDS5054X_try_05;%% Instrument Connection% Find a VISA-USB object.obj1 = instrfind('Type', 'visa-usb', 'RsrcName', 'USB0::0xF4EC::0xEE38::SDS5XCBC4R0031::0::INSTR', 'Tag', '');% Create the VISA-USB object if it does not exist% otherwise use the object that was found.if isempty(obj1)obj1 = visa('KEYSIGHT', 'USB0::0xF4EC::0xEE38::SDS5XCBC4R0031::0::INSTR');elsefclose(obj1);obj1 = obj1(1);end% Configure instrument object, obj1, to 60000 Input and 512 Output Buffer Size% 60000 is the largest input I can without generating an error. This allows the% most data to be transfered from SDS5x to PC at one time.set(obj1, 'InputBufferSize', 60000);set(obj1, 'OutputBufferSize', 512);% Connect to instrument object, obj1.fopen(obj1);%% Instrument Configuration and Control% Communicating with instrument object, obj1.% NOTE!: Connect Chan1 to Probe Cal Port for 1kHz 3.3Vpp square wave,% or to some external test signal.% Query the identification number of the SDS5xSDS5xID = query(obj1, '*IDN?');% Reset the SDS5x to factory startupfprintf(obj1, '*RST');pause(1)%%% Note some pauses are needed so scope can keep up. Pausing until% receiving a response would be better. Pause as you need to to make your% scripte work. %%%% Disable all input channelsfprintf(obj1, 'CHAN1:SWIT OFF');fprintf(obj1, 'CHAN2:SWIT OFF');fprintf(obj1, 'CHAN3:SWIT OFF');fprintf(obj1, 'CHAN4:SWIT OFF');pause(1)% Setup Channel 1fprintf(obj1, 'CHAN1:BWL 20M');fprintf(obj1, 'CHAN1:COUP DC');fprintf(obj1, 'CHAN1:OFFS 0.0E+0');fprintf(obj1, 'CHAN1:SCAL 0.25E+0');pause(1)% Timebase Setupfprintf(obj1, 'TIM:DEL 0.0E+0');fprintf(obj1, 'TIM:SCAL 1.0E-2');pause(1)% Acquisition Setup%% Waveform Setupfprintf(obj1, 'WAV:SOUR C1');pause(1)% Acquire Raw Waveformfprintf(obj1, 'CHAN1:SWIT ON');pause(1)% Trigger Setupfprintf(obj1, 'TRIG:EDGE:SOUR C1');fprintf(obj1, 'TRIG:TYPE EDGE');fprintf(obj1, 'TRIG:EDGE:LEV 1.0E+00');fprintf(obj1, 'TRIG:RUN'); % Run/Stop to freeze waveform acquired into scope memorypause(1)fprintf(obj1, 'TRIG:STOP'); % Can eliminate stopt to continue to trigger on waveformpause(1)% Waveform Generator%fprintf(obj1, 'C1:BSWV WVTP,SQUARE');%fprintf(obj1, 'C1:BSWV WVTP,RAMP');%fprintf(obj1, 'C1:BSWV FRQ,5000');%fprintf(obj1, 'C1:BSWV AMP,3');%fprintf(obj1, 'C1:BSWV DUTY,30');%query(obj1, 'C1:BSWV?')%fprintf(obj1, 'C1:OUTP ON');% Clear Data (Probably not needed to clear data.)clear dataV dataVn dataV_no_head dataVn_no_head read_len scope_mem_len read_stepsclear steps read_start visa_string volt_no_head% Send Dataread_len = 50000; % This is the length of data that will be read from the scope, for each loop read. Nice round number, 50000 of 60000 max.fprintf(obj1, 'WAV:DATA?'); % 1st read from scope. Next reads in for loop. Tell scope to transfer 50000 samples from first samplepause(0.1)dataVn = fread(obj1, read_len, 'int8'); % Read the 50000 samples.pause(0.1)dataV = ; % start a voltage collection vectordataVn_no_head = dataVn(17:end); % Strip off the header bytes.dataV_no_head = ; % % start a no head voltage collection vector%scope_mem_len = str2num(char(dataVn(8:16)'))scope_mem_len = str2num(query(obj1, 'ACQ:POIN?')); % Get the number of sample the scope acquiredread_steps = ceil(scope_mem_len/read_len); % Fine the number of loop iterationsfor steps = 1:(read_steps - 1) % Iterate through all 50000 chunks of dataread_start = read_len*steps + 1; % adjust a new starting point to read a 50000 chunkvisa_string = "WAV:STAR " + read_start % create a visa string for the start pointfprintf(obj1, visa_string); % set the start point for the 50000 chunkpause(0.1)query(obj1, 'WAV:STAR?'); % See if the starting point is rightpause(0.1)fprintf(obj1, 'WAV:DATA?'); % looped read from scope. Tell scope to transfer 50000 samples from new start point at each looppause(0.1)dataVn = fread(obj1, read_len, 'int8'); % Read the 50000 samples.pause(0.1)dataV = [dataV; dataVn]; % Concatenate the voltage vectordataVn_no_head = dataVn(17:end); % strip the headers off the voltage vectors at each loopdataV_no_head = [dataV_no_head; dataVn_no_head]; % concatenate the no header voltage vectorend% This deviates from the PG01-E11A Programming guide in that it does not% use the waveform preamble. It uses commands like CHAN1:SCAL?,% CHAN1:OFFS?, etc% Calculate Voltage Waveform% Read Data%dataV = fread(obj1, 50000, 'int8'); % 60000 can not be bigger that Input Buffer%volt_no_head = dataV(17:end-2); % Clear out the 17 header and the last two end file symbolsvolt_no_head = dataV_no_head; % change of varialble. (not needed)% NOTE: the header may not repear on a second read further into scope% memory, and th end file symols may not occur untilt the end of scope% memory, not at end of individual read!!! Need to look into this.vdiv = query(obj1, 'CHAN1:SCAL?'); % Dummy to rid result of chracter header for all following.vdiv = str2num(query(obj1, 'CHAN1:SCAL?')); % See Step3 formula P591 PG01-E11Avoffset = str2num(query(obj1, 'CHAN1:OFFS?')); % See Step3 formula P591 PG01-E11Acode_per_div = 30; % Constant for SDS5xvoltV = volt_no_head*vdiv/code_per_div - voffset; % voffset is in scope display% voffset is in scope display, It should not be in final waveform.% - voffset in formula compensates for this.% This deviates from the PG01-E11A Programming guide in that it does not% use the waveform preamble. It uses commands like TIM:SCAL?,% TIM:DEL?, etc% Calculate Time Vector% NOTE: Formula for time in Step4 P592 PG01-E11A needs *index*interval to% be replaced by + index*intervaltimebase = str2num(query(obj1, 'TIM:SCAL?')); % See P246-P247 PG01-E02B and Step4 formula P592 PG01-E11Adelay = str2num(query(obj1, 'TIM:DEL?')); % See Step4 formula P592 PG01-E11A% query(obj1, 'ACQ:SRAT?')samplerate = str2num(query(obj1, 'ACQ:SRAT?')); % See P247 PG01-E02B and Step4 formula P592 PG01-E11Ainterval = (1/samplerate); % See P247 PG01-E02B and Step4 formula P592 PG01-E11Aggrid = 10; % Constant for SDS5xindex = [0:1:size(voltV)-1]; % See Step4 formula P592 PG01-E11AtimeS = -delay - (timebase*ggrid/2) + index*interval; % See Step4 formula P592 PG01-E11A% Plot Waveformplot(timeS, voltV)%% Disconnect and Clean Up% The following properly disposes open instrument objects when SDS5054X_try_00.m executed% as part of a function or script.% Disconnect all objects.fclose(obj1);% Clean up all objects.delete(obj1);clear obj1;