Test and Measurement Forum

Buffer problem in fast streaming

Post general discussions on using our drivers to write your own software here

Buffer problem in fast streaming

Postby Morris » Mon Nov 09, 2009 5:10 pm

I am launching fast streaming with the following Delphi code :

[color=#0000FF]ps3000_set_ets ( ps3000_handle, 0, 0, 0 );

ps3000_set_channel ( ps3000_handle, 0, true, false, 9 );

ps3000_set_channel ( ps3000_handle, 1, true, false, 9 );

ps3000_set_trigger ( ps3000_handle, 5, 0, 0, 0, 0 );

ps3000_get_timebase ( ps3000_handle, 13, 10000,
time_interval, time_units, 1, max_samples );

GetResult := ps3000_run_streaming_ns ( ps3000_handle, 1 , ptuMicroSec,
100000, 0, 1, 100000);[/color]

I then launch the following code every 10 milliseconds :

[color=#0000FF] GetResult := ps3000_get_streaming_last_values(ps3000_handle,
@myCallBack ) ;[/color]



myCallBack contains the code :

[color=#0000FF]procedure myCallBack (var ovBuffer : smallint ;
overflow : smallint ;
TriggeredAt : Cardinal ;
Triggered : smallint ;
AutoStop : smallint ;
nValues : Cardinal ) stdcall ;
var vArray : TValuesArray ;
vArrayPtr : ^TValuesArray ;
begin
try
vArrayPtr := @ovBuffer ;
vArray := vArrayPtr^ ;
………..
except
gFailed := true ;
SendStringToMonitor('Exception raised vArrayPtr = ' +
IntToStr(longword(vArrayPtr)) + ' Length = ' +
IntToStr(aLength));
end ;
end ;[/color]
This code works very well except for one problem. When the total number of samples passes through the overview buffer size (100,000 in the above example) one of two things occurs:
1. A memory exception is triggered. This only appears to happen for sample periods greater than 10 microseconds)
2. The data stream becomes corrupted for 24 samples.

I have tried it for a number of sample periods and a number of overview buffer sizes.

The behaviour is consistent with the above summary for overview buffer sizes from 30000 to 150000.

Can anyone please help me solve this problem?

Thank you.
Morris
User
User
 
Posts: 2
Joined: Tue Jun 16, 2009 10:56 pm

Re: Buffer problem in fast streaming

Postby Robin » Tue Nov 10, 2009 10:36 am

Hi Morris

I'm not very familiar with Delphi, but I have used our C++ fast streaming example, which works in a similar way. I have tried setting the timer to 10 ms and buffer size to 30,000 and 100,000 and not had any errors.

If you have not seen this example already, it might be useful. The SDK can be downloaded via http://www.picotech.com/software.html

If you can recreate this problem in the example or want me to try anything, let me know.

Robin
Robin
Zen Master
Zen Master
 
Posts: 558
Joined: Fri Sep 19, 2008 10:17 am

Re: Buffer problem in fast streaming

Postby Morris » Tue Nov 10, 2009 10:49 pm

Thank you, Robin.

I have continued to work on the problem, and realise that it might be due to my not understanding the overview buffer structure. If I inspect the overview buffer, starting at the location pointed to by the parameter passed to the ps3000_get_streaming_last_values procedure, I can access three times the overview buffer size, that is an array [1..3,0..ovBufferSize).
The first row seems to contain Channel A sampled data.
The second row seems to contain the same data, time shifted by a few samples.

The third row seems to contain the Channel B data and that is the one which shows discontinuities.

If I try to access the "fourth row", an exception is raised.

If you could please clarify the use of the buffers by the PicoScope driver, I might be able to overcome the problem.

Thank you again for your help.

Dr. Morris Lockwood
Morris
User
User
 
Posts: 2
Joined: Tue Jun 16, 2009 10:56 pm

Re: Buffer problem in fast streaming

Postby Morris » Wed Nov 11, 2009 10:57 am

I have explored further and I can now access four memory arrays.

The first is Channel A and dxoes not have any transients at the transition at the end of the buffer.

The second is Channel A delayed by 12 samples. It does have a transient at the buffer rollover.

The third is Channel B delayed by 24 samples with respect to the first one. It does have a transient at the buffer rollover.

The third is Channel B delayed by a further 12 samples (that is 36 with respect to the first one). It does have a transient at the buffer rollover.

I will try to upload a screen shot of the waveforms. Both A and B inputs are connected to the 10 kHz sinewave input signal.
Attachments
MemoryTransition.doc
(37 KiB) Downloaded 117 times
Morris
User
User
 
Posts: 2
Joined: Tue Jun 16, 2009 10:56 pm

Re: Buffer problem in fast streaming

Postby Robin » Wed Nov 11, 2009 2:52 pm

Hi Morris

The driver will always return min and max buffers for each channel (even if you set aggregation to 1).

I'm not sure why you are seeing gaps in the data. Are you reading more than nSamples values? You shouldn't need to worry about the buffer rollover, you just need to read the nSamples starting at the buffer pointer each time your callback function is called.

