What scope allows hardware triggers on both channels?

Post your .Net discussions here
Post Reply
davidpruitt
Advanced User
Advanced User
Posts: 0
Joined: Tue May 17, 2016 6:45 pm

What scope allows hardware triggers on both channels?

Post by davidpruitt »

Quick question: I know the Pico2204A only allows doing a hardware trigger (using the RunBlock function) on one channel at a time.

If I want to place hardware triggers on both channels simultaneously (rather than writing my own software triggers and streaming data from the scope using the run_streaming_ns function), what scope would I need to purchase?

Thanks!

Hitesh

Re: What scope allows hardware triggers on both channels?

Post by Hitesh »

Hi David,

The API for the PicoScope 2204A does support the ability to trigger when the conditions are met on channel A AND channel B as well as channel A OR channel B.

Which specific trigger condition are you looking for?

Regards,

davidpruitt
Advanced User
Advanced User
Posts: 0
Joined: Tue May 17, 2016 6:45 pm

Re: What scope allows hardware triggers on both channels?

Post by davidpruitt »

Pretty simple reallly, I just want to be able to trigger each channel once the voltage rises above a certain level, say 1.0 V. Then, when the trigger occurs, I just want to collect the next 500 ms or so of data coming from that channel, whether it be channel A or channel B.

Based on our discussion at the following link, it didn't sound like this was possible: topic24621.html

So if channel A triggers (rises above a certain voltage level), collect the next 500 ms of data.
Also, if channel B triggers, collect the next 500 ms of data.

Also, it's possible that channel A and channel B could trigger very close in time (say, within a few ms), if that changes things at all? Although it's not necessarily going to be like that all the time.

Up until now, I've been using the run_streaming_ns function to stream both channels very quickly, and then I wrote a software trigger to simply record data off of each channel when the respective channel triggers (that's what I have been doing in this dicussion: topic24661.html). I recently ran into a small road-bump, however, because doing it that way puts a larger load on the computer's processor. On the machines that I am running my software on, it's consumes about 25% of the CPU per scope that I have connected to the computer. So if I have 4 scopes connected, I am consuming 100% of the CPU and my software starts to fall behind.

When using the RunBlock method of gathering data, however, it shifts the load over to the oscilloscope, so the CPU is much less taxed, and I could connect 10 scopes (or more) to a single computer if I want. So I just wanted to see how feasible it is to trigger off both channels using RunBlock.

davidpruitt
Advanced User
Advanced User
Posts: 0
Joined: Tue May 17, 2016 6:45 pm

Re: What scope allows hardware triggers on both channels?

Post by davidpruitt »

So just to clarify further, let me write some pseudocode showing what I want to do:

Code: Select all

while(true)
{
    if (ChannelA is triggered)
        Collect data from ChannelA
    if (ChannelB is triggered)
        Collect data from ChannelB
}

Hitesh

Re: What scope allows hardware triggers on both channels?

Post by Hitesh »

Hi David,

Unfortunately independent triggers is not possible with our current range of real-time oscilloscopes. A single trigger event can be setup for a data collection run and this is configured for a single channel or a combination of channels.

What is the sampling rate that you are using? The PicoScope 2204A is a low memory device and uses an older driver model which is ok for rates of 1 MS/s or less.

Depending on your application requirements, it might be possible that you could use a PicoScope model with more memory that uses a different driver model so you can still process the data in software without potentially losing data.

Regards,

davidpruitt
Advanced User
Advanced User
Posts: 0
Joined: Tue May 17, 2016 6:45 pm

Re: What scope allows hardware triggers on both channels?

Post by davidpruitt »

In streaming mode my app (depending on some selections made by the user) either streams at 5 us/sample or 10 us/sample (so if my math is correct that is either 200 kS/second or 100 kS/second). We can sample at a lower resolution, however. The signal we are sampling is a 500 ms signal bi-phasic pulse train at a frequency of 33 Hz, and each pulse has a 100 us pulse-width. Peak-to-peak voltage of the signal is variable, but typically 5V to 10V.

