/**************************************************************************** * SetTrigger * this function sets all the required trigger parameters, and calls the * triggering functions ****************************************************************************/ short SetTrigger(Scope.TriggerChannelProperties[] channelProperties, short nChannelProperties, Scope.TriggerConditions[] triggerConditions, short nTriggerConditions, Scope.ThresholdDirection[] directions, Pwq pwq, uint delay, short auxOutputEnabled, int autoTriggerMs) { short status; if ( (status = Scope.SetTriggerChannelProperties(_handle, channelProperties, nChannelProperties, auxOutputEnabled, autoTriggerMs)) != 0) { return(status); } if ((status = Scope.SetTriggerChannelConditions(_handle, triggerConditions, nTriggerConditions)) != 0) { return(status); } if (directions == null) { directions = new Scope.ThresholdDirection[] { Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None } } ; if ((status = Scope.SetTriggerChannelDirections(_handle, directions[(int)Scope.Channel.ChannelA], directions[(int)Scope.Channel.ChannelB], directions[(int)Scope.Channel.ChannelC], directions[(int)Scope.Channel.ChannelD], directions[(int)Scope.Channel.External], directions[(int)Scope.Channel.Aux])) != 0) { return(status); } if ((status = Scope.SetTriggerDelay(_handle, delay)) != 0) { return(status); } if (pwq == null) { pwq = new Pwq(null, 0, Scope.ThresholdDirection.None, 0, 0, Scope.PulseWidthType.None); } status = Scope.SetPulseWidthQualifier(_handle, pwq.conditions, pwq.nConditions, pwq.direction, pwq.lower, pwq.upper, pwq.type); return(status); } //******************************************************************************** //Function to acquire data to array * //******************************************************************************** int BlockDataAcquisition(uint sampleCount, uint timebase, short oversampling, int pretrigger) { //Time in ms the measurement will consume int timeIndisposed; int pretrig; int posttrig; //Create structured Array for measurement results of all 4channels //MaxPinned will contain the measurement values or the maximum values in aggregated mode //MinPinned will contain minimum values´in aggregated mode otherwise 0 for (int i = 0; i < 4; i++) { short[] minBuffers = new short[sampleCount]; short[] maxBuffers = new short[sampleCount]; minPinned[i] = new PinnedArray <short>(minBuffers); maxPinned[i] = new PinnedArray <short>(maxBuffers); int status = Scope.SetDataBuffers(_handle, (Scope.Channel)i, maxBuffers, minBuffers, (int)sampleCount); } //Start collecting Data and create ready=true callback to acknowledge when acquisition is finished _ready = false; _callbackDelegate = BlockCallback; pretrig = (int)(sampleCount * pretrigger / 100); posttrig = (int)(sampleCount * (100 - pretrigger) / 100); //Start acquisition Scope.RunBlock(_handle, pretrig, posttrig, timebase, oversampling, out timeIndisposed, 0, _callbackDelegate, IntPtr.Zero); //If a linearitytest is performed wait buffer to fill and start axis if (linearitytest == true) { //Wait for pretrigger buffer to fill with data Thread.Sleep(800); //Start axis movement serialPortTester.WriteLine("$AL3"); } //Wait for measurement finished while (!_ready) { Thread.Sleep(10); } //Stop scope after data has been acquired Scope.Stop(_handle); //If acquisiton was successfully finished get values if (_ready) { short overflow; Scope.GetValues(_handle, 0, ref sampleCount, 1, Scope.DownSamplingMode.None, 0, out overflow); } else { } return(timeIndisposed); } int StartDataAcquisition(uint sampleCount, uint timebase, short oversampling, int pretrigger) { //Time in ms the measurement will consume int timeIndisposed; int pretrig; int posttrig; //Create structured Array for measurement results of all 4channels //MaxPinned will contain the measurement values or the maximum values in aggregated mode //MinPinned will contain minimum values´in aggregated mode otherwise 0 for (int i = 0; i < 4; i++) { short[] minBuffers = new short[sampleCount]; short[] maxBuffers = new short[sampleCount]; minPinned[i] = new PinnedArray <short>(minBuffers); maxPinned[i] = new PinnedArray <short>(maxBuffers); int status = Scope.SetDataBuffers(_handle, (Scope.Channel)i, maxBuffers, minBuffers, (int)sampleCount); } //Start collecting Data and create ready=true callback to acknowledge when acquisition is finished _ready = false; _callbackDelegate = BlockCallback; pretrig = (int)(sampleCount * pretrigger / 100); posttrig = (int)(sampleCount * (100 - pretrigger) / 100); //Start acquisition Scope.RunBlock(_handle, pretrig, posttrig, timebase, oversampling, out timeIndisposed, 0, _callbackDelegate, IntPtr.Zero); return(timeIndisposed); } int FinishDataAcquisition(uint sampleCount, uint timebase, short oversampling, int pretrigger) { //Wait for measurement finished while (!_ready) { Thread.Sleep(10); } //Scope.ReportedTimeUnits reported_time_units_A, reported_time_units_B; //long time_A, time_B; //int time_ah, time_bh, time_al, time_bl; //Stop scope after data has been acquired Scope.Stop(_handle); //If acquisiton was successfully finished get values if (_ready) { short overflow; Scope.GetValues(_handle, 0, ref sampleCount, 1, Scope.DownSamplingMode.None, 0, out overflow); } else { } return(0); } int EvaluateDataAcquisition(uint sampleCount, uint numAvg, out double avgA, out double avgB, out double avgC, out double avgD) { long sum_a = 0, sum_b = 0, sum_c = 0, sum_d = 0; for (uint i = sampleCount / 2; i != sampleCount / 2 + numAvg; i++) { sum_a += maxPinned[0].Target[i]; sum_b += maxPinned[1].Target[i]; sum_c += maxPinned[2].Target[i]; sum_d += maxPinned[3].Target[i]; } avgA = sum_a / numAvg; avgB = sum_b / numAvg; avgC = sum_c / numAvg; avgD = sum_d / numAvg; return(0); } }
/**************************************************************************** * SetTrigger * this function sets all the required trigger parameters, and calls the * triggering functions ****************************************************************************/ short SetTrigger(Scope.TriggerChannelProperties[] channelProperties, short nChannelProperties, Scope.TriggerConditions[] triggerConditions, short nTriggerConditions, Scope.ThresholdDirection[] directions, Pwq pwq, uint delay, short auxOutputEnabled, int autoTriggerMs) { short status; if ( (status = Scope.SetTriggerChannelProperties(_handle, channelProperties, nChannelProperties, auxOutputEnabled, autoTriggerMs)) != 0) { return(status); } if ((status = Scope.SetTriggerChannelConditions(_handle, triggerConditions, nTriggerConditions)) != 0) { return(status); } if (directions == null) { directions = new Scope.ThresholdDirection[] { Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None } } ; if ((status = Scope.SetTriggerChannelDirections(_handle, directions[(int)Scope.Channel.ChannelA], directions[(int)Scope.Channel.ChannelB], directions[(int)Scope.Channel.ChannelC], directions[(int)Scope.Channel.ChannelD], directions[(int)Scope.Channel.External], directions[(int)Scope.Channel.Aux])) != 0) { return(status); } if ((status = Scope.SetTriggerDelay(_handle, delay)) != 0) { return(status); } if (pwq == null) { pwq = new Pwq(null, 0, Scope.ThresholdDirection.None, 0, 0, Scope.PulseWidthType.None); } status = Scope.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 (Scope.SetNoOfRapidCaptures(_handle, numRapidCaptures) > 0 || !valid); int maxSamples; Scope.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)Scope.Channel.ChannelA].range); // ChannelInfo stores ADC counts Scope.TriggerChannelProperties[] sourceDetails = new Scope.TriggerChannelProperties[] { new Scope.TriggerChannelProperties(triggerVoltage, 256 * 10, triggerVoltage, 256 * 10, Scope.Channel.ChannelA, Scope.ThresholdMode.Level) }; Scope.TriggerConditions[] conditions = new Scope.TriggerConditions[] { new Scope.TriggerConditions(Scope.TriggerState.True, Scope.TriggerState.DontCare, Scope.TriggerState.DontCare, Scope.TriggerState.DontCare, Scope.TriggerState.DontCare, Scope.TriggerState.DontCare, Scope.TriggerState.DontCare) }; Scope.ThresholdDirection[] directions = new Scope.ThresholdDirection[] { Scope.ThresholdDirection.Rising, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.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)Scope.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; Scope.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)Scope.Model.PS4223: _firstRange = Scope.Range.Range_50MV; _lastRange = Scope.Range.Range_100V; _channelCount = DUAL_SCOPE; break; case (int)Scope.Model.PS4224: _firstRange = Scope.Range.Range_50MV; _lastRange = Scope.Range.Range_20V; _channelCount = DUAL_SCOPE; break; case (int)Scope.Model.PS4423: _firstRange = Scope.Range.Range_50MV; _lastRange = Scope.Range.Range_100V; _channelCount = QUAD_SCOPE; break; case (int)Scope.Model.PS4424: _firstRange = Scope.Range.Range_50MV; _lastRange = Scope.Range.Range_20V; _channelCount = QUAD_SCOPE; break; case (int)Scope.Model.PS4226: _firstRange = Scope.Range.Range_50MV; _lastRange = Scope.Range.Range_20V; _channelCount = DUAL_SCOPE; break; case (int)Scope.Model.PS4227: _firstRange = Scope.Range.Range_50MV; _lastRange = Scope.Range.Range_20V; _channelCount = DUAL_SCOPE; break; case (int)Scope.Model.PS4262: _firstRange = Scope.Range.Range_10MV; _lastRange = Scope.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 = (Scope.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 (Scope.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 = Scope.SetDataBuffers(_handle, (Scope.Channel)i, minBuffers[i], maxBuffers[i], (int)sampleCount); } Console.WriteLine("Waiting for trigger...Press a key to abort"); _autoStop = false; status = Scope.RunStreaming(_handle, ref sampleInterval, Scope.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; Scope.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)(Scope.Channel.ChannelA + ch)].range), maxPinned[ch].Target[i], adc_to_mv(maxPinned[ch].Target[i], (int)_channelSettings[(int)(Scope.Channel.ChannelA + ch)].range)); } } writer.WriteLine(); } } } if (Console.KeyAvailable) { Console.ReadKey(true); // clear the key } Scope.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)Scope.Channel.ChannelA].range); // ChannelInfo stores ADC counts Scope.TriggerChannelProperties[] sourceDetails = new Scope.TriggerChannelProperties[] { new Scope.TriggerChannelProperties(triggerVoltage, 256 * 10, triggerVoltage, 256 * 10, Scope.Channel.ChannelA, Scope.ThresholdMode.Level) }; Scope.TriggerConditions[] conditions = new Scope.TriggerConditions[] { new Scope.TriggerConditions(Scope.TriggerState.True, Scope.TriggerState.DontCare, Scope.TriggerState.DontCare, Scope.TriggerState.DontCare, Scope.TriggerState.DontCare, Scope.TriggerState.DontCare, Scope.TriggerState.DontCare) }; Scope.ThresholdDirection[] directions = new Scope.ThresholdDirection[] { Scope.ThresholdDirection.Rising, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.ThresholdDirection.None, Scope.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(); }