Working with multiple picoscopes

Post your .Net discussions here
Post Reply
mzeeshan
Newbie
Posts: 0
Joined: Wed Jun 28, 2017 7:26 am

Working with multiple picoscopes

Post by mzeeshan »

Hello,

I have been working on an application with multiple picoscopes. I started with a single channel first. Previously, I had posted a question regarding my requirements of acquisition in block mode at 10Hz rate (topic30981.html). At that time when I tried to run everything within a 10Hz timer, the random delay in RunBlock and GetValues caused problems after several packets. So to solve that I came up with the following solution (which is the current structure I'm following):

The program works in two parts:

A) In data capturing part, commands to RunBlock and GetValues are sent much faster than 10Hz and the results are copied to another buffer.
B) At every 10Hz timer tick, the data processing part copies the value in the buffer to its own buffer for processing.

This makes sure that data processing part does not have to wait for the delay in RunBlock and GetValues and gets the latest packet from the input signal.

Now all this works well for a single picoscope which is actually a Windows form running on a separate thread. However, when I run multiple picoscopes (four at a time), each running on a separate thread, I observe some random stalling in a random picoscope. All picoscopes work well for a short period of time and then randomly some picoscope seems to be unable to get a new value. I have been trying to trace the problem for long time (its difficult since everything happens in realtime and with four picoscopes) but finally I found that the problem occurs because of random high delay in GetValues command. Once the command is sent before that problem occurs, the program gets stuck at GetValues for as long as a few seconds sometimes and then a new value is copied to the buffer. Now I check the buffer is not occupied during that time.

So, I came to the conclusion that the picoscope cannot get the access to the USB sometimes and once it loses access its hard to get it since all other picoscopes are always trying to access the USB at a rate higher than 10Hz. This of course forced me to check my USB connections. The four picoscopes all connect with a 4 port, USB 3.0 hub which then connects to a USB 3.0 port on the PC. I quickly checked with individually connecting each picoscope with a single USB 3.0 port (fortunately they were available on the PC) but the problem did happen again.

I connected the 4 picoscopes back to the hub as I quickly thought about testing your PicosScope 6 software. I opened 4 instances and as I watched the waveforms, even though I could see very very short jerks (almost not perceivable) but I did not see that problem. Now that could mean that may be you guys of course do not have the requirement of fixed 10 Hz so probably you can work with the random delay sometimes.

But now here is the question that popped in my head after all this, does the picoscope driver or the USB controlling driver treats simultaneous USB access requests from the same process differently as compared to the requests from separate applications? Since all picoscopes even though running on separate thread, still belong to the same process in a single application. So may be if I try to run each picoscope in a separate application, it might work? Also do you think that the four picoscopes to a single USB 3.0 at rate higher than 10Hz can take up all the data rate bandwidth of USB 3.0?

Need your help regarding all this please.

Thank you for reading this long post.

Best regards,

Shan

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

Re: Working with multiple picoscopes

Post by Martyn »

It would help to know some more detail about your data collection :-

1. How many samples you are collecting in each block ?
2. How many channels are enabled on each device ?
3. What is the sample interval ?
4. Is this the same for all of the scopes ?
Martyn
Technical Support Manager

mzeeshan
Newbie
Posts: 0
Joined: Wed Jun 28, 2017 7:26 am

Re: Working with multiple picoscopes

Post by mzeeshan »

Sample interval = 8ns
4) All four picoscopes have the same configuration

Here's how Im getting the block in a loop. (The loop only has a small 25ms sleep time, other than that it keeps running so that it can get at least a single value every 0.1s duration, and the data processing module running at 10Hz, can copy this latest value for processing.)

