Rapid Block Memory Segments

Post your MATLAB discussions here
Post Reply
mc1
Newbie
Posts: 0
Joined: Thu Feb 07, 2019 8:09 pm

Rapid Block Memory Segments

Post by mc1 » Thu Feb 07, 2019 8:21 pm

Hello all,
I'm using a 4000 series PicoScope in matlab and having some trouble with rapid block. My goal is to have the function generator sweep through some signals that will eventually be fed back into the PicoScope to be stored in the rapid block memory segments, and then once the sweep is complete transfer the block. I was wondering if it's even possible to do it like this? I'm new to the PicoScope so I'm not sure if this is even an intended function of rapid block. Thanks in advance.

Below is the section of code where I try to collect the first frequency to segment 1, and then change frequencies and collect the second frequency to segment 2. When I get the data I only have the second frequency.


% Capture the blocks of data
% segmentIndex : 1
[status.runBlock, timeIndisposedMs] = invoke(blockGroupObj, 'runBlock', 1);

% set the second frequency
set(ps4000aDeviceObj.Signalgenerator(1), 'startFrequency', 500);
[status.setSigGenBuiltInSimple] = invoke(sigGenGroupObj, 'setSigGenBuiltInSimple', 0);

%run a block to collect the second frequency
[status.runBlock, timeIndisposedMs] = invoke(blockGroupObj, 'runBlock', 2);

% Retrieve Rapid Block Data
% numCaptures : 16
% ratio : 1
% ratioMode : 0 (ps4000aEnuminfo.enPS4000ARatioMode.PS4000A_RATIO_MODE_NONE)

% Provide additional output arguments for the remaining channels e.g. chB
% for Channel B
[numSamples, overflow, chA] = invoke(rapidBlockGroupObj, 'getRapidBlockData', 16, 1, 0);

Martyn
Site Admin
Site Admin
Posts: 3709
Joined: Fri Jun 10, 2011 8:15 am
Location: St. Neots

Re: Rapid Block Memory Segments

Post by Martyn » Mon Feb 11, 2019 10:45 am

As you have issued two calls to RunBlock this is not a RapidBlock scenario, which would collect two buffers with no interaction from the application.

For your case you should be able to perform the two runs, collecting data to segment 1 and then segment 2, and then reading data from segment 1, and then data from segment 2 using getBlockData.

You will need to have segmented the memory before starting the collection
Martyn
Technical Support Manager

mc1
Newbie
Posts: 0
Joined: Thu Feb 07, 2019 8:09 pm

Re: Rapid Block Memory Segments

Post by mc1 » Mon Feb 11, 2019 1:31 pm

Thanks for the response, Martyn.
Will I have to run getBlockData twice? My intention is to store multiple segments and then get the data all at once in the interest of saving time.
Thanks again.

Martyn
Site Admin
Site Admin
Posts: 3709
Joined: Fri Jun 10, 2011 8:15 am
Location: St. Neots

Re: Rapid Block Memory Segments

Post by Martyn » Mon Feb 11, 2019 1:55 pm

You will need to call the function twice with the segment index changing, but this can easily be done in a loop.
Martyn
Technical Support Manager

mc1
Newbie
Posts: 0
Joined: Thu Feb 07, 2019 8:09 pm

Re: Rapid Block Memory Segments

Post by mc1 » Mon Feb 11, 2019 3:04 pm

Okay, thanks for the help. I set up a loop and it's working pretty well. I didn't know if there was a way to optimize the process, but sounds like this is the way to go. Thanks again.

mc1
Newbie
Posts: 0
Joined: Thu Feb 07, 2019 8:09 pm

Re: Rapid Block Memory Segments

Post by mc1 » Fri Feb 15, 2019 4:57 pm

Martyn,

I have this working in a loop, but it's a little slower than I'd like. Is there a way to rework the code to use getRapidBlockData or getValuesBulk? Playing around with the code I've found that I can easily store to different memory segments, and then call them all one at a time later. Is there no way to call multiple segments at once. I feel like if they're sitting there indexed in the memory then there must be a better way of retrieving them.

% segmentIndex : 0
[status.ps4000aRunBlock, timeIndisposedMs] = invoke(blockGroupObj, 'ps4000aRunBlock', 0);
%run some code then store to the next segmentIndex
[status.ps4000aRunBlock, timeIndisposedMs] = invoke(blockGroupObj, 'ps4000aRunBlock', 1);