For most of our use-cases within our research lab, it would be sufficient to only capture the first pulse within the 500 ms pulse train that occurs. That is only about 100 samples large (with some empty space both before and after the pulse itself) and doesn't require a lot of memory. I believe if we want to capture the entire 500 ms pulse train at 10 us resolution, it would require us to use streaming mode because the buffer size simply isn't that large in block mode.

So based off of the Pico2204A specs at the following link, it has 8 kS of buffer memory in block mode: https://www.picotech.com/oscilloscope/2 ... ifications

If we want to capture the entire 500 ms pulse train in block mode, the best resolution we could get seems to be 62.5 us/sample, based on my math below:

8000 samples (the block memory buffer size) / 500 ms (length of our pulse train) = 16 samples/ms
1 sample / 16 ms = 0.0625 ms/sample
1 sample = 62.5 microseconds

That's definitely not as nice as 10 us/sample, but we'd hopefully still be able to get the general shape of the signal with that and measure peak-to-peak voltage of the pulses. Of course there's also the option of quickly setting up another block one right after the other to capture the full pulse train, which is certainly doable.

But anyway, honestly none of the above is really my concern.

I'm surprised that you cannot independently trigger separate channels on any of the oscilloscopes in your product line. Not even the highest tier PicoScope 9341 that costs $23k? (Not that I would need or buy that one) It seems like a feature that would make sense to implement, one that would be commonly used, and definitely one that we want. Can I put in a feature request?

I can do this using software triggers that I have written, and my code works well, but due to the amount of data coming in it bogs down the processor if we have several scopes hooked up to a computer (more than 2), so it'd be nice to offload that task to the hardware.

davidpruitt
Advanced User
Advanced User
Posts: 0
Joined: Tue May 17, 2016 6:45 pm

Re: What scope allows hardware triggers on both channels?

Post by davidpruitt »

But you say that I could trigger off Channel A or Channel B? So would that look something like this:

Enable Channel A
Enable Channel B
Set trigger to trigger on A OR B (using advanced trigger options???)
Run Block
Wait until scope is ready
Read data using ps2000_get_times_and_values (it would include both A and B buffers)
Reset the block to start over again

I assume if I did it this way, only 4 ks of internal buffer memory would be available for each channel?

Hitesh

Re: What scope allows hardware triggers on both channels?

Post by Hitesh »

Hi David,

You would have to use the advanced trigger options, and the data returned would be for both channels A and B.

The buffer memory would be divided between the two channels.

Regards,

davidpruitt
Advanced User
Advanced User
Posts: 0
Joined: Tue May 17, 2016 6:45 pm

Re: What scope allows hardware triggers on both channels?

Post by davidpruitt »

Hitesh,

According to the programmer's manual (https://www.picotech.com/download/manua ... .en-10.pdf), it doesn't seem like what you described is possible, even with "advanced trigger conditions". Quote from the manual (page 39 of the PDF, but numbered page 35 of the document):

Code: Select all

The channels that are set to CONDITION_TRUE or CONDITION_FALSE must all meet
their conditions simultaneously to produce a trigger. Channels set to CONDITION_DONT_CARE are ignored. 

The oscilloscope can use only a single input channel (either channel A or channel B) for the trigger source. Therefore you may define CONDITION_TRUE or CONDITION_FALSE for only one of these channels at a time
Can you elaborate on how to use the advanced trigger conditions to achieve what you describe?

Hitesh

Re: What scope allows hardware triggers on both channels?

Post by Hitesh »

Hi David,

The Programmer's Guide has recently been updated.

Please refer to section 5.20.1 (PS2000_TRIGGER_CONDITIONS structure):
The PicoScope 2204, 2204A, 2205 and 2205A models can all trigger from both channel
A and channel B, and therefore all support logic triggering.
If you have implemented some code to try this, please post it here and I can take a look.

Regards,

davidpruitt
Advanced User
Advanced User
Posts: 0
Joined: Tue May 17, 2016 6:45 pm

Re: What scope allows hardware triggers on both channels?

