public static float[] GetWaveFromFile(AnalogChannel channel, uint waveLength, double samplePeriod, double timeOffset) { if(readChannel == null || readTime == null) { String filename = Path.GetTempFileName(); FileStream f = new FileStream(filename, FileMode.Create, FileAccess.Write); byte[] i2cSequence = Resources.Load ("i2c_sequence.mat"); f.Write(i2cSequence, 0, i2cSequence.Length); f.Close(); MatfileReader matfileReader = new MatlabFileIO.MatfileReader(filename); readChannel = new Dictionary<AnalogChannel, float[]>() { { AnalogChannel.ChA, Utils.CastArray<double, float>(matfileReader.Variables["chA"].data as double[]) }, { AnalogChannel.ChB, Utils.CastArray<double, float>(matfileReader.Variables["chB"].data as double[]) }, }; readTime = matfileReader.Variables["time"].data as double[]; samplePeriodOriginal = readTime[1] - readTime[0]; sequenceLength = readChannel[AnalogChannel.ChA].Length; matfileReader.Close(); } if (samplePeriod / samplePeriodOriginal % 1.0 != 0.0) throw new Exception("Data from file doesn't suit the dummy scope sampling frequency"); uint decimation = (uint)Math.Ceiling(samplePeriod / samplePeriodOriginal); float[] wave = Utils.DecimateArray(readChannel[channel], decimation); int sampleOffset = (int)Math.Ceiling(timeOffset / samplePeriodOriginal % sequenceLength); int requiredRepetitions = (int)Math.Ceiling(waveLength / (double)wave.Length); if (requiredRepetitions > 1) { List<float> concat = new List<float>(); for(int i = 0; i < requiredRepetitions; i++) concat.AddRange(wave); wave = concat.Take((int)waveLength).ToArray(); } return wave; }
float baseVoltageRangeMax = 0.6769f; //V /// <summary> /// Sets and uploads the divider and multiplier what are optimal for the requested range /// </summary> /// <param name="channel"></param> /// <param name="minimum"></param> /// <param name="maximum"></param> public void SetVerticalRange(AnalogChannel channel, float minimum, float maximum) { if (!Connected) return; //Walk through dividers/multipliers till requested range fits //this walk assumes it starts with the smallest range, and that range is only increasing int dividerIndex = 0; int multIndex = 0; verticalRanges[channel] = new Range(minimum, maximum); for (int i = 0; i < rom.computedDividers.Length * rom.computedMultipliers.Length; i++) { dividerIndex= i / rom.computedMultipliers.Length; multIndex = rom.computedMultipliers.Length - (i % rom.computedMultipliers.Length) - 1; if ( (ProbeScaleHostToScope(channel, maximum) < baseVoltageRangeMax * rom.computedDividers[dividerIndex] / rom.computedMultipliers[multIndex]) && (ProbeScaleHostToScope(channel, minimum) > baseVoltageRangeMin * rom.computedDividers[dividerIndex] / rom.computedMultipliers[multIndex]) ) break; } SetDivider(channel, validDividers[dividerIndex]); SetMultiplier(channel, validMultipliers[multIndex]); channelSettings[channel] = rom.getCalibration(channel, validDividers[dividerIndex], validMultipliers[multIndex]); SetYOffset(channel, yOffset[channel]); yOffset[channel] = GetYOffset(channel); if (channel == triggerAnalog.channel) { TriggerAnalog = this.triggerAnalog; //SetTriggerThreshold(this.triggerThreshold); } }
public float GetYOffset(AnalogChannel channel) { REG r = (channel == AnalogChannel.ChA) ? REG.CHA_YOFFSET_VOLTAGE : REG.CHB_YOFFSET_VOLTAGE; byte offsetByte = FpgaSettingsMemory[r].GetByte(); return ConvertYOffsetByteToVoltage(channel, offsetByte); }
/// <summary> /// Sets vertical offset of a channel /// </summary> /// <param name="channel">0 or 1 (channel A or B)</param> /// <param name="offset">Vertical offset in Volt</param> public void SetYOffset(AnalogChannel channel, float offset) { yOffset[channel] = offset; if (!Connected) return; //FIXME: convert offset to byte value REG r = (channel == AnalogChannel.ChA) ? REG.CHA_YOFFSET_VOLTAGE : REG.CHB_YOFFSET_VOLTAGE; //Logger.Debug("Set Y-offset for channel " + channel + " to " + offset + "V"); //Offset: 0V --> 150 - swing +-0.9V //Let ADC output of 127 be the zero point of the Yoffset double[] c = channelSettings[channel].coefficients; int offsetInt = (int)(-(ProbeScaleHostToScope(channel, offset) + c[2] + c[0] * 127) / c[1]); FpgaSettingsMemory[r].Set((byte)Math.Max(yOffsetMin, Math.Min(yOffsetMax, -(ProbeScaleHostToScope(channel, offset) + c[2] + c[0] * 127) / c[1]))); //Logger.Debug(String.Format("Yoffset Ch {0} set to {1} V = byteval {2}", channel, GetYOffset(channel), FpgaSettingsMemory[r].GetByte())); }
public static SmartScope.GainCalibration ComputeCalibration(AnalogChannel channel, double div, double mul, double[] inputVoltage, double[] adcValue, double[] yOffset) { int rows = adcValue.Length; int cols = 3; double[] matrixData = adcValue.Concat( yOffset.Concat( Enumerable.Repeat(1.0, rows) )).ToArray(); var A = new DenseMatrix(rows, cols, matrixData); var B = new DenseMatrix(rows, 1, inputVoltage); var C = A.QR().Solve(B); return new SmartScope.GainCalibration() { channel = channel, divider = div, multiplier = mul, coefficients = C.ToColumnWiseArray() }; }
public static Dictionary<AnalogChannel, AnalogWaveProperties> MeasureAutoArrangeSettings(IScope scope, AnalogChannel aciveChannel, Action<float> progressReport) { float progress = 0f; progressReport(progress); //stop scope streaming scope.DataSourceScope.Stop(); //Prepare scope for test if (scope is SmartScope) (scope as SmartScope).SetDisableVoltageConversion(false); //set to timerange wide enough to capture 50Hz, but slightly off so smallest chance of aliasing const float initialTimeRange = 0.0277f; scope.AcquisitionMode = AcquisitionMode.AUTO; scope.AcquisitionLength = initialTimeRange; scope.SetViewPort(0, scope.AcquisitionLength); //s.AcquisitionDepth = 4096; scope.TriggerHoldOff = 0; scope.SendOverviewBuffer = false; AnalogTriggerValue atv = new AnalogTriggerValue(); atv.channel = AnalogChannel.ChA; atv.direction = TriggerDirection.RISING; atv.level = 5000; scope.TriggerAnalog = atv; foreach (AnalogChannel ch in AnalogChannel.List) scope.SetCoupling(ch, Coupling.DC); scope.CommitSettings(); progress += .1f; progressReport(progress); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // VERTICAL == VOLTAGE //set to largest input range float maxRange = 1.2f / 1f * 36f; foreach (AnalogChannel ch in AnalogChannel.List) scope.SetVerticalRange(ch, -maxRange / 2f, maxRange / 2f); float[] minValues = new float[] { float.MaxValue, float.MaxValue }; float[] maxValues = new float[] { float.MinValue, float.MinValue }; //measure min and max voltage over 3 full ranges for (int i = -1; i < 2; i++) { progress += .1f; progressReport(progress); foreach (AnalogChannel ch in AnalogChannel.List) scope.SetYOffset(ch, (float)i * maxRange); scope.CommitSettings(); System.Threading.Thread.Sleep(100); scope.ForceTrigger(); //fetch data DataPackageScope p = FetchLastFrame(scope); p = FetchLastFrame(scope); //needs this second fetch as well to get voltage conversion on ChanB right?!? if (p == null) { Logger.Error("Didn't receive data from scope, aborting"); return null; } //check if min or max need to be updated (only in case this measurement was not saturated) float[] dataA = (float[])p.GetData(DataSourceType.Viewport, AnalogChannel.ChA).array; float[] dataB = (float[])p.GetData(DataSourceType.Viewport, AnalogChannel.ChB).array; float minA = dataA.Min(); float maxA = dataA.Max(); float minB = dataB.Min(); float maxB = dataB.Max(); if (minA != p.SaturationLowValue[AnalogChannel.ChA] && minA != p.SaturationHighValue[AnalogChannel.ChA] && minValues[0] > minA) minValues[0] = minA; if (minB != p.SaturationLowValue[AnalogChannel.ChB] && minB != p.SaturationHighValue[AnalogChannel.ChB] && minValues[1] > minB) minValues[1] = minB; if (maxA != p.SaturationLowValue[AnalogChannel.ChA] && maxA != p.SaturationHighValue[AnalogChannel.ChA] && maxValues[0] < maxA) maxValues[0] = maxA; if (maxB != p.SaturationLowValue[AnalogChannel.ChB] && maxB != p.SaturationHighValue[AnalogChannel.ChB] && maxValues[1] < maxB) maxValues[1] = maxB; } //calc ideal voltage range and offset float sizer = 3; //meaning 3 waves would fill entire view float[] coarseAmplitudes = new float[2]; coarseAmplitudes[0] = maxValues[0] - minValues[0]; coarseAmplitudes[1] = maxValues[1] - minValues[1]; float[] desiredOffsets = new float[2]; desiredOffsets[0] = (maxValues[0] + minValues[0]) / 2f; desiredOffsets[1] = (maxValues[1] + minValues[1]) / 2f; float[] desiredRanges = new float[2]; desiredRanges[0] = coarseAmplitudes[0] * sizer; desiredRanges[1] = coarseAmplitudes[1] * sizer; //intervene in case the offset is out of range for this range if (desiredRanges[0] < Math.Abs(desiredOffsets[0])) desiredRanges[0] = Math.Abs(desiredOffsets[0]); if (desiredRanges[1] < Math.Abs(desiredOffsets[1])) desiredRanges[1] = Math.Abs(desiredOffsets[1]); //set fine voltage range and offset scope.SetVerticalRange(AnalogChannel.ChA, -desiredRanges[0] / 2f, desiredRanges[0] / 2f); scope.SetYOffset(AnalogChannel.ChA, -desiredOffsets[0]); scope.SetVerticalRange(AnalogChannel.ChB, -desiredRanges[1] / 2f, desiredRanges[1] / 2f); scope.SetYOffset(AnalogChannel.ChB, -desiredOffsets[1]); scope.CommitSettings(); //now get data in order to find accurate lowHigh levels (as in coarse mode this was not accurate) DataPackageScope pFine = FetchLastFrame(scope); pFine = FetchLastFrame(scope); //needs this second fetch as well to get voltage conversion on ChanB right?!? Dictionary<AnalogChannel, float[]> dataFine = new Dictionary<AnalogChannel, float[]>(); dataFine.Add(AnalogChannel.ChA, (float[])pFine.GetData(DataSourceType.Viewport, AnalogChannel.ChA).array); dataFine.Add(AnalogChannel.ChB, (float[])pFine.GetData(DataSourceType.Viewport, AnalogChannel.ChB).array); Dictionary<AnalogChannel, float> minimumValues = new Dictionary<AnalogChannel, float>(); Dictionary<AnalogChannel, float> maximumValues = new Dictionary<AnalogChannel, float>(); Dictionary<AnalogChannel, float> amplitudes = new Dictionary<AnalogChannel, float>(); Dictionary<AnalogChannel, float> offsets = new Dictionary<AnalogChannel, float>(); Dictionary<AnalogChannel, bool> isFlatline = new Dictionary<AnalogChannel, bool>(); foreach (var kvp in dataFine) { minimumValues.Add(kvp.Key, kvp.Value.Min()); maximumValues.Add(kvp.Key, kvp.Value.Max()); amplitudes.Add(kvp.Key, kvp.Value.Max() - kvp.Value.Min()); offsets.Add(kvp.Key, (kvp.Value.Max() + kvp.Value.Min())/2f); isFlatline.Add(kvp.Key, amplitudes[kvp.Key] < 0.01f); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // HORIZONTAL == FREQUENCY const float minTimeRange = 500f * 0.00000001f;//500 samples over full hor span const float maxTimeRange = 1f; double frequency, frequencyError, dutyCycle, dutyCycleError; Dictionary<AnalogChannel, double> finalFrequencies = new Dictionary<AnalogChannel, double>(); finalFrequencies.Add(AnalogChannel.ChA, double.MaxValue); finalFrequencies.Add(AnalogChannel.ChB, double.MaxValue); int iterationCounter = 0; //only for performance testing float currTimeRange = minTimeRange; bool continueLooping = true; if (isFlatline.Where(x => x.Value).ToList().Count == isFlatline.Count) //no need to find frequency in case of 2 DC signals continueLooping = false; while (continueLooping) { progress += .04f; progressReport(progress); iterationCounter++; //only for performance testing scope.AcquisitionLength = currTimeRange; scope.SetViewPort(0, scope.AcquisitionLength); scope.CommitSettings(); DataPackageScope pHor = FetchLastFrame(scope); pHor = FetchLastFrame(scope); Dictionary<AnalogChannel, float[]> timeData = new Dictionary<AnalogChannel, float[]>(); timeData.Add(AnalogChannel.ChA, (float[])pHor.GetData(DataSourceType.Viewport, AnalogChannel.ChA).array); timeData.Add(AnalogChannel.ChB, (float[])pHor.GetData(DataSourceType.Viewport, AnalogChannel.ChB).array); foreach (var kvp in timeData) { //make sure entire amplitude is in view float currMinVal = kvp.Value.Min(); float currMaxVal = kvp.Value.Max(); float lowMarginValue = minimumValues[kvp.Key] + amplitudes[kvp.Key] * 0.1f; float highMarginValue = maximumValues[kvp.Key] - amplitudes[kvp.Key] * 0.1f; if (currMinVal > lowMarginValue) break; if (currMaxVal < highMarginValue) break; ComputeFrequencyDutyCycle(pHor.GetData(DataSourceType.Viewport, kvp.Key), out frequency, out frequencyError, out dutyCycle, out dutyCycleError); if (!double.IsNaN(frequency) && (finalFrequencies[kvp.Key] == double.MaxValue)) finalFrequencies[kvp.Key] = frequency; } //update and check whether we've found what we were looking for currTimeRange *= 100f; bool freqFoundForAllActiveWaves = true; foreach (var kvp in timeData) if (!isFlatline[kvp.Key] && finalFrequencies[kvp.Key] == double.MaxValue) freqFoundForAllActiveWaves = false; continueLooping = !freqFoundForAllActiveWaves; if (currTimeRange > maxTimeRange) continueLooping = false; } //in case of flatline or very low freq, initial value will not have changed foreach (AnalogChannel ch in finalFrequencies.Keys.ToList()) if (finalFrequencies[ch] == double.MaxValue) finalFrequencies[ch] = 0; Dictionary<AnalogChannel, AnalogWaveProperties> waveProperties = new Dictionary<AnalogChannel, AnalogWaveProperties>(); foreach (var kvp in isFlatline) waveProperties.Add(kvp.Key, new AnalogWaveProperties(minimumValues[kvp.Key], maximumValues[kvp.Key], amplitudes[kvp.Key], offsets[kvp.Key], isFlatline[kvp.Key], finalFrequencies[kvp.Key])); return waveProperties; }
private float ProbeScaleHostToScope(AnalogChannel ch, float volt) { return volt / probeSettings[ch]; }
public void SetYOffsetByte(AnalogChannel channel, byte offset) { REG r = channel == AnalogChannel.ChA ? REG.CHA_YOFFSET_VOLTAGE : REG.CHB_YOFFSET_VOLTAGE; Logger.Debug("Set Y offset for channel " + channel + " to " + offset + " (int value)"); FpgaSettingsMemory[r].Set(offset); }
public Coupling GetCoupling(AnalogChannel channel) { STR dc = channel == AnalogChannel.ChA ? STR.CHA_DCCOUPLING : STR.CHB_DCCOUPLING; return(StrobeMemory[dc].GetBool() ? Coupling.DC : Coupling.AC); }
public ProbeDivision GetProbeDivision(AnalogChannel ch) { return(probeSettings[ch]); }
public void SetProbeDivision(AnalogChannel ch, ProbeDivision division) { probeSettings[ch] = division; SetVerticalRange(ch, verticalRanges[ch].minimum, verticalRanges[ch].maximum); }
public float GetYOffsetMin(AnalogChannel channel) { return(ConvertYOffsetByteToVoltage(channel, yOffsetMin)); }
private float ProbeScaleScopeToHost(AnalogChannel ch, float volt) { return(volt * probeSettings[ch]); }
private float ProbeScaleHostToScope(AnalogChannel ch, float volt) { return(volt / probeSettings[ch]); }
void SetDivider(AnalogChannel channel, double divider) { validateDivider(divider); byte div = (byte)(Array.IndexOf(validDividers, divider)); int bitOffset = channel.Value * 4; byte mask = (byte)(0x3 << bitOffset); byte divMul = FpgaSettingsMemory[REG.DIVIDER_MULTIPLIER].GetByte(); divMul = (byte)((divMul & ~mask) + (div << bitOffset)); FpgaSettingsMemory[REG.DIVIDER_MULTIPLIER].Set(divMul); }
/// <summary> /// Get a package of scope data /// </summary> /// <returns>Null in case communication failed, a data package otherwise. Might result in disconnecting the device if a sync error occurs</returns> public DataPackageScope GetScopeData() { if (hardwareInterface == null) { return(null); } byte[] buffer; SmartScopeHeader header; try { buffer = hardwareInterface.GetData(BYTES_PER_BURST); } catch (ScopeIOException) { return(null); } catch (Exception e) { Logger.Error("Error while trying to get scope data: " + e.Message); return(null); } if (buffer == null) { return(null); } try { header = new SmartScopeHeader(buffer); } catch (Exception e) { #if WINDOWS Logger.Warn("Error parsing header - attempting to fix that"); header = ResyncHeader(); if (header == null) { Logger.Error("Resync header failed - resetting"); Reset(); return(null); } #else Logger.Error("Failed to parse header - resetting scope: " + e.Message); Reset(); return(null); #endif } bool newAcquisition = currentDataPackage == null || currentDataPackage.Identifier != header.AcquisitionId; AcquisitionDepthLastPackage = header.AcquisitionDepth; SamplePeriodLastPackage = header.SamplePeriod; acquiring = header.Acquiring; stopPending = header.LastAcquisition; awaitingTrigger = header.AwaitingTrigger; armed = header.Armed; List <AnalogChannel> analogChannels = new List <AnalogChannel>() { AnalogChannel.ChA, AnalogChannel.ChB }; Dictionary <AnalogChannel, GainCalibration> channelConfig = header.ChannelSettings(this.rom); Dictionary <Channel, Array> receivedData; //find min and max voltages for each channel, to allow saturation detection byte[] minMaxBytes = new byte[] { 0, 255 }; Dictionary <Channel, float[]> minMaxVoltages = new Dictionary <Channel, float[]>(); foreach (AnalogChannel ch in analogChannels) { minMaxVoltages.Add(ch, minMaxBytes.ConvertByteToVoltage(header.ChannelSettings(this.rom)[ch], header.GetRegister(ch.YOffsetRegister()), probeSettings[ch])); } if (header.OverviewBuffer) { buffer = hardwareInterface.GetData(OVERVIEW_BUFFER_SIZE * BYTES_PER_SAMPLE); if (newAcquisition) { //This should not be possible since the overview is always sent *AFTER* the viewport data, //so the last received package's identifier should match with this one Logger.Warn("Got an overview buffer but no data came in for it before. This is wrong"); return(null); } if (buffer == null) { //This is also pretty bad Logger.Warn("Failed to get overview buffer payload. This is bad"); return(null); } receivedData = SplitAndConvert(buffer, analogChannels, header); foreach (Channel ch in receivedData.Keys) { currentDataPackage.SetData(ChannelDataSourceScope.Overview, ch, receivedData[ch]); if (ch is AnalogChannel) { currentDataPackage.SaturationLowValue[ch] = minMaxVoltages[ch][0]; currentDataPackage.SaturationHighValue[ch] = minMaxVoltages[ch][1]; } } return(currentDataPackage); } if (header.FullAcquisitionDump) { buffer = hardwareInterface.GetData(header.Samples * BYTES_PER_SAMPLE); if (newAcquisition || buffer == null) { Logger.Warn("Got an acquisition buffer but no data came in for it before. This is wrong"); return(null); } receivedData = SplitAndConvert(buffer, analogChannels, header); foreach (Channel ch in receivedData.Keys) { //Here we don't use AddData since we want to assign the whole acqbuf in memory // at once instead of growing it as it comes in. // Need to update datapackage timestamp though! ChannelData target = currentDataPackage.GetData(ChannelDataSourceScope.Acquisition, ch); Array targetArray; if (target == null) { targetArray = Array.CreateInstance(receivedData[ch].GetType().GetElementType(), header.AcquisitionDepth); currentDataPackage.SetData(ChannelDataSourceScope.Acquisition, ch, targetArray); if (ch is AnalogChannel) { currentDataPackage.SaturationLowValue[ch] = minMaxVoltages[ch][0]; currentDataPackage.SaturationHighValue[ch] = minMaxVoltages[ch][1]; } } else { targetArray = target.array; } Array.ConstrainedCopy(receivedData[ch], 0, targetArray, header.PackageOffset * header.Samples, receivedData[ch].Length); } float fullAcquisitionDumpProgress = (header.PackageOffset + 1) * (float)header.Samples / header.AcquisitionDepth; //update FullAcquisitionFetchProgress and fire event when finished float previousAcqTransferProgress = currentDataPackage.FullAcquisitionFetchProgress; currentDataPackage.FullAcquisitionFetchProgress = fullAcquisitionDumpProgress; if (currentDataPackage.FullAcquisitionFetchProgress == 1 && previousAcqTransferProgress < 1) { currentDataPackage.UpdateTimestamp(); if (OnAcquisitionTransferFinished != null) { OnAcquisitionTransferFinished(this, new EventArgs()); } } return(currentDataPackage); } if (header.ImpossibleDump) { return(null); } if (header.NumberOfPayloadBursts == 0 || header.TimedOut) { return(null); } try { buffer = hardwareInterface.GetData(BYTES_PER_BURST * header.NumberOfPayloadBursts); } catch (Exception e) { Logger.Error("Failed to fetch payload - resetting scope: " + e.Message); Reset(); return(null); } if (buffer == null) { Logger.Error("Failed to get payload - resetting"); Reset(); return(null); } receivedData = SplitAndConvert(buffer, analogChannels, header); if (newAcquisition) { if (header.PackageOffset != 0) { Logger.Warn("Got an off-set package but didn't get any date before"); return(null); } /* FIXME: integrate into header*/ AnalogChannel triggerChannel = header.TriggerValue.channel; byte[] triggerLevel = new byte[] { header.GetRegister(REG.TRIGGER_LEVEL) }; float[] triggerLevelFloat = triggerLevel.ConvertByteToVoltage(header.ChannelSettings(this.rom)[triggerChannel], header.GetRegister(triggerChannel.YOffsetRegister()), probeSettings[triggerChannel]); header.TriggerValue.level = triggerLevelFloat[0]; currentDataPackage = new DataPackageScope(this.GetType(), header.AcquisitionDepth, header.SamplePeriod, header.ViewportLength, header.ViewportOffsetSamples, header.TriggerHoldoff, header.TriggerHoldoffSamples, header.Rolling, header.AcquisitionId, header.TriggerValue, header.ViewportExcess); } #if DEBUG currentDataPackage.header = header; currentDataPackage.Settings["AcquisitionId"] = header.AcquisitionId; #endif currentDataPackage.Settings["InputDecimation"] = header.GetRegister(REG.INPUT_DECIMATION); currentDataPackage.offset[ChannelDataSourceScope.Viewport] = header.ViewportOffset; currentDataPackage.samplePeriod[ChannelDataSourceScope.Viewport] = header.ViewportSamplePeriod; foreach (Channel ch in receivedData.Keys) { currentDataPackage.AddData(ChannelDataSourceScope.Viewport, ch, receivedData[ch]); if (ch is AnalogChannel) { currentDataPackage.SaturationLowValue[ch] = minMaxVoltages[ch][0]; currentDataPackage.SaturationHighValue[ch] = minMaxVoltages[ch][1]; } } foreach (AnalogChannel ch in AnalogChannel.List) { currentDataPackage.Resolution[ch] = ProbeScaleScopeToHost(ch, (float)channelConfig[ch].coefficients[0]); currentDataPackage.Settings["Multiplier" + ch.Name] = channelConfig[ch].multiplier; #if DEBUG currentDataPackage.Settings["Divider" + ch.Name] = channelConfig[ch].divider; currentDataPackage.Settings["Offset" + ch.Name] = ConvertYOffsetByteToVoltage(ch, header.GetRegister(ch.YOffsetRegister())); #endif } return(currentDataPackage); }
public Coupling GetCoupling(AnalogChannel channel) { STR dc = channel == AnalogChannel.ChA ? STR.CHA_DCCOUPLING : STR.CHB_DCCOUPLING; return StrobeMemory[dc].GetBool() ? Coupling.DC : Coupling.AC; }
public static REG YOffsetRegister(this AnalogChannel ch) { return((ch == AnalogChannel.ChA) ? REG.CHA_YOFFSET_VOLTAGE : /*(ch == AnalogChannel.ChB) ?*/ REG.CHB_YOFFSET_VOLTAGE); }
private AnalogChannelRaw(AnalogChannel ch) : base(ch.Name + "Raw", ch.Value, typeof(byte)) { }
public static AnalogChannelRaw Raw(this AnalogChannel ch) { return((AnalogChannelRaw)ch); }
public GainCalibration getCalibration(AnalogChannel ch, double divider, double multiplier) { return gainCalibration.Where(x => x.channel == ch && x.divider == divider && x.multiplier == multiplier).First(); }
public void SetDummyWaveAmplitude(AnalogChannel channel, double amplitude) { ChannelConfig[channel].amplitude = amplitude; }
private AnalogChannelRaw(AnalogChannel ch) : base(ch.Name, ch.Value) { }
public void SetDummyWaveFrequency(AnalogChannel channel, double frequency) { ChannelConfig[channel].frequency = frequency; }
private float ConvertYOffsetByteToVoltage(AnalogChannel channel, byte value) { double[] c = channelSettings[channel].coefficients; float voltageSet = (float)(-value * c[1] - c[2] - c[0] * 127.0); return ProbeScaleScopeToHost(channel, voltageSet); }
public void SetDummyWavePhase(AnalogChannel channel, double phase) { ChannelConfig[channel].phase = phase; }
public float GetYOffsetMin(AnalogChannel channel) { return ConvertYOffsetByteToVoltage(channel, yOffsetMin); }
public void SetDummyWaveDutyCycle(AnalogChannel channel, double dc) { ChannelConfig[channel].dutyCycle = dc > 1 ? 1 : dc < 0 ? 0 : dc; }
public float[] GetVerticalRange(AnalogChannel channel) { int dividerIndex = Array.IndexOf (validDividers, channelSettings [channel].divider); int multIndex = Array.IndexOf (validMultipliers, channelSettings [channel].multiplier); return new float[] { ProbeScaleScopeToHost(channel, (float)(baseVoltageRangeMin * rom.computedDividers[dividerIndex] / rom.computedMultipliers[multIndex])), ProbeScaleScopeToHost(channel, (float)(baseVoltageRangeMax * rom.computedDividers[dividerIndex] / rom.computedMultipliers[multIndex])) }; }
public void SetDummyWaveForm(AnalogChannel channel, AnalogWaveForm w) { ChannelConfig[channel].waveform = w; }
public ProbeDivision GetProbeDivision(AnalogChannel ch) { return probeSettings[ch]; }
public void SetDummyWaveDcOffset(AnalogChannel channel, double dcOffset) { ChannelConfig[channel].dcOffset = dcOffset; }
void SetMultiplier(AnalogChannel channel, double multiplier) { validateMultiplier(multiplier); int bitOffset = channel.Value * 4; byte mul = (byte)(Array.IndexOf(validMultipliers, multiplier) << 2); byte mask = (byte)(0xC << bitOffset); byte divMul = FpgaSettingsMemory[REG.DIVIDER_MULTIPLIER].GetByte(); divMul = (byte)((divMul & ~mask) + (mul << bitOffset)); FpgaSettingsMemory[REG.DIVIDER_MULTIPLIER].Set(divMul); }
public void SetDummyWaveDcOffset(AnalogChannel channel, int bursts) { ChannelConfig[channel].bursts = bursts; }
public void SetCoupling(AnalogChannel channel, Coupling coupling) { STR dc = channel == AnalogChannel.ChA ? STR.CHA_DCCOUPLING : STR.CHB_DCCOUPLING; bool enableDc = coupling == Coupling.DC; //Logger.Debug("Set DC coupling for channel " + channel + (enableDc ? " ON" : " OFF")); StrobeMemory[dc].Set(enableDc); }
public void SetNoiseAmplitude(AnalogChannel channel, double noiseAmplitude) { ChannelConfig[channel].noise = noiseAmplitude; }
/// <summary> /// Choose channel upon which to trigger /// </summary> /// <param name="channel"></param> public void SetTriggerChannel(AnalogChannel channel) { this.triggerAnalog.channel = channel; TriggerAnalog = this.triggerAnalog; }
public void SetVerticalRange(AnalogChannel ch, float minimum, float maximum) { }
private float ProbeScaleScopeToHost(AnalogChannel ch, float volt) { return volt * probeSettings[ch]; }
private Dictionary <Channel, Array> SplitAndConvert(byte[] buffer, List <AnalogChannel> channels, SmartScopeHeader header, Dictionary <AnalogChannel, SmartScope.GainCalibration> channelSettings, int offset, int length) { int n_channels = channels.Count; int n_samples = length / n_channels; byte[][] splitRaw = new byte[n_channels][]; float[][] splitVolt = new float[n_channels][]; for (int j = 0; j < n_channels; j++) { splitRaw[j] = new byte[n_samples]; splitVolt[j] = new float[n_samples]; } //this section converts twos complement to a physical voltage value Dictionary <Channel, Array> result = new Dictionary <Channel, Array>(); for (int j = 0; j < n_channels; j++) { AnalogChannel ch = channels[j]; double[] coeff = channelSettings[ch].coefficients; if (coeff.Length != 3) { throw new Exception(String.Format("Calibration coefficients are not of length 3, but {0} for ch {1} (n_ch:{2}", coeff.Length, ch.Name, n_channels)); } byte yOffset = header.GetRegister(ch.YOffsetRegister()); float gain = probeSettings[ch]; float totalOffset = (float)(yOffset * coeff[1] + coeff[2]); int k = j; if (offset + n_channels * (n_samples - 1) + k >= buffer.Length) { throw new Exception(String.Format("Buffer will be addressed out of bounds. [offset:{0}][n_chan:{1}][length:{2}][n_samp:{3}][buf_len:{4}]", offset, n_channels, length, n_samples, buffer.Length)); } for (int i = 0; i < n_samples; i++) { byte b = buffer[offset + k]; splitRaw[j][i] = b; splitVolt[j][i] = (float)(b * coeff[0] + totalOffset) * gain; k += n_channels; } } for (int j = 0; j < n_channels; j++) { AnalogChannel ch = channels[j]; if (header.GetStrobe(STR.LA_ENABLE) && header.GetStrobe(STR.LA_CHANNEL) == ch.Value > 0) { if (j >= splitRaw.Length) { throw new Exception(String.Format("Assigning LA channel failing due to oob index {1} (len = {2})", j, splitRaw.Length)); } result[LogicAnalyserChannel.LA] = splitRaw[j]; } else { if (j >= splitVolt.Length) { throw new Exception(String.Format("Assigning Voltage channel failing due to oob index {1} (len = {2})", j, splitVolt.Length)); } result[ch] = splitVolt[j]; } if (j >= splitRaw.Length) { throw new Exception(String.Format("Assigning RAW failing due to oob index {1} (len = {2})", j, splitRaw.Length)); } result[ch.Raw()] = splitRaw[j]; } return(result); }