I'm using the following to access each segment at will, but it seems like there should be a way to grab a range of segments.

% start index : 0
% segment index : 0
% downsampling ratio: 1
% downsampling mode : 0 (ps4000aEnuminfo.enPS4000ARatioMode.PS4000A_RATIO_MODE_NONE)
[numSamples, overflow, chA, chB] = invoke(blockGroupObj, 'getBlockData', 0, 0, 1, 0);

Hitesh
Advanced User
Advanced User
Posts: 2856
Joined: Tue May 31, 2011 3:43 pm
Location: St. Neots, Cambridgeshire

Re: Rapid Block Memory Segments

Post by Hitesh » Wed Feb 20, 2019 12:20 pm

Hi mc1,

You might be able to use the ps4000aGetValuesBulk() function in the Rapidblock group to retrieve a number of waveforms at once if you are using segmented memory. This will require you to setup your data buffers using the ps4000aSetDataBuffer() function and also convert the data from ADC counts to millivolts (see the getRapidBlockData() function in the Instrument Driver editor for some pointers on how to do this).

To view help information on the functions, please see this post.

If you set the displayOutput property of the instrument driver to 0 after establishing the connection, it may speed up things a little as it will reduce the amount of output to the command window.

Hope this helps,
Hitesh

Software Dev. Engineer

mc1
Newbie
Posts: 0
Joined: Thu Feb 07, 2019 8:09 pm

Re: Rapid Block Memory Segments

Post by mc1 » Fri Feb 22, 2019 7:51 pm

Hitesh,

Thanks for the help. Changing the displayOutput saved 0.25 seconds, which is helpful.

I'm still having trouble with ps4000aGetValuesBulk.

[numSamples, overflow, chA] = invoke(rapidBlockGroupObj, 'ps4000GetValuesBulk', 0, 0, 1, 0);
Error using icgroup/invoke (line 60)
The function ps4000GetValuesBulk is not supported by this device group object.

ps4000aGetValuesBulk doesn't seem to be in the group for me access/adjust settings. I also ran methods and it didn't appear on the list. I'm very new to pico, so I could be missing something obvious. Any thoughts?

Driver specific methods for class icdevice:

deviceReset ps4000aIsLedFlashing
getUnitInfo ps4000aMemorySegments
ps4000aChangePowerSource ps4000aSetBandwidthFilter
ps4000aCurrentPowerSource ps4000aSetChannel
ps4000aFlashLed ps4000aSetDataBuffer
ps4000aGetAnalogueOffset ps4000aSetDataBuffers
ps4000aGetChannelInformation ps4000aStop
ps4000aGetMaxDownSampleRatio resetDevice
ps4000aGetMaxSegments setChannelDefaults
ps4000aGetTimebase2

mc1
Newbie
Posts: 0
Joined: Thu Feb 07, 2019 8:09 pm

Re: Rapid Block Memory Segments

Post by mc1 » Mon Feb 25, 2019 3:51 pm

Hitesh,

I realized I had a type-o in my code that was holding things up a bit on rapidBlock. However, I'm still running into some trouble setting up the buffer. I've been piecing it together as follows:

Code: Select all

overviewBufferSize  = 250000; % Size of the buffer(s) to collect data from the driver's buffer(s).
segmentIndex        = 0;   
ratioMode           = ps4000aEnuminfo.enPS4000ARatioMode.PS4000A_RATIO_MODE_NONE;

pDriverBufferChA = libpointer('int16Ptr', zeros(overviewBufferSize, 1, 'int16'));

status.setDataBufferChA = invoke(ps4000aDeviceObj, 'ps4000aSetDataBuffer', ...
    chA, pDriverBufferChA, overviewBufferSize, segmentIndex, ratioMode);


pAppBufferChA = libpointer('int16Ptr', zeros(overviewBufferSize, 1));


% Register application buffer and driver buffers (with the wrapper driver).
status.setAppAndDriverBuffersA = invoke(streamingGroupObj, 'setAppAndDriverBuffers', chA, ...
    pAppBufferChA, pDriverBufferChA, overviewBufferSize);
When I run ps4000aGetValuesBulk as seen below I get the error that the buffers are not set up

Code: Select all

[numSamples, overflow, chA] = invoke(rapidBlockGroupObj, 'ps4000aGetValuesBulk', 20000, 0, 1, 1, 0);

