Complex pulse width trigger setup not working

Post general discussions on using our drivers to write your own software here
Post Reply
dkirschb
Newbie
Posts: 0
Joined: Tue Feb 15, 2022 6:50 am

Complex pulse width trigger setup not working

Post by dkirschb »

Hi,
I am trying to set up a more complex pulse width trigger using a picoscope 2405A and the latest picosdk API.

The setup I am trying to achive shall be as follows:
I want measure the pulse width of multiple (up to 4) analogue input signals at the same time
and trigger if one (or multiple) of these signals fall out of a pulse width window which I consider as "ok".
Capture shall be performed in block mode.

The pulse width to measure will be in the order of microseconds. All the input signals are in phase,
so that the start condition for the pulse width counter is the same for all channels.

With the help of the forum I already got the setup running using only a single channel of the scope. I paste
the used code for the trigger configuration hereafter. I tend to use python for this task although I also tried it using the C-API directly:

Code: Select all

sourceDetails = PS2000A_TRIGGER_CHANNEL_PROPERTIES( 
		trigger_Voltage_adc_incs, # thresholdUpper
		256*10,		# thresholdUpperHysteresis
		trigger_Voltage_adc_incs,  # thresholdLower
		256*10, 	# thresholdLowerHysteresis
		pico.PS2000A_CHANNEL['PS2000A_CHANNEL_A'], # channel
		pico.PS2000A_THRESHOLD_MODE['PS2000A_LEVEL'])  # mode


res1 = pico.ps2000aSetTriggerChannelProperties( self.hnd,
                                                ctypes.byref(sourceDetails),
                                                1,
                                                0,
                                                0)

conditions = PS2000A_TRIGGER_CONDITIONS(    
					pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_TRUE'],  # Channel A
                                        pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'], # Channel B
                                        pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'],  # Channel C
                                        pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'],  # Channel D
                                        pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'],  # external
                                        pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'],  # aux
                                        pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_TRUE'],            # PWQ
                                        pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'])  # digital


res2 = pico.ps2000aSetTriggerChannelConditions( self.hnd, ctypes.byref(conditions), 1)

res3 = pico.ps2000aSetTriggerChannelDirections(self.hnd,
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_FALLING_LOWER'],  # Channel A
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_NONE'],  # Channel B
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_NONE'],  # Channel C
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_NONE'], # Channel D
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_NONE'], # ext
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_NONE'])  # aux

pwq_conds = PS2000A_PWQ_CONDITIONS( 
					pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_TRUE'], # Channel A
                                    	pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'], # Channel B
                                    	pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'], # Channel C
                                    	pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'], # Channel D
                                    	pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'], # ext
                                    	pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'], # aux
                                    	pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'] ) # digital

ret4 = pico.ps2000aSetPulseWidthQualifier( self.hnd,  # handle
						ctypes.byref(pwq_conds),  # conditions
                                            	1,  # nConditions
                                            	pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_FALLING'],  # dir
                                            	pulseduration_min_samples,  # lower
                                            	pulseduration_max_samples,  # upper
                                            	4  )  # type (PS2000A_PW_TYPE_OUT_OF_RANGE)
After having this working I tried to extend the setup to multiple channels. For this I basically extended the PS2000A_TRIGGER_CHANNEL_PROPERTIES, PS2000A_TRIGGER_CONDITIONS and PS2000A_PWQ_CONDITIONS structures to have one entry per active channel.
But when I then try to run this with more than one channel (currently 2) enabled, the trigger always immediately fires after calling ps2000ARunBlock() although the input signals are all present and
within the pulse width window I consider as "ok".

Again I'll paste the used code for the trigger configuration below:

Code: Select all

sourceDetails = (PS2000A_TRIGGER_CHANNEL_PROPERTIES * 2)()

sourceDetails[0].thresholdUpper = trigVoltage
sourceDetails[0].thresholdUpperHysteresis = 256*0
sourceDetails[0].thresholdLower = trigVoltage
sourceDetails[0].thresholdLowerHysteresis = 256*0
sourceDetails[0].channel = i
sourceDetails[0].thresholdMode = pico.PS2000A_THRESHOLD_MODE['PS2000A_LEVEL']

sourceDetails[1].thresholdUpper = trigVoltage
sourceDetails[1].thresholdUpperHysteresis = 256*0
sourceDetails[1].thresholdLower = trigVoltage
sourceDetails[1].thresholdLowerHysteresis = 256*0
sourceDetails[1].channel = i
sourceDetails[1].thresholdMode = pico.PS2000A_THRESHOLD_MODE['PS2000A_LEVEL']

res1 = pico.ps2000aSetTriggerChannelProperties(self.hnd, # handle
							ctypes.byref(sourceDetails),  # channelProperties
							2,  # nChannelProperties
							0,  # auxOutputEnable
							0)    # autoTriggerMilliseconds


trig_conds = (PS2000A_TRIGGER_CONDITIONS * 2)()

trig_conds[0].channelA              = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_TRUE']
trig_conds[0].channelB              = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
trig_conds[0].channelC              = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
trig_conds[0].channelD              = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
trig_conds[0].external              = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
trig_conds[0].aux                   = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
trig_conds[0].pulseWidthQualifier   = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_TRUE']
trig_conds[0].digital               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']

trig_conds[1].channelA              = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
trig_conds[1].channelB              = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_TRUE']
trig_conds[1].channelC              = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
trig_conds[1].channelD              = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
trig_conds[1].external              = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
trig_conds[1].aux                   = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
trig_conds[1].pulseWidthQualifier   = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_TRUE']
trig_conds[1].digital               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']

res2 = pico.ps2000aSetTriggerChannelConditions( self.hnd, ctypes.byref(trig_conds), 2)
												
res3 = pico.ps2000aSetTriggerChannelDirections(
					self.hnd,
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_FALLING_LOWER'],  # Channel A
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_FALLING_LOWER'],  # Channel B
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_NONE'],           # Channel C
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_NONE'],           # Channel D
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_NONE'],           # ext
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_NONE'])           # aux
					
pwq_conds = (PS2000A_PWQ_CONDITIONS * 2)()

pwq_conds[0].channelA               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_TRUE'] 
pwq_conds[0].channelB               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'] 
pwq_conds[0].channelC               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
pwq_conds[0].channelD               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
pwq_conds[0].external               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
pwq_conds[0].aux                    = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
pwq_conds[0].digital                = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']

pwq_conds[1].channelA               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE'] 
pwq_conds[1].channelB               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_TRUE'] 
pwq_conds[1].channelC               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
pwq_conds[1].channelD               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
pwq_conds[1].external               = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
pwq_conds[1].aux                    = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']
pwq_conds[1].digital                = pico.PS2000A_TRIGGER_STATE['PS2000A_CONDITION_DONT_CARE']

ret4 = pico.ps2000aSetPulseWidthQualifier( self.hnd,  # handle
					ctypes.byref(pwq_conds),   # conditions
					2,  # nConditions
					pico.PS2000A_THRESHOLD_DIRECTION['PS2000A_FALLING'], # dir
					,  # lower
					,  # upper
					4 () ) # type
Is my desired setup even possible with the scope and the sdk? Or am I simply getting the behaviour of the driver/API wrong.

Any comments welcome.
Thanks in advance.

Post Reply