/**************************************************************************** * SetTrigger * this function sets all the required trigger parameters, and calls the * triggering functions ****************************************************************************/ short SetTrigger(Imports.TriggerChannelProperties[] channelProperties, short nChannelProperties, Imports.TriggerConditions[] triggerConditions, short nTriggerConditions, Imports.ThresholdDirection[] directions, Pwq pwq, uint delay, short auxOutputEnabled, int autoTriggerMs) { short status; if ( (status = Imports.SetTriggerChannelProperties(_handle, channelProperties, nChannelProperties, auxOutputEnabled, autoTriggerMs)) != 0) { return status; } if ((status = Imports.SetTriggerChannelConditions(_handle, triggerConditions, nTriggerConditions)) != 0) { return status; } if (directions == null) directions = new Imports.ThresholdDirection[] { Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None}; if ((status = Imports.SetTriggerChannelDirections(_handle, directions[(int)Imports.Channel.ChannelA], directions[(int)Imports.Channel.ChannelB], directions[(int)Imports.Channel.ChannelC], directions[(int)Imports.Channel.ChannelD], directions[(int)Imports.Channel.External], directions[(int)Imports.Channel.Aux])) != 0) { return status; } if ((status = Imports.SetTriggerDelay(_handle, delay)) != 0) { return status; } if (pwq == null) pwq = new Pwq(null, 0, Imports.ThresholdDirection.None, 0, 0, Imports.PulseWidthType.None); status = Imports.SetPulseWidthQualifier(_handle, pwq.conditions, pwq.nConditions, pwq.direction, pwq.lower, pwq.upper, pwq.type); return status; }
/**************************************************************************** * SetTrigger * this function sets all the required trigger parameters, and calls the * triggering functions ****************************************************************************/ short SetTrigger(Imports.TriggerChannelProperties[] channelProperties, short nChannelProperties, Imports.TriggerConditions[] triggerConditions, short nTriggerConditions, Imports.ThresholdDirection[] directions, Pwq pwq, uint delay, short auxOutputEnabled, int autoTriggerMs) { short status; if ( (status = Imports.SetTriggerChannelProperties(_handle, channelProperties, nChannelProperties, auxOutputEnabled, autoTriggerMs)) != 0) { return(status); } if ((status = Imports.SetTriggerChannelConditions(_handle, triggerConditions, nTriggerConditions)) != 0) { return(status); } if (directions == null) { directions = new Imports.ThresholdDirection[] { Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None } } ; if ((status = Imports.SetTriggerChannelDirections(_handle, directions[(int)Imports.Channel.ChannelA], directions[(int)Imports.Channel.ChannelB], directions[(int)Imports.Channel.ChannelC], directions[(int)Imports.Channel.ChannelD], directions[(int)Imports.Channel.External], directions[(int)Imports.Channel.Aux])) != 0) { return(status); } if ((status = Imports.SetTriggerDelay(_handle, delay)) != 0) { return(status); } if (pwq == null) { pwq = new Pwq(null, 0, Imports.ThresholdDirection.None, 0, 0, Imports.PulseWidthType.None); } status = Imports.SetPulseWidthQualifier(_handle, pwq.conditions, pwq.nConditions, pwq.direction, pwq.lower, pwq.upper, pwq.type); return(status); } /**************************************************************************** * CollectBlockImmediate * this function demonstrates how to collect a single block of data * from the unit (start collecting immediately) ****************************************************************************/ void CollectBlockImmediate() { Console.WriteLine("Collect block immediate..."); Console.WriteLine("Press a key to start"); WaitForKey(); SetDefaults(); /* Trigger disabled */ SetTrigger(null, 0, null, 0, null, null, 0, 0, 0); BlockDataHandler("First 10 readings", 0); } /**************************************************************************** * CollectBlockRapid * this function demonstrates how to collect blocks of data * using the RapidCapture function ****************************************************************************/ void CollectBlockRapid() { ushort numRapidCaptures = 1; bool valid = false; Console.WriteLine("Collect rapid block..."); Console.WriteLine("Specify number of captures:"); do { try { numRapidCaptures = ushort.Parse(Console.ReadLine()); valid = true; } catch { valid = false; Console.WriteLine("\nEnter numeric values only"); } } while (Imports.SetNoOfRapidCaptures(_handle, numRapidCaptures) > 0 || !valid); int maxSamples; Imports.MemorySegments(_handle, numRapidCaptures, out maxSamples); Console.WriteLine("Collecting {0} rapid blocks. Press a key to start", numRapidCaptures); WaitForKey(); SetDefaults(); /* Trigger is optional, disable it for now */ SetTrigger(null, 0, null, 0, null, null, 0, 0, 0); RapidBlockDataHandler(numRapidCaptures); } /**************************************************************************** * CollectBlockTriggered * this function demonstrates how to collect a single block of data from the * unit, when a trigger event occurs. ****************************************************************************/ void CollectBlockTriggered() { short triggerVoltage = mv_to_adc(1000, (short)_channelSettings[(int)Imports.Channel.ChannelA].range); // ChannelInfo stores ADC counts Imports.TriggerChannelProperties[] sourceDetails = new Imports.TriggerChannelProperties[] { new Imports.TriggerChannelProperties(triggerVoltage, 256 * 10, triggerVoltage, 256 * 10, Imports.Channel.ChannelA, Imports.ThresholdMode.Level) }; Imports.TriggerConditions[] conditions = new Imports.TriggerConditions[] { new Imports.TriggerConditions(Imports.TriggerState.True, Imports.TriggerState.DontCare, Imports.TriggerState.DontCare, Imports.TriggerState.DontCare, Imports.TriggerState.DontCare, Imports.TriggerState.DontCare, Imports.TriggerState.DontCare) }; Imports.ThresholdDirection[] directions = new Imports.ThresholdDirection[] { Imports.ThresholdDirection.Rising, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None }; Console.WriteLine("Collect block triggered..."); Console.Write("Collects when value rises past {0}", (_scaleVoltages) ? adc_to_mv(sourceDetails[0].ThresholdMajor, (int)_channelSettings[(int)Imports.Channel.ChannelA].range) : sourceDetails[0].ThresholdMajor); Console.WriteLine("{0}", (_scaleVoltages) ? ("mV") : ("ADC Counts")); Console.WriteLine("Press a key to start..."); WaitForKey(); SetDefaults(); /* Trigger enabled * Rising edge * Threshold = 1000mV */ SetTrigger(sourceDetails, 1, conditions, 1, directions, null, 0, 0, 0); BlockDataHandler("Ten readings after trigger", 0); } /**************************************************************************** * Initialise unit' structure with Variant specific defaults ****************************************************************************/ void GetDeviceInfo() { int variant = 0; string[] description = { "Driver Version ", "USB Version ", "Hardware Version ", "Variant Info ", "Serial ", "Cal Date ", "Kernel Ver " }; System.Text.StringBuilder line = new System.Text.StringBuilder(80); if (_handle >= 0) { for (int i = 0; i < 7; i++) { short requiredSize; Imports.GetUnitInfo(_handle, line, 80, out requiredSize, i); if (i == 3) { line.Length = 4; variant = Convert.ToInt16(line.ToString()); } Console.WriteLine("{0}: {1}", description[i], line); } switch (variant) { case (int)Imports.Model.PS4223: _firstRange = Imports.Range.Range_50MV; _lastRange = Imports.Range.Range_100V; _channelCount = DUAL_SCOPE; break; case (int)Imports.Model.PS4224: _firstRange = Imports.Range.Range_50MV; _lastRange = Imports.Range.Range_20V; _channelCount = DUAL_SCOPE; break; case (int)Imports.Model.PS4423: _firstRange = Imports.Range.Range_50MV; _lastRange = Imports.Range.Range_100V; _channelCount = QUAD_SCOPE; break; case (int)Imports.Model.PS4424: _firstRange = Imports.Range.Range_50MV; _lastRange = Imports.Range.Range_20V; _channelCount = QUAD_SCOPE; break; case (int)Imports.Model.PS4226: _firstRange = Imports.Range.Range_50MV; _lastRange = Imports.Range.Range_20V; _channelCount = DUAL_SCOPE; break; case (int)Imports.Model.PS4227: _firstRange = Imports.Range.Range_50MV; _lastRange = Imports.Range.Range_20V; _channelCount = DUAL_SCOPE; break; case (int)Imports.Model.PS4262: _firstRange = Imports.Range.Range_10MV; _lastRange = Imports.Range.Range_20V; _channelCount = DUAL_SCOPE; break; } } } /**************************************************************************** * Select input voltage ranges for channels A and B ****************************************************************************/ void SetVoltages() { bool valid = false; /* See what ranges are available... */ for (int i = (int)_firstRange; i <= (int)_lastRange; i++) { Console.WriteLine("{0} . {1} mV", i, inputRanges[i]); } /* Ask the user to select a range */ Console.WriteLine("Specify voltage range ({0}..{1})", _firstRange, _lastRange); Console.WriteLine("99 - switches channel off"); for (int ch = 0; ch < _channelCount; ch++) { Console.WriteLine(""); uint range = 8; do { try { Console.WriteLine("Channel: {0}", (char)('A' + ch)); range = uint.Parse(Console.ReadLine()); valid = true; } catch { valid = false; Console.WriteLine("\nEnter numeric values only"); } } while ((range != 99 && (range < (uint)_firstRange || range > (uint)_lastRange) || !valid)); if (range != 99) { _channelSettings[ch].range = (Imports.Range)range; Console.WriteLine(" = {0} mV", inputRanges[range]); _channelSettings[ch].enabled = true; } else { Console.WriteLine("Channel Switched off"); _channelSettings[ch].enabled = false; } } SetDefaults(); // Set defaults now, so that if all but 1 channels get switched off, timebase updates to timebase 0 will work } /**************************************************************************** * * Select _timebase, set _oversample to on and time units as nano seconds * ****************************************************************************/ void SetTimebase() { int timeInterval; int maxSamples; bool valid = false; Console.WriteLine("Specify timebase"); do { try { _timebase = uint.Parse(Console.ReadLine()); valid = true; } catch { valid = false; Console.WriteLine("\nEnter numeric values only"); } } while (!valid); while (Imports.GetTimebase(_handle, _timebase, BUFFER_SIZE, out timeInterval, 1, out maxSamples, 0) != 0) { Console.WriteLine("Selected timebase {0} could not be used", _timebase); _timebase++; } Console.WriteLine("Timebase {0} - {1} ns", _timebase, timeInterval); _oversample = 1; } /**************************************************************************** * Stream Data Handler * - Used by the two stream data examples - untriggered and triggered * Inputs: * - preTrigger - the number of samples in the pre-trigger phase * (0 if no trigger has been set) ***************************************************************************/ void StreamDataHandler(uint preTrigger) { uint sampleCount = BUFFER_SIZE * 10; /* *10 is to make sure buffer large enough */ short[][] minBuffers = new short[_channelCount][]; short[][] maxBuffers = new short[_channelCount][]; PinnedArray <short>[] minPinned = new PinnedArray <short> [_channelCount]; PinnedArray <short>[] maxPinned = new PinnedArray <short> [_channelCount]; uint totalsamples = 0; uint triggeredAt = 0; short status; uint sampleInterval = 1; for (int i = 0; i < _channelCount; i++) // create data buffers { minBuffers[i] = new short[sampleCount]; maxBuffers[i] = new short[sampleCount]; minPinned[i] = new PinnedArray <short>(minBuffers[i]); maxPinned[i] = new PinnedArray <short>(maxBuffers[i]); status = Imports.SetDataBuffers(_handle, (Imports.Channel)i, minBuffers[i], maxBuffers[i], (int)sampleCount); } Console.WriteLine("Waiting for trigger...Press a key to abort"); _autoStop = false; status = Imports.RunStreaming(_handle, ref sampleInterval, Imports.ReportedTimeUnits.MicroSeconds, preTrigger, 1000000 - preTrigger, true, 1000, sampleCount); Console.WriteLine("Run Streaming : {0} ", status); Console.WriteLine("Streaming data...Press a key to abort"); TextWriter writer = new StreamWriter("stream.txt", false); writer.Write("For each of the {0} Channels, results shown are....", _channelCount); writer.WriteLine(); writer.WriteLine("Maximum Aggregated value ADC Count & mV, Minimum Aggregated value ADC Count & mV"); writer.WriteLine(); for (int i = 0; i < _channelCount; i++) { writer.Write("Ch Max ADC Max mV Min ADC Min mV "); } writer.WriteLine(); while (!_autoStop && !Console.KeyAvailable) { /* Poll until data is received. Until then, GetStreamingLatestValues wont call the callback */ Thread.Sleep(100); _ready = false; Imports.GetStreamingLatestValues(_handle, StreamingCallback, IntPtr.Zero); if (_ready && _sampleCount > 0) /* can be ready and have no data, if autoStop has fired */ { if (_trig > 0) { triggeredAt = totalsamples + _trigAt; } totalsamples += (uint)_sampleCount; Console.Write("\nCollected {0,4} samples, index = {1,5} Total = {2,5}", _sampleCount, _startIndex, totalsamples); if (_trig > 0) { Console.Write("\tTrig at Index {0}", triggeredAt); } for (uint i = _startIndex; i < (_startIndex + _sampleCount); i++) { for (int ch = 0; ch < _channelCount; ch++) { if (_channelSettings[ch].enabled) { writer.Write("Ch{0} {1,7} {2,7} {3,7} {4,7} ", (char)('A' + ch), minPinned[ch].Target[i], adc_to_mv(minPinned[ch].Target[i], (int)_channelSettings[(int)(Imports.Channel.ChannelA + ch)].range), maxPinned[ch].Target[i], adc_to_mv(maxPinned[ch].Target[i], (int)_channelSettings[(int)(Imports.Channel.ChannelA + ch)].range)); } } writer.WriteLine(); } } } if (Console.KeyAvailable) { Console.ReadKey(true); // clear the key } Imports.Stop(_handle); writer.Close(); if (!_autoStop) { Console.WriteLine("\ndata collection aborted"); } foreach (PinnedArray <short> p in minPinned) { if (p != null) { p.Dispose(); } } foreach (PinnedArray <short> p in maxPinned) { if (p != null) { p.Dispose(); } } } /**************************************************************************** * CollectStreamingImmediate * this function demonstrates how to collect a stream of data * from the unit (start collecting immediately) ***************************************************************************/ void CollectStreamingImmediate() { SetDefaults(); Console.WriteLine("Collect streaming..."); Console.WriteLine("Data is written to disk file (stream.txt)"); Console.WriteLine("Press a key to start"); WaitForKey(); /* Trigger disabled */ SetTrigger(null, 0, null, 0, null, null, 0, 0, 0); StreamDataHandler(0); } /**************************************************************************** * CollectStreamingTriggered * this function demonstrates how to collect a stream of data * from the unit (start collecting on trigger) ***************************************************************************/ void CollectStreamingTriggered() { short triggerVoltage = mv_to_adc(1000, (short)_channelSettings[(int)Imports.Channel.ChannelA].range); // ChannelInfo stores ADC counts Imports.TriggerChannelProperties[] sourceDetails = new Imports.TriggerChannelProperties[] { new Imports.TriggerChannelProperties(triggerVoltage, 256 * 10, triggerVoltage, 256 * 10, Imports.Channel.ChannelA, Imports.ThresholdMode.Level) }; Imports.TriggerConditions[] conditions = new Imports.TriggerConditions[] { new Imports.TriggerConditions(Imports.TriggerState.True, Imports.TriggerState.DontCare, Imports.TriggerState.DontCare, Imports.TriggerState.DontCare, Imports.TriggerState.DontCare, Imports.TriggerState.DontCare, Imports.TriggerState.DontCare) }; Imports.ThresholdDirection[] directions = new Imports.ThresholdDirection[] { Imports.ThresholdDirection.Rising, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None, Imports.ThresholdDirection.None }; Console.WriteLine("Collect streaming triggered..."); Console.WriteLine("Data is written to disk file (stream.txt)"); Console.WriteLine("Press a key to start"); WaitForKey(); SetDefaults(); /* Trigger enabled * Rising edge * Threshold = 1000mV */ SetTrigger(sourceDetails, 1, conditions, 1, directions, null, 0, 0, 0); StreamDataHandler(100000); } /**************************************************************************** * DisplaySettings * Displays information about the user configurable settings in this example ***************************************************************************/ void DisplaySettings() { int ch; int voltage; Console.WriteLine("\n\nReadings will be scaled in {0}", (_scaleVoltages) ? ("mV") : ("ADC counts")); for (ch = 0; ch < _channelCount; ch++) { voltage = inputRanges[(int)_channelSettings[ch].range]; Console.Write("Channel {0} Voltage Range = ", (char)('A' + ch)); if (voltage < 1000) { Console.WriteLine("{0}mV", voltage); } else { Console.WriteLine("{0}V", voltage / 1000); } } Console.WriteLine(); }