Pico4424 streaming with Win10 64bits

Post your C and C++ discussions here
Post Reply
JohnCell
Newbie
Posts: 0
Joined: Mon Mar 26, 2018 2:53 pm

Pico4424 streaming with Win10 64bits

Post by JohnCell » Tue Mar 27, 2018 7:50 am

Hello Support Team !

I’ve developed a Win7 32bits Picoscope 4424 streaming application that has been working like a charm for many years.

Unfortunately, I’m struggling to port this application to Win10 64bits.
The Pico 4424 is crashing (LED turns off) after a few second of streaming acquisition.

On Win10 64bits, I’m only able to run the streaming for a very short time (1 or 2 sec) and one single channel. Longer acquisition or adding channels crashes…
Of course, I’m using the latest 64bits SDK.

Please find attached my streaming and callback functions.
Any suggestion would be greatly appreciated !!

Thanks
John

Code: Select all


PICO_STATUS     CurrentStatus;
int16_t         Handle;


 // Open PicoScope 4000.
 CurrentStatus = ps4000OpenUnit( &Handle );


 // Check retuned Pico Handle.
 if( Handle == 0 )
  {
    wxEndBusyCursor();
    wxMessageBox( wxString("Sorry,\nNo Picoscope found : ")  << PicoGetErrorText( CurrentStatus ) <<  "\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
    return( -1 );
  }

 if( Handle == -1 )
  {
    wxEndBusyCursor();
    wxMessageBox( wxString("Sorry,\nFailed to open Picoscope  : ")  << PicoGetErrorText( CurrentStatus ) <<  "\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
    return( -1 );
  }



 // Check returned Pico Status.
 if(   ( CurrentStatus != PICO_OK )  && ( CurrentStatus != PICO_EEPROM_CORRUPT )  )
  {
    wxEndBusyCursor();
    wxMessageBox( wxString("Sorry,\n Bad Pico Status returned: ")  << PicoGetErrorText( CurrentStatus ) <<  "\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
    return( -1 );
  }


 // Free Pico Data buffers.
 for( int i=0; i < PICO_CHANNELS_MAX_NB; i++)
 if( GLOBAL_PicoSignal_Data[i] != NULL )
   {
      delete [] GLOBAL_PicoSignal_Data[i];
      GLOBAL_PicoSignal_Data[i] = NULL;
   }



 // Compute sample number.
 GLOBAL_PicoSignal_SampleNumber = uint32_t( float( RibbonPico_SamplingDuration_SpinCtrl->GetValue()  ) / float( GLOBAL_PicoSignal_SamplingPeriod )* float( 1.0e9 )   );




 // Select channels, range and coupling.
 // >> Channel A <<
 if( GLOBAL_PicoSignal_VoltageRange[0] != -1 )
  {
    // Memory alloc.
    GLOBAL_PicoSignal_Data[0] = new int16_t[ GLOBAL_PicoSignal_SampleNumber ];

    // Setup Data channel A.
    CurrentStatus = ps4000SetChannel( Handle, PS4000_CHANNEL_A, int16_t( true ), int16_t( GLOBAL_PicoSignal_CouplingMode[0] ), (PS4000_RANGE)GLOBAL_PicoSignal_VoltageRange[0] );                       // Channel A activated, DC coupling, +/-5V range.
    if( CurrentStatus != PICO_OK )
      {
        CurrentStatus = ps4000CloseUnit( Handle );
        wxEndBusyCursor();
        wxMessageBox( "Can't set channel A.\n\nExiting.", "PicoScope error", wxOK |wxICON_ERROR );
        return( -1 );
       }
    CurrentStatus = ps4000SetDataBuffer( Handle, PS4000_CHANNEL_A, GLOBAL_PicoSignal_Data[0], GLOBAL_PicoSignal_SampleNumber );
    if( CurrentStatus != PICO_OK )
     {
        CurrentStatus = ps4000CloseUnit( Handle );
        wxEndBusyCursor();
        wxMessageBox( wxString( "Error allocating Channel A buffer :") << PicoGetErrorText( CurrentStatus ) << "\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
        return( -1 );
     }

   }
 else
    CurrentStatus = ps4000SetChannel( Handle, PS4000_CHANNEL_A, int16_t( false ), GLOBAL_PicoSignal_CouplingMode[0], (PS4000_RANGE)GLOBAL_PicoSignal_VoltageRange[0] );                       // Channel A activated, DC coupling, +/-5V range.





 // >> Channel B <<
 if( GLOBAL_PicoSignal_VoltageRange[1] != -1 )
  {
    // Memory alloc.
    GLOBAL_PicoSignal_Data[1] = new int16_t[ GLOBAL_PicoSignal_SampleNumber ];

    // Setup Data channel B.
    CurrentStatus = ps4000SetChannel( Handle, PS4000_CHANNEL_B, int16_t( true ), int16_t( GLOBAL_PicoSignal_CouplingMode[1] ), (PS4000_RANGE)GLOBAL_PicoSignal_VoltageRange[1] );                       // Channel B activated, DC coupling, +/-5V range.
    if( CurrentStatus != PICO_OK )
     {
        CurrentStatus = ps4000CloseUnit( Handle );
        wxEndBusyCursor();
        wxMessageBox( "Can't set channel B.\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
        return( -1 );
      }

    CurrentStatus = ps4000SetDataBuffer( Handle, PS4000_CHANNEL_B, GLOBAL_PicoSignal_Data[1], GLOBAL_PicoSignal_SampleNumber );
    if( CurrentStatus != PICO_OK )
     {
        CurrentStatus = ps4000CloseUnit( Handle );
        wxEndBusyCursor();
        wxMessageBox( "Error allocating Channel B buffer.\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
        return( -1 );
      }
  }
 else
    CurrentStatus = ps4000SetChannel( Handle, PS4000_CHANNEL_B, int16_t( false ), GLOBAL_PicoSignal_CouplingMode[1], (PS4000_RANGE)GLOBAL_PicoSignal_VoltageRange[1] );                       // Channel A activated, DC coupling, +/-5V range.





 // >> Channel C <<
 if( GLOBAL_PicoSignal_VoltageRange[2] != -1 )
  {
    // Memory alloc.
    GLOBAL_PicoSignal_Data[2] = new int16_t[ GLOBAL_PicoSignal_SampleNumber ];

    // Setup Data channel C.
    CurrentStatus = ps4000SetChannel( Handle, PS4000_CHANNEL_C, int16_t( true ), int16_t( GLOBAL_PicoSignal_CouplingMode[2] ), (PS4000_RANGE)GLOBAL_PicoSignal_VoltageRange[2] );                       // Channel B activated, DC coupling, +/-5V range.
    if( CurrentStatus != PICO_OK )
     {
       CurrentStatus = ps4000CloseUnit( Handle );
       wxEndBusyCursor();
       wxMessageBox( "Can't set channel C.\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
       return( -1 );
     }
    CurrentStatus = ps4000SetDataBuffer( Handle, PS4000_CHANNEL_C, GLOBAL_PicoSignal_Data[2], GLOBAL_PicoSignal_SampleNumber );
    if( CurrentStatus != PICO_OK )
     {
       CurrentStatus = ps4000CloseUnit( Handle );
       wxEndBusyCursor();
       wxMessageBox( "Error allocating Channel C buffer.\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
       return( -1 );
     }
   }
 else
    CurrentStatus = ps4000SetChannel( Handle, PS4000_CHANNEL_C, int16_t( false ), GLOBAL_PicoSignal_CouplingMode[2], (PS4000_RANGE)GLOBAL_PicoSignal_VoltageRange[2] );                       // Channel A activated, DC coupling, +/-5V range.



 // >> Channel D <<
 if( GLOBAL_PicoSignal_VoltageRange[3] != -1 )
  {
    // Memory alloc.
    GLOBAL_PicoSignal_Data[3] = new int16_t[ GLOBAL_PicoSignal_SampleNumber ];

    // Setup data channel D.
    CurrentStatus = ps4000SetChannel( Handle, PS4000_CHANNEL_D, int16_t( true ), int16_t( GLOBAL_PicoSignal_CouplingMode[3] ), (PS4000_RANGE)GLOBAL_PicoSignal_VoltageRange[3] );                       // Channel B activated, DC coupling, +/-5V range.
    if( CurrentStatus != PICO_OK )
     {
       CurrentStatus = ps4000CloseUnit( Handle );
       wxEndBusyCursor();
       wxMessageBox( "Can't set channel D.\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
       return( -1 );
      }

    CurrentStatus = ps4000SetDataBuffer( Handle, PS4000_CHANNEL_D, GLOBAL_PicoSignal_Data[3], GLOBAL_PicoSignal_SampleNumber );
    if( CurrentStatus != PICO_OK )
     {
       CurrentStatus = ps4000CloseUnit( Handle );
       wxEndBusyCursor();
       wxMessageBox( "Error allocating Channel D buffer.\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
       return( -1 );
     }
  }
 else
    CurrentStatus = ps4000SetChannel( Handle, PS4000_CHANNEL_D, int16_t( false ), GLOBAL_PicoSignal_CouplingMode[3], (PS4000_RANGE)GLOBAL_PicoSignal_VoltageRange[3] );                       // Channel A activated, DC coupling, +/-5V range.



 // >> Trigger << : *NO* trigger condition.
 TRIGGER_CONDITIONS conditions;
 conditions.channelA                    = CONDITION_DONT_CARE;
 conditions.channelB                    = CONDITION_DONT_CARE;
 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              = 0;
 properties.thresholdLowerHysteresis    = 0;
 properties.thresholdUpperHysteresis    = 300;
 properties.channel                     = PS4000_CHANNEL_A;
 properties.thresholdMode               = LEVEL;


 if( ps4000SetTriggerChannelConditions( Handle, &conditions, 1) != PICO_OK )
  {
    CurrentStatus = ps4000CloseUnit( Handle );
    wxEndBusyCursor();
    wxMessageBox( "Can't set Trigger Conditions.\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
    return( -1 );
  }

 if( ps4000SetTriggerChannelDirections(Handle, NONE, RISING, NONE, NONE, NONE, NONE) != PICO_OK)
  {
    CurrentStatus = ps4000CloseUnit( Handle );
    wxEndBusyCursor();
    wxMessageBox( "Can't set Trigger Direction.\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
    return( -1 );
  }

 if( ps4000SetTriggerChannelProperties(Handle, &properties, 1, 0, 0) != PICO_OK)
  {
    CurrentStatus = ps4000CloseUnit( Handle );
    wxEndBusyCursor();
    wxMessageBox( "Can't set Trigger Properties.\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
    return( -1 );
  }



 uint32_t   UsedSamplingPeriod = GLOBAL_PicoSignal_SamplingPeriod;
 int16_t    Pico_AutoStop_Flag = false;
 // Run streaming.

 CurrentStatus = ps4000RunStreaming( Handle, &UsedSamplingPeriod, PS4000_NS, uint32_t(10), uint32_t( GLOBAL_PicoSignal_SampleNumber -10 ), int16_t( true ), uint32_t( 1 ), GLOBAL_PicoSignal_SampleNumber  );
 if( CurrentStatus != PICO_OK )
  {
    CurrentStatus = ps4000CloseUnit( Handle );
    wxEndBusyCursor();
    wxMessageBox( wxString("Error running streaming: ") << PicoGetErrorText( CurrentStatus ) << "\n\nExiting.", "PicoScope error", wxOK | wxICON_ERROR );
    return( -1 );
  }


 // Streaming wait loop.
 while( Pico_AutoStop_Flag == false )
  {
    // Poll until data is received. Until then, GetStreamingLatestValues wont call the callback.
    Pico_StreamingDataReady_Flag = false;
    CurrentStatus = ps4000GetStreamingLatestValues( Handle, (ps4000StreamingReady)MyApp::PicoStreamingCallBack, NULL );
  }


 // Close.
 ps4000Stop( Handle );
 ps4000CloseUnit( Handle );



/******************************************************************************/
               void _stdcall  MyApp::PicoStreamingCallBack(   int16_t          handle,
                                                                   int32_t          noOfSamples,
                                                                   uint32_t         startIndex,
                                                                   int16_t          overflow,
                                                                   uint32_t         triggerAt,
                                                                   int16_t          triggered,
                                                                   int16_t          autoStop,
                                                                   void            *pParameter      )
{

 Pico_AutoStop_Flag              = autoStop;

 // Set data ready flag.
 Pico_StreamingDataReady_Flag    = true;

}

Hitesh
Site Admin
Site Admin
Posts: 2845
Joined: Tue May 31, 2011 3:43 pm
Location: St. Neots, Cambridgeshire

Re: Pico4424 streaming with Win10 64bits

Post by Hitesh » Tue Mar 27, 2018 9:40 am

Hi John,

Would it be possible to send a copy of your project to support@picotech.com please?

It might be useful to indicate when the crash occurs when running the program.

Regards,
Hitesh

Technical Support Engineer

JohnCell
Newbie
Posts: 0
Joined: Mon Mar 26, 2018 2:53 pm

Re: Pico4424 streaming with Win10 64bits

Post by JohnCell » Tue Mar 27, 2018 9:44 am

Hi Hitesh,

Thanks for your prompt answer.

You mean the *whole* project src files ?
Its gcc, wxWidgets, CodeBlocks; will you handle this ?

BR
John

Hitesh
Site Admin
Site Admin
Posts: 2845
Joined: Tue May 31, 2011 3:43 pm
Location: St. Neots, Cambridgeshire

Re: Pico4424 streaming with Win10 64bits

Post by Hitesh » Tue Mar 27, 2018 10:51 am

Hi John,

Looking through your code, there a couple of things to note:

1. In your streaming wait loop, it might be worth introducing a small sleep (1 to 10 ms should be fine) to ensure that the application is not hitting the driver repeatedly with requests for data.

2. In the streaming callback, please ensure that you are copying data from the drivers buffers to application buffers as per the example code available on GitHub.

No need to send the code for now.

Regards,
Hitesh

Technical Support Engineer

JohnCell
Newbie
Posts: 0
Joined: Mon Mar 26, 2018 2:53 pm

Re: Pico4424 streaming with Win10 64bits

Post by JohnCell » Tue Mar 27, 2018 1:32 pm

Hi Hitesh,
Thanks for your suggestions.

1- Delay
I've tried the 10ms delay in the waiting loop : Pico is still crashing. :cry:

2- Copy Buffers
This sounds unclear to me.
I've followed instruction from "4000 Series Programmers Guide" on streaming ( page 16 ).
I'm allocating one buffer for each used channel.
I'm setting up each buffers with "ps400SetDataBuffer" .
I do not use aggregation.

According to your remark, it sounds TWO buffers are required for each channel (Application one and Driver one).
I've also taken a look a sample "ps4000con.c" , but not it's that clear to me :?

Do we need to define two buffers for each channels ?

Thanks
John

Hitesh
Site Admin
Site Admin
Posts: 2845
Joined: Tue May 31, 2011 3:43 pm
Location: St. Neots, Cambridgeshire

Re: Pico4424 streaming with Win10 64bits

Post by Hitesh » Tue Mar 27, 2018 4:01 pm

Hi John,

The driver buffer is the one that you set with ps4000SetDataBuffer(). You set one for each channel.

The application buffer is a buffer that you copy the data from the driver buffer into in the streaming callback function so that you can then process the data in your main application. An application buffer is set up for each channel.

This is shown in the Streaming Callback definition in the ps4000con.c example.

Regards,
Hitesh

Technical Support Engineer

JohnCell
Newbie
Posts: 0
Joined: Mon Mar 26, 2018 2:53 pm

Re: Pico4424 streaming with Win10 64bits

Post by JohnCell » Wed Mar 28, 2018 7:39 am

Hi Hitesh,

My application only calls streaming one single time for an 8s long acquisition.
After this single streaming call, Pico is closed and data are processed by the app.

I mean there is never, in parallel, driver data acquisition and application data processing .
From my understanding, it seems no problem to use one single buffer.
First for driver acquisition.
And then, after Pico is closed, for app processing.

Is this correct ?
If yes, do you confirm I don't have to make a copy of driver buffer ?

Thanks so much for your help :D
John

Hitesh
Site Admin
Site Admin
Posts: 2845
Joined: Tue May 31, 2011 3:43 pm
Location: St. Neots, Cambridgeshire

Re: Pico4424 streaming with Win10 64bits

Post by Hitesh » Wed Mar 28, 2018 10:27 am

Hi John,

The driver buffer is used for retrieval of data from the driver. Typically during a data collection run (this is dependant on your settings), you might see data in the buffer from index 0 up to a certain point when the callback function is called, followed by data in the remaining portion of the buffer when the callback function is next called.

When the callback function is called again, you should find new data from the start of the buffer.

The above is why we recommend copying the data into application buffers - this could be one long buffer for the channel or a buffer of the same length as the driver buffer.

The alternative is to wait until the end of data collection and retrieve the data set from the driver using the ps4000GetValuesAsync() call.

Have you tried running our console example?

Regards,
Hitesh

Technical Support Engineer

JohnCell
Newbie
Posts: 0
Joined: Mon Mar 26, 2018 2:53 pm

Re: Pico4424 streaming with Win10 64bits

Post by JohnCell » Fri Mar 30, 2018 9:25 am

Hi Hitesh,

I wish you a happy Easter !
Back to problems... :?

First
I've isolated the issue, it comes from the call to ps4000RunStreaming :

ps4000RunStreaming( Handle, &UsedSamplingPeriod, PS4000_NS, uint32_t(0), uint32_t( GLOBAL_PicoSignal_SampleNumber ), int16_t( true ), uint32_t( 1 ), GLOBAL_PicoSignal_SampleNumber );

A few milliseconds after this call, program enters some kind of infinite loop.
I particular, the next call to ps4000GetStreamingLatestValues is never reached.

Wouldn't be possible there's a bug in 64bits streaming driver ?
I do insist the same code works like a charm under Win7 32bits.


Second
I've not been able to compile the sample ps4000con.c
I get linking errors :
^
C:\Users\user\AppData\Local\Temp\ccPT5d0S.o:ps4000con.c:(.text+0x2b1): undefined reference to `__imp_ps4000SetEts'
C:\Users\user\AppData\Local\Temp\ccPT5d0S.o:ps4000con.c:(.text+0x366): undefined reference to `__imp_ps4000SetChannel'
C:\Users\user\AppData\Local\Temp\ccPT5d0S.o:ps4000con.c:(.text+0x4bc): undefined reference to `__imp_ps4000GetTimebase'

Although I've been careful to copy ps4000.dll in the directory where I'm compiling the sample ps4000cn



Thanks for your help !

Hitesh
Site Admin
Site Admin
Posts: 2845
Joined: Tue May 31, 2011 3:43 pm
Location: St. Neots, Cambridgeshire

Re: Pico4424 streaming with Win10 64bits

Post by Hitesh » Tue Apr 03, 2018 3:40 pm

Hi John,

Happy belated Easter to you too.

I'll check our example here too. Please add the (64-bit) ps4000a.lib to your project and it just find the functions.

Regards,
Hitesh

Technical Support Engineer

Post Reply