Post by davidpruitt »

Hitesh,

Thanks for the link to the updated programmer's guide. I am still somewhat confused, however. Although it says that the Pico 2204A supports logic triggering, it also says:

"The channels that are set to CONDITION_TRUE or CONDITION_FALSE must all meet their conditions simultaneously to produce a trigger."

This would lead one to believe that if I set both Channel A and Channel B to be CONDITION_TRUE using the ps2000SetAdvTriggerChannelConditions function, they would both need to be true for the trigger to occur (which would essentially be an AND operation). How does one do an OR operation? In the PicoScope 6 application it seems to let me choose from AND, OR, XOR, and several other boolean operations, but I don't see any documentation on how to do this in the programmer's guide.

My initial thought was that maybe the ps2000SetAdvTriggerChannelConditions takes an array of trigger conditions since it takes a pointer to a PS2000_TRIGGER_CONDITIONS followed by an integer called nConditions (that would seemingly denote an array followed by the length of the array). This would make sense to me, because then maybe the function just does an OR operation on each condition you give as a parameter. However, the documentation on the nConditions parameter says the following:

"nConditions: should be set to 1 if conditions is non-null, otherwise 0"

Therefore, based on that documentation, I would assume that ps2000SetAdvTriggerChannelConditions does not take an array of PS2000_TRIGGER_CONDITIONS, and nContitions sole purpose is to denote whether the "conditions" parameter is null or not.

So, if you have any more information on how to do anything other than an AND operation, please let me know. Thanks!

Hitesh

Re: What scope allows hardware triggers on both channels?

Post by Hitesh »

Hi David,

It looks as though there are some errors in relation to advanced triggers in the Programmer's Guide. Support for logic trigger functionality for the devices using the ps2000 driver (where supported) was added in one of the PicoScope 6.10 versions.

I will report this to our Technical Publications team.

To setup an AND condition for channels A and B, you would specify one PS2000_TRIGGER_CONDITIONS and set both channelA and channelB fields to PS2000_CONDITION_TRUE.

If you wish to setup an OR condition, you need to specify two PS2000_TRIGGER_CONDITIONS, setting channelA to PS2000_CONDITION_TRUE in one structure, and channelB to PS2000_CONDITION_TRUE in the other.

I've copied below a snippet code that I've tested with our C console application:

Code: Select all