Robin
Robin
Zen Master
Zen Master
 
Posts: 558
Joined: Fri Sep 19, 2008 10:17 am

Re: Buffer problem in fast streaming

Postby Morris » Wed Nov 11, 2009 3:51 pm

Robin,

Thank you for your response.

I am using aggregation set to 1.

The reading code I am using is :
type
TValuesArray = array of smallint ;
var
vArray : TValuesArray ;

That is vArray is an undimensioned array of small integer
procedure SimpleFastStream(var ovBuffer : smallint ;
overflow : smallint ;
TriggeredAt : Cardinal ;
Triggered : smallint ;
AutoStop : smallint ;
nValues : Cardinal ) stdcall ;
var vArray : TValuesArray ;
k : integer ;
oIndex : longint ;
a, b, c, d : longint ;
begin
try
vArrayPtr := @ovBuffer ;
vArray := vArrayPtr^ ;
if nvalues > 0 then
begin
for k := 0 to nValues - 1 do
begin
oIndex := gSampleCount + k ;
try
a := vArray[k] ;
b := vArray[ovBufferSize + k] ;
c := vArray[2*ovBufferSize + k] ;
// d := vArray[3*ovBufferSize + k] ;

..............

As I mentioned, there is a 12 sample stagger between the 4 buffers.

Any ideas?

Morris
Morris
User
User
 
Posts: 2
Joined: Tue Jun 16, 2009 10:56 pm

Re: Buffer problem in fast streaming

Postby Robin » Thu Nov 12, 2009 2:10 pm

Hi Morris

The way you are accessing the buffers assumes that they are contiguous, which isn't necessarily the case.

The driver passes your function an array of pointers. Each one points to a buffer.

Have a look at our example, which does the following to access the data buffers.

Code: Select all
         
      if(g_DeviceSetting.channel_Setting[PS3000_CHANNEL_A].enabled)
      {
         memcpy(g_display.buffer_max_a + (g_NumberOfSamples - nValues), overviewBuffers[0], nValues * sizeof(short));
         memcpy(g_display.buffer_min_a + (g_NumberOfSamples - nValues), overviewBuffers[1], nValues * sizeof(short));
      }

      if(g_DeviceSetting.channel_Setting[PS3000_CHANNEL_B].enabled)
      {
         memcpy(g_display.buffer_max_b + (g_NumberOfSamples - nValues), overviewBuffers[2], nValues * sizeof(short));
         memcpy(g_display.buffer_min_b + (g_NumberOfSamples - nValues), overviewBuffers[3], nValues * sizeof(short));
      }

      if(g_DeviceSetting.channel_Setting[PS3000_CHANNEL_C].enabled)
      {
         memcpy(g_display.buffer_max_c + (g_NumberOfSamples - nValues), overviewBuffers[4], nValues * sizeof(short));
         memcpy(g_display.buffer_min_c + (g_NumberOfSamples - nValues), overviewBuffers[5], nValues * sizeof(short));
      }

      if(g_DeviceSetting.channel_Setting[PS3000_CHANNEL_D].enabled)
      {
         memcpy(g_display.buffer_max_d + (g_NumberOfSamples - nValues), overviewBuffers[6], nValues * sizeof(short));
         memcpy(g_display.buffer_min_d + (g_NumberOfSamples - nValues), overviewBuffers[7], nValues * sizeof(short));
      }




Robin
Robin
Zen Master
Zen Master
 
Posts: 558
Joined: Fri Sep 19, 2008 10:17 am

Re: Buffer problem in fast streaming

Postby Morris » Mon Nov 16, 2009 9:40 am

Thank you Robin.

I have now solved the problem which was associated with how two dimensional arrays are declared in Delphi an C++.

The following code fragments explain the solution:
[code]
type TValuesArray = array of array of smallint ;
TValuesArrayPtr = ^TValuesArray ;

procedure SimpleFastStream( ovBuffer : smallint ;
overflow : smallint ;
TriggeredAt : Cardinal ;
Triggered : smallint ;
AutoStop : smallint ;
nValues : Cardinal ) stdcall ;
var

aValue : smallint ;
vArray : TValuesArray ;
vArrayPtr : ^TValuesArray ;
k : integer ;
a, b, c, d : smallint ;
begin
try
vArrayPtr := @ovBuffer ;
vArray := vArrayPtr^ ;

if nvalues > 0 then
begin
for k := 0 to nValues - 1 do
begin
a := vArray[0,k] ;
b := vArray[1,k] ;
c := vArray[2,k] ;
d := vArray[3,k] ;
{......... do something useful}
end ;

[/code]

Clearly, this code can be improved but the basic method of de-referencing works.

Thank you again for you help.

Morris
Morris
User
User
 
Posts: 2
Joined: Tue Jun 16, 2009 10:56 pm


Return to General Software Discussions

Who is online

Users browsing this forum: No registered users and 4 guests