Code: Select all

 while (!stopPicoscope) //is set to true if user stops the processing
            {
                do
                {
                    retry = false;
                    status = Imports.RunBlock(_handle, 0, (int)sampleCount, _timebase, out timeIndisposed, 0, _callbackDelegate, IntPtr.Zero);

                    if (status == (short)StatusCodes.PICO_POWER_SUPPLY_CONNECTED || status == (short)StatusCodes.PICO_POWER_SUPPLY_NOT_CONNECTED || status == (short)StatusCodes.PICO_POWER_SUPPLY_UNDERVOLTAGE)
                    {
                        status = Imports.ChangePowerSource(_handle, status);
                        retry = true;
                    }
                    else
                    {
                        //textMessage.AppendText("Run Block Called\n");
                    }
                }
                while (retry);

                while (!_ready)
                {
                    //Thread.Sleep();
                }

                Imports.Stop(_handle);

                if (_ready)
                {
                    short overflow;
                    status = Imports.GetValues(_handle, 0, ref sampleCount, 1, Imports.DownSamplingMode.None, 0, out overflow);

                    
                        if (copyNewValues) // is set to true in data processing module after data has been copied from receivedDataTmpChA/B buffer to dataprocessing module's own buffer
                        {
                            Array.Copy(maxBuffersChA, receivedDataTmpChA, maxBuffersChA.Length);
                            Array.Copy(maxBuffersChB, receivedDataTmpChB, maxBuffersChB.Length);
                            copyNewValues = false;
                        }                  

                    if (status == (short)StatusCodes.PICO_OK)
                    {
                        //textMessage.AppendText("Have Data\n");                        
                    }
                    else
                    {
                        //textMessage.AppendText("No Data\n");
                    }
                }
                else
                {
                    //textMessage.AppendText("data collection aborted\n");
                }

                Imports.Stop(_handle);
                Thread.Sleep(25); 
            }
-->
Sure here are the details

1) Sample count = 47, Timebase = 3, Signal frequency ~13MHz
2) Both channels enabled on 5242A
3) Timebase = 3 --> Sample interval = 8ns
4) All four picoscopes have the same configuration

Here's how Im getting the block in a loop. (The loop only has a small 25ms sleep time, other than that it keeps running so that it can get at least a single value every 0.1s duration, and the data processing module running at 10Hz, can copy this latest value for processing.)

Code: Select all

 while (!stopPicoscope) //is set to true if user stops the processing
            {
                do
                {
                    retry = false;
                    status = Imports.RunBlock(_handle, 0, (int)sampleCount, _timebase, out timeIndisposed, 0, _callbackDelegate, IntPtr.Zero);

                    if (status == (short)StatusCodes.PICO_POWER_SUPPLY_CONNECTED || status == (short)StatusCodes.PICO_POWER_SUPPLY_NOT_CONNECTED || status == (short)StatusCodes.PICO_POWER_SUPPLY_UNDERVOLTAGE)
                    {
                        status = Imports.ChangePowerSource(_handle, status);
                        retry = true;
                    }
                    else
                    {
                        //textMessage.AppendText("Run Block Called\n");
                    }
                }
                while (retry);

                while (!_ready)
                {
                    //Thread.Sleep();
                }

                Imports.Stop(_handle);

                if (_ready)
                {
                    short overflow;
                    status = Imports.GetValues(_handle, 0, ref sampleCount, 1, Imports.DownSamplingMode.None, 0, out overflow);

                    
                        if (copyNewValues) // is set to true in data processing module after data has been copied from receivedDataTmpChA/B buffer to dataprocessing module's own buffer
                        {
                            Array.Copy(maxBuffersChA, receivedDataTmpChA, maxBuffersChA.Length);
                            Array.Copy(maxBuffersChB, receivedDataTmpChB, maxBuffersChB.Length);
                            copyNewValues = false;
                        }                  

                    if (status == (short)StatusCodes.PICO_OK)
                    {
                        //textMessage.AppendText("Have Data\n");                        
                    }
                    else
                    {
                        //textMessage.AppendText("No Data\n");
                    }
                }
                else
                {
                    //textMessage.AppendText("data collection aborted\n");
                }

                Imports.Stop(_handle);
                Thread.Sleep(25); 
            }