Code: Select all

ps4000aGetValuesBulk:- Status code: 70. Please refer to the PicoStatus.m file.
with code 70 being PICO_BUFFERS_NOT_SET: 70

Any advice on setting up the buffer(s)? And do I need to set up a buffer for each memory segment I plan to use?

Martyn
Site Admin
Site Admin
Posts: 3709
Joined: Fri Jun 10, 2011 8:15 am
Location: St. Neots

Re: Rapid Block Memory Segments

Post by Martyn » Mon Mar 04, 2019 9:54 am

If you are going to use ps4000aGetValuesBulk you will need to set up buffers for all the segments before calling this function.
Martyn
Technical Support Manager

mc1
Newbie
Posts: 0
Joined: Thu Feb 07, 2019 8:09 pm

Re: Rapid Block Memory Segments

Post by mc1 » Fri Mar 08, 2019 7:38 pm

So I have set up two buffers and two memory segments and the code will run but it doesn't seem to capture the data.

Code: Select all

% Set Memory Segments
 nSegments = 2;

[status.memorySegments, nMaxSamples] = invoke(ps4000aDeviceObj, 'ps4000aMemorySegments', nSegments);


% nCaptures : 1   1 capture per segment

numCaptures = 1;
[status.setNoOfCaptures] = invoke(rapidBlockGroupObj, 'ps4000aSetNoOfCaptures', numCaptures);


%set buffers

overviewBufferSize  = 250000; % Size of the buffer(s) to collect data from the driver's buffer(s).
segmentIndex        = 0;   
ratioMode           = ps4000aEnuminfo.enPS4000ARatioMode.PS4000A_RATIO_MODE_NONE;

% buffer for segment 0
pDriverBufferChA = libpointer('int16Ptr', zeros(overviewBufferSize, 1, 'int16'));

status.setDataBufferChA = invoke(ps4000aDeviceObj, 'ps4000aSetDataBuffer', ...
    chA, pDriverBufferChA, overviewBufferSize, segmentIndex, ratioMode);


% buffer for segment 1
pDriverBufferChA1 = libpointer('int16Ptr', zeros(10000,1));

status.setDataBufferChA1 = invoke(ps4000aDeviceObj, 'ps4000aSetDataBuffer', ...
    chA, pDriverBufferChA1, overviewBufferSize, 1, ratioMode);




% Capture the blocks of data

% segmentIndex : 0 

[status.ps4000aRunBlock, timeIndisposedMs] = invoke(blockGroupObj, 'ps4000aRunBlock', 0);

pause(1) %while waveform changes

% segmentIndex : 1 
[status.ps4000aRunBlock, timeIndisposedMs] = invoke(blockGroupObj, 'ps4000aRunBlock', 1);
pause(1)

[nCaptures] = invoke(rapidBlockGroupObj ,'ps4000aGetNoOfCaptures')

%Transfer from the pico to matlab

noOfSamples = 20000;
fromSegmentIndex = 0;
toSegmentIndex = 1;
downSampleRatio = 1;
downSampleRatioMode = 0;
 
[numSamples, overflow, chA] = invoke(rapidBlockGroupObj, 'ps4000aGetValuesBulk', noOfSamples, ...
    fromSegmentIndex, toSegmentIndex, downSampleRatio, downSampleRatioMode);
The following code returns zero, indicating no data has been captured. I know the data is there because I can manually call one segment at time with getBlockData.

Code: Select all

 [nCaptures] = invoke(rapidBlockGroupObj ,'ps4000aGetNoOfCaptures') 
Also, my ChA array just becomes a 1x1 with values of 1, when it should have a full dataset.

Any idea on why I'm not getting the data into MATLAB?

Martyn
Site Admin
Site Admin
Posts: 3709
Joined: Fri Jun 10, 2011 8:15 am
Location: St. Neots

Re: Rapid Block Memory Segments

Post by Martyn » Fri Mar 08, 2019 7:42 pm

If you want two captures you need numCaptures set to 2 as well as memory segments.
Martyn
Technical Support Manager

mc1
Newbie
Posts: 0
Joined: Thu Feb 07, 2019 8:09 pm

Re: Rapid Block Memory Segments

Post by mc1 » Fri Mar 08, 2019 7:56 pm

with numCaptures set to 2 I get the exact same results.

Post Reply