void set_trigger_advanced(void)
{
	int16_t ok = 0;
	int16_t auto_trigger_ms = 0;

	// Setup trigger for channel A OR channel B

	// To trigger on more than one channel set this parameter to 2 or more
	// Each condition can only have on parameter set to PS2000_CONDITION_TRUE or PS2000_CONDITION_FALSE
	// If more than on condition is set then it will trigger off condition one, or condition two etc.
	unitOpened.trigger.advanced.nProperties = 2;
	
	// Trigger Conditions

	// Allocate memory for the trigger conditions structure array. The conditions from the structure will be 'OR'ed' together
	unitOpened.trigger.advanced.conditions = (PS2000_TRIGGER_CONDITIONS*) malloc (sizeof (PS2000_TRIGGER_CONDITIONS) * unitOpened.trigger.advanced.nProperties);
	
	// Set up a PS2000_TRIGGER_CONDITIONS structure to specify channel A
	unitOpened.trigger.advanced.conditions[0].channelA = PS2000_CONDITION_TRUE;
	unitOpened.trigger.advanced.conditions[0].channelB = PS2000_CONDITION_DONT_CARE;
	unitOpened.trigger.advanced.conditions[0].channelC = PS2000_CONDITION_DONT_CARE;
	unitOpened.trigger.advanced.conditions[0].channelD = PS2000_CONDITION_DONT_CARE;
	unitOpened.trigger.advanced.conditions[0].external = PS2000_CONDITION_DONT_CARE;
	unitOpened.trigger.advanced.conditions[0].pulseWidthQualifier = PS2000_CONDITION_DONT_CARE;

	// Set up a PS2000_TRIGGER_CONDITIONS structure to specify channel B
	unitOpened.trigger.advanced.conditions[1].channelA = PS2000_CONDITION_DONT_CARE;
	unitOpened.trigger.advanced.conditions[1].channelB = PS2000_CONDITION_TRUE;
	unitOpened.trigger.advanced.conditions[1].channelC = PS2000_CONDITION_DONT_CARE;
	unitOpened.trigger.advanced.conditions[1].channelD = PS2000_CONDITION_DONT_CARE;
	unitOpened.trigger.advanced.conditions[1].external = PS2000_CONDITION_DONT_CARE;
	unitOpened.trigger.advanced.conditions[1].pulseWidthQualifier = PS2000_CONDITION_DONT_CARE;

	ok = ps2000SetAdvTriggerChannelConditions(unitOpened.handle, unitOpened.trigger.advanced.conditions, unitOpened.trigger.advanced.nProperties);


	// Trigger Directions

	// Set channels A and B to rising
	// The remainder will be ignored as only a condition is set for channels A and B
	unitOpened.trigger.advanced.directions.channelA = PS2000_ADV_RISING;
	unitOpened.trigger.advanced.directions.channelB = PS2000_ADV_RISING;
	unitOpened.trigger.advanced.directions.channelC = PS2000_ADV_RISING;
	unitOpened.trigger.advanced.directions.channelD = PS2000_ADV_RISING;
	unitOpened.trigger.advanced.directions.ext = PS2000_ADV_RISING;

	ok = ps2000SetAdvTriggerChannelDirections(unitOpened.handle,
		unitOpened.trigger.advanced.directions.channelA,
		unitOpened.trigger.advanced.directions.channelB,
		unitOpened.trigger.advanced.directions.channelC,
		unitOpened.trigger.advanced.directions.channelD,
		unitOpened.trigger.advanced.directions.ext);


	unitOpened.trigger.advanced.channelProperties = (PS2000_TRIGGER_CHANNEL_PROPERTIES*) malloc (sizeof (PS2000_TRIGGER_CHANNEL_PROPERTIES) * unitOpened.trigger.advanced.nProperties);
	

	// Trigger Properties

	// There is one property for each condition
	// Set channel A
	// Trigger level converted from volts to ADC counts
	// hysteresis 256 ADC counts  

	unitOpened.trigger.advanced.channelProperties[0].channel = (int16_t) PS2000_CHANNEL_A;
	unitOpened.trigger.advanced.channelProperties[0].thresholdMajor = mv_to_adc(1000, unitOpened.channelSettings[PS2000_CHANNEL_A].range);
        // not used in level triggering, should be set when in window mode
	unitOpened.trigger.advanced.channelProperties[0].thresholdMinor = 0;			
	unitOpened.trigger.advanced.channelProperties[0].hysteresis = (int16_t) 256;	
        // used in level triggering, not used when in window mode
	unitOpened.trigger.advanced.channelProperties[0].thresholdMode = PS2000_LEVEL;

	unitOpened.trigger.advanced.channelProperties[1].channel = (int16_t) PS2000_CHANNEL_B;
	unitOpened.trigger.advanced.channelProperties[1].thresholdMajor = mv_to_adc(500, unitOpened.channelSettings[PS2000_CHANNEL_A].range);
	unitOpened.trigger.advanced.channelProperties[1].thresholdMinor = 0;			
        // not used in level triggering, should be set when in window mode
	unitOpened.trigger.advanced.channelProperties[1].hysteresis = (int16_t) 256;	
        // used in level triggering, not used when in window mode
	unitOpened.trigger.advanced.channelProperties[1].thresholdMode = PS2000_LEVEL;
	
	ok = ps2000SetAdvTriggerChannelProperties (unitOpened.handle,
												unitOpened.trigger.advanced.channelProperties,
												unitOpened.trigger.advanced.nProperties,
												auto_trigger_ms);

        // Trigger delay
	ok = ps2000SetAdvTriggerDelay (unitOpened.handle, 0, -50); 
}
Hope this helps,

Post Reply