Test and Measurement Forum

Pico 4000 series scope hangs using triggers

Post your C and C++ discussions here

Pico 4000 series scope hangs using triggers

Postby dlodini » Mon Jun 07, 2010 8:32 pm

I am adding the Pico 4000 series scope driver to our company's scope software. We previously had the 3000 scope working. After making some changes, I got the scope working for untriggered data correctly. When activating some triggers the program and scope hang.

I believe the program is waiting for the callback from the scope but never gets it. The program will not close until I unplug and plug in the USB cable.

Another thing to note is the triggering works correctly for one block sample. The crash happens when I enter in a loop where it keeps getting samples and displaying them. This same loop works fine with no triggers set.
dlodini
Newbie
 
Posts: 0
Joined: Mon Jun 07, 2010 8:06 pm

Re: Pico 4000 series scope hangs using triggers

Postby Robin » Tue Jun 08, 2010 12:19 pm

Hi

Below is a simple example to check that the 'scope is triggering and calling the callback function.

If this doesn't help you, can you post the relevant section of your code?

Thanks

Robin

Code: Select all
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include "ps4000Api.h"

short gReady;

void _stdcall ReadyCallback(short handle, PICO_STATUS status, void * pParameter)
{
   gReady = 1;
}

void main()
{
   long               nSamples = 2000;
   unsigned long timebase = 400;
   short threshold = 0;

   PICO_STATUS status;
   short handle;

   if(ps4000OpenUnit(&handle) != PICO_OK) return;

   if(ps4000SetChannel(handle, PS4000_CHANNEL_A, 1, 1, PS4000_1V) != PICO_OK) return;
   if(ps4000SetChannel(handle, PS4000_CHANNEL_B, 1, 1, PS4000_1V) != PICO_OK) return;

   
   //Set up the trigger

   TRIGGER_CONDITIONS conditions;
   conditions.channelA = CONDITION_DONT_CARE;
   conditions.channelB = CONDITION_TRUE;
   conditions.channelC = CONDITION_DONT_CARE;
   conditions.channelD = CONDITION_DONT_CARE;
   conditions.aux = CONDITION_DONT_CARE;
   conditions.pulseWidthQualifier= CONDITION_DONT_CARE;

   TRIGGER_CHANNEL_PROPERTIES properties;
   properties.thresholdLower = 0;
   properties.thresholdUpper = threshold;
   properties.thresholdLowerHysteresis = 0;
   properties.thresholdUpperHysteresis = 300;
   properties.channel = PS4000_CHANNEL_B;
   properties.thresholdMode = LEVEL;

   if(ps4000SetTriggerChannelConditions(handle, &conditions, 1) != PICO_OK) return;
   if(ps4000SetTriggerChannelDirections(handle, NONE, RISING, NONE, NONE, NONE, NONE) != PICO_OK) return;
   if(ps4000SetTriggerChannelProperties(handle, &properties, 1, 0, 0) != PICO_OK) return;

   long timeIndisposed;

   short counter = 0;
   while(!_kbhit())
   {
      gReady = 0;
      if((status = ps4000RunBlock(handle, 0, nSamples, timebase, 1, &timeIndisposed, 0, ReadyCallback, NULL)) != PICO_OK)
      {
         printf("ps4000RunBlock status = %Xh", status);
         _getch();
         return;
      }

      while(gReady == 0)
      {
         Sleep(0);
      }
      
      printf("Trigger: %d\n", counter++);

   }
   ps4000CloseUnit(handle);
}
Robin
Zen Master
Zen Master
 
Posts: 558
Joined: Fri Sep 19, 2008 10:17 am

Re: Pico 4000 series scope hangs using triggers

Postby dlodini » Tue Jun 08, 2010 1:34 pm

Actually, I did make some progress since my last post. I believe the problem is with calling the ps4000Stop. According to the spec we should not call this function between samples. However, this seems to work differently with or without triggering and I am not sure why. Like I said previously, we originally had the 3000 series scope working with this code. So the code originally called the stop between each sample. Our original code had two states. One state it called the functions to setup the scope channel, triggers, etc and call runblock. The second state would check to see if data is ready, stop the run and get the values, then switch to the first state. I took out the stop state and instead of having the second state call the first, I reset my bool value for ready and called runblock and kept it on the first state for the next getvalue.

The problem is this method freezes when I have it set to not having a trigger but with the trigger it works fine. I add the stop back in and basically follow the same algorithm as the old scope and no trigger works fine but setting up the trigger hangs. I would expect the scope to work the same with or with the trigger, but that is not what I am seeing. I set up some if statements to work around the problem and it is getting messy. Messy, and still does not work right. The scope now hangs when I switch the trigger modes.
dlodini
Newbie
 
Posts: 0
Joined: Mon Jun 07, 2010 8:06 pm

Re: Pico 4000 series scope hangs using triggers

Postby Robin » Tue Jun 08, 2010 2:05 pm

You should call stop only when you have finished calling GetData, regardless of whether you are triggering or not.

Can you post the relivent code, as it's difficult to say what is going wrong otherwise?

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

Re: Pico 4000 series scope hangs using triggers

Postby dlodini » Tue Jun 08, 2010 2:38 pm

Here is some code. If you need more to get the idea of what is going on then let me know. One thing to note. GetData will be called over and over. The state will be set back to init if we change triggers or channel settings. I think this is where it is hanging the most, when it is set back to init to change all the settings. But the otherwise, the hangs appear to be random. Sometime I switch trigger modes with no problems, other times it hangs.

BOOL CPico4000Driver::InitScope(CEaseScopeDoc *pDoc)
{
if (!this->m_trigger.Load(pDoc))
return FALSE;
if (!this->SetScopeChannels())
return FALSE;
if (!this->PrepareTimebase(pDoc))
return FALSE;
if (!this->SetScopeTrigger())
return FALSE;
if (!this->RunBlock())
return FALSE;
return TRUE;
}



int CPico4000Driver::GetData(CEaseScopeDoc *pDoc, CNiReal64Vector& data1, long& lMinMV1, BOOL& bOverflow1, CNiReal64Vector& data2, long& lMinMV2, BOOL& bOverflow2)
{
int nResult = DRIVER_NONE;

// Check for valid document.
if (m_pDocument != pDoc && m_pDocument)
return nResult;

m_pDocument = pDoc;

// Check if we can collect the data.
if (m_bReset || g_bHalt || !IsOpen() || pDoc->m_nState != STATE_AQUIREDATA)
{
Stop();
return nResult;
}

if (!this->PrepareChannels(pDoc, data1, lMinMV1, bOverflow1, data2, lMinMV2, bOverflow2))
{
m_pDocument = NULL;
return nResult;
}


if (m_nState == INIT)
{
if (!this->InitScope(pDoc))
return nResult;
m_nState = DATA;
}
else if (m_nState == DATA)
{
int nReady = this->CheckDataReady();
if (nReady < 0) // Error
{
m_nState = INIT;
m_pDocument = NULL;
}

if (nReady <= 0) // Error or not ready.
return nResult;
// Data is ready.
if (this->ReadData())
{
nResult |= DRIVER_GRAPH;
if (this->m_trigger.GetMode() == TRIGGER_MODE_SINGLE)
{
pDoc->SetParmLong(kszChannelOnOff, 0, FALSE);
nResult |= DRIVER_CONTROLS;
}
}

if(this->m_trigger.GetMode()!=TRIGGER_MODE_OFF)
{
bDataReady=FALSE;
if (!this->RunBlock())
return FALSE;
}
else m_nState=INIT;

m_pDocument = NULL;
}

return nResult;
}
dlodini
Newbie
 
Posts: 0
Joined: Mon Jun 07, 2010 8:06 pm

Re: Pico 4000 series scope hangs using triggers

Postby dlodini » Tue Jun 08, 2010 9:17 pm

I have been thinking about this some more and I have a couple questions.

Between samples we are not suppose to call ps4000stop. How about if we are about to switch triggering or channel properties? Also, if we are not to call stop before doing this, then what will happen if we switch settings while it is in the middle of a block run?

If this could cause a problem, then is there any way to determine if the scope is in the middle of a run or is it up to us to keep track of that?
dlodini
Newbie
 
Posts: 0
Joined: Mon Jun 07, 2010 8:06 pm

Re: Pico 4000 series scope hangs using triggers

Postby dlodini » Wed Jun 09, 2010 1:52 pm

Actually, I think I may have just fixed it. The problem was that when an error occured I durring the Init I reran the Init block again. There was no call to Stop; however, It looks like the scope does not like resetting everything up before taking a sample. I took out the line to reset the state to Init and I have not had any hangs since. Other changes I made are: No matter what the trigger mode I do not rerun the init, and before I run the init I make sure there is no block running. I don't know if these changes make a difference, but they don't hurt.

I am going have to test this longer to make sure the issue is totally gone, since it was pretty random. However, it is looking good so far.
dlodini
Newbie
 
Posts: 0
Joined: Mon Jun 07, 2010 8:06 pm

Re: Pico 4000 series scope hangs using triggers

Postby Robin » Wed Jun 09, 2010 3:01 pm

I'm glad it's working.

You don't need to call stop to change channel or trigger settings. However, you should not change them between calling RunBlock and the driver calling your callback function.

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

Re: Pico 4000 series scope hangs using triggers

Postby dlodini » Wed Jun 09, 2010 8:00 pm

That is for sure. The Scope was locking right up. However, it also looks like we should not set up the channels and triggers twice without sampling between. This appears to be what my trouble was. My Init state was set to init state again before collecting data and which caused the problem.

if (nReady < 0) // Error
{
m_nState = INIT;
m_pDocument = NULL;
}

I after setting up the scope it never started a block, it just went back into setting up the scope again.
dlodini
Newbie
 
Posts: 0
Joined: Mon Jun 07, 2010 8:06 pm

Re: Pico 4000 series scope hangs using triggers

Postby dlodini » Wed Jun 23, 2010 3:03 pm

I have another question related to this issue. If a trigger is setup with a range that it never hits. Is there a way to abort if we can't call ps4000Stop between the runblock and the callback. In this case we would have started the runblock but the callback would never be called so we can't call ps4000Stop. How can we abort in this case?
dlodini
Newbie
 
Posts: 0
Joined: Mon Jun 07, 2010 8:06 pm

Re: Pico 4000 series scope hangs using triggers

Postby Robin » Thu Jun 24, 2010 7:40 am

Hi

If you want to abort waiting for a trigger, you should call ps4000Stop. You can then call RunBlock again. After calling ps4000Stop, the driver will call the callback function with, I believe, a status of PICO_CANCELLED.

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

Re: Pico 4000 series scope hangs using triggers

Postby dlodini » Mon Jun 28, 2010 2:32 pm

That worked, thanks.
dlodini
Newbie
 
Posts: 0
Joined: Mon Jun 07, 2010 8:06 pm


Return to C and C++

Who is online

Users browsing this forum: No registered users and 0 guests