示例#1
0
        private void oscTimer_Action(object arg)
        {
            if (!oscTimerLock)
            {
                oscTimerLock = true;

                oscDispatcher.Invoke(
                    new Action(() =>
                {
                    try
                    {
                        if (adcDataValid)
                        {
                            oscDataCanvas.Children.Clear();
                            int xNmb     = AdcData.GetLength(1);
                            double xStep = contentWidth / (xNmb - 1);
                            for (int i = 0; i < xNmb - 1; i++)
                            {
                                Line l            = new Line();
                                l.X1              = i * (xStep);
                                l.X2              = (i + 1) * xStep;
                                l.Y1              = (0.5 - (AdcData[2, i] / (double)0x8000)) * contentHeight;
                                l.Y2              = (0.5 - (AdcData[2, i + 1] / (double)0x8000)) * contentHeight;
                                l.StrokeThickness = 2.0;
                                l.Stroke          = Brushes.Green;
                                oscDataCanvas.Children.Add(l);
                            }
                            adcDataValid = false;
                        }
                    }
                    catch { };
                }));
            }
            oscTimerLock = false;
        }
示例#2
0
文件: FFT3.cs 项目: aemerman/Nevis14
        double sampFreq; //Sampling Frequency

        #endregion Fields

        #region Methods

        public AdcData DoQACalculations(double[] fourierHisto, int channel)
        {
            int numPoints = 0;      //Keeping track of pts in FFT
            int ithData = 0;        //For help looping through FFT
            int numHarm = -1;       //Counting how many harmonics found

            Dictionary<double, double> theData = new Dictionary<double, double>();  //Keeping track of level of each frequency

            double binCont;         // Help with filling FFT
            double sum2 = 0.0;           // For Calculating SINAD
            double bin1, binMax = 0.0;    // For Manipulating output of FFT
            double[] aHarmFreq = new double[150];   //Aliased Harmonics
            double fourierFreq, tempFreq = 0;  //Help with looping through dictionary
            double noDistSum2 = 0;

            AdcData qadata = new AdcData();
            qadata.outFreq = new string[5] { "", "", "", "", "" };

            //----Find the Second Largest Value----//
            bin1 = fourierHisto[0];         // bin1 has the largest value, however
            fourierHisto[0] = 0;            // that isn't actually part of our data.
            binMax = fourierHisto.Max();        // The max value, our signal, is actually
            fourierHisto[0] = bin1;             // the second largest value, now in binMax.

            chart1.Series[channel].Points.AddXY(0, 20 * Math.Log10(Math.Abs(fourierHisto[1]) / Math.Abs(binMax))); // Only added to make plot look nicer
            //----Normalize all the points to the maximum----//
            for (int i = 1; i < (sampLength / 2); i++)
            {
                binCont = Math.Abs(fourierHisto[i]) / Math.Abs(binMax); // Normalizing to the maximum
                theData[20 * Math.Log10(binCont)] = ((i) * sampFreq / sampLength);
                chart1.Series[channel].Points.AddXY((i) * sampFreq / sampLength, 20 * Math.Log10(binCont));
                if (binCont != 1.0)
                {            // This is all points except the signal
                    numPoints++;
                    sum2 += binCont * binCont;
                }
            }

            noDistSum2 += sum2;     // This is so we can make parallel calculations subtracting harmonics

            //----Find Relevant Harmonics----//
            // Harmonics occur at |+/- (k*sampFreq) +/- (n*signalFreq)|
            // There will be overcounting if we let both k and n go +/-
            // Keeping k positive, and for k=0 keeping n positive,thedata there is no overcounting

            for (int k = 0; k <= 20; k++)
            {
                for (int ord = -55; ord <= 55; ord++)
                {
                    if (k > 0 || ord >= 0)
                        tempFreq = Math.Abs(k * sampFreq + ord * freq);
                    if (tempFreq != freq && tempFreq < sampFreq / 2 && tempFreq > 0)
                    {     // Limits range of interesting harmonics
                        numHarm++;
                        aHarmFreq[numHarm] = tempFreq;
                    }
                }
            }

            //----Printing the Highest Readings and Corresponding Freq----//

            var amps = theData.Keys.ToList();
            amps.Sort();

            foreach (double normAmp in amps)
            {
                fourierFreq = theData[normAmp];
                if ((ithData > (numPoints - 6)) && (ithData < numPoints))
                {
                    qadata.outFreq[numPoints - 1 - ithData] = String.Format("  {0:F2},   {1:F2}", fourierFreq, normAmp);
                }
                if (ithData == numPoints - 1)
                {
                    qadata.sfdr = normAmp;
                    // The SFDR is distance from signal (normalized to zero) to second largest
                    // value. This will be the normalized amplitude of the second last point
                    // since the last point is the signal (at 0 dB).
                }
                // This will remove the relevant harmonics so we can calculate SNR
                for (int i = 0; i <= numHarm; i++)
                {
                    if (Math.Abs(fourierFreq - aHarmFreq[i]) < 0.00001)
                    {
                        noDistSum2 -= Math.Pow(10, normAmp / 10);
                    }
                }
                ithData++;
            }

            //----Calculating Characteristic Variables----//
            qadata.sinadNoHarm = 10 * Math.Log10(noDistSum2);
            qadata.sinad = 10 * Math.Log10(sum2);
            qadata.enob = (-qadata.sinad - 1.76) / 6.02;

            return qadata;
        }
示例#3
0
文件: FFT3.cs 项目: aemerman/Nevis14
        private void AddDataToChart(AdcData[] adcData)
        {
            // Add QA information to the chart area
            for (int isig = 0; isig < numchannels; isig++)
            {
                var fftInfo = new Legend
                {
                    BackColor = Color.Transparent,
                    InsideChartArea = chart1.ChartAreas[isig].Name,
                    LegendStyle = LegendStyle.Column,
                    Name = "Info Legend " + (isig + 1)
                };
                for (int i = 0; i < 11; i++)
                    fftInfo.CustomItems.Add(new LegendItem());

                fftInfo.CustomItems[0].Cells.Add(new LegendCell(""));
                fftInfo.CustomItems[1].Cells.Add(new LegendCell(String.Format("SFDR: {0:F2}", adcData[isig].sfdr)));
                fftInfo.CustomItems[2].Cells.Add(new LegendCell(String.Format("SINAD: {0:F2}", adcData[isig].sinad)));
                fftInfo.CustomItems[3].Cells.Add(new LegendCell(String.Format("SNR: {0:F2}", adcData[isig].sinadNoHarm)));
                fftInfo.CustomItems[4].Cells.Add(new LegendCell(String.Format("ENOB: {0:F2}", adcData[isig].enob)));
                fftInfo.CustomItems[5].Cells.Add(new LegendCell("Spur Freq. [MHz]:"));
                for (int i = 6; i < 11; i++)
                {
                    fftInfo.CustomItems[i].Cells.Add(new LegendCell(String.Format("{0:F2}", adcData[isig].outFreq[i - 6])));
                }
                Font infoFont = new Font(FontFamily.GenericSansSerif, 9, FontStyle.Italic);
                for (int i = 0; i < 11; i++)
                {
                    fftInfo.CustomItems[i].Cells[0].Font = infoFont;
                    fftInfo.CustomItems[i].Cells[0].Alignment = ContentAlignment.MiddleLeft;
                }

                // Add everything to the original chart
                chart1.Legends.Add(fftInfo);
            }
        }
示例#4
0
文件: FFT3.cs 项目: aemerman/Nevis14
        public AdcData[] FFT3(double infreq, int channels = 4)
        {
            numchannels = channels;
            freq = infreq;
            chart1 = new Chart();
            chart1.Size = new System.Drawing.Size(690, 595);

            //----Setting Sampling Frequency----//

            switch ((int)(5 * freq))      //To bypass C# rules about switching doubles
            {
                case 25:
                    sampFreq = 40; freq = 5.0065104167; break;
                case 90:
                    sampFreq = 40.113166485310122; break;
                case 50:
                    sampFreq = 40; freq = 9.967447917; break;
                case 10:
                    sampFreq = 40.0000000667; freq = 1.9986979167; break;
                case 1:
                    sampFreq = 40.0; break;
                default:
                    sampFreq = 40.0; break;
            }

            InitializeChart();

            double[][] signalHisto = ReadData();

            FormatChart("sig");
            chart1.SaveImage(filePath + "signal.png", ChartImageFormat.Png);

            /*for (int i = 3; i > 0; i--)
            {
                chart1.Series.Remove(chart1.Series[i]);
                chart1.ChartAreas.Remove(chart1.ChartAreas[i]);
                chart1.Titles.Remove(chart1.Titles[i+1]);
            }
            chart1.Series[0].MarkerSize = 3;
            chart1.SaveImage(filePath + "signal_large.png", ChartImageFormat.Png);*/

            //---- Start to Take FFTs----//
            AdcData[] adcData = new AdcData[4];
            for (int i = 0; i < 4; i++) adcData[i].outFreq = new string[5] { "", "", "", "", "" };

            // Reset Charts
            InitializeChart();

            // Start doing FFTs for each channel
            for (int isig = 0; isig < numchannels; isig++)
            {
                double[] fourierHisto = DoFFT(signalHisto[isig]);
                adcData[isig] = DoQACalculations(fourierHisto, isig);
            }   //End FFT

            FormatChart("FFT");
            AddDataToChart(adcData);
            chart1.Size = new Size(1000, 1000);
            chart1.SaveImage(filePath + "fft.png", ChartImageFormat.Png); // Save the FFT Charts
            return adcData;
        }
示例#5
0
文件: Form1.cs 项目: aemerman/Nevis14
        private void WriteResult(AdcData[] adcData)
        {
            if (adcData.Length != 4) throw new Exception("Invalid input to WriteResult.");
            bool underperf = false;
            bool defect = false;
            for (int i = 0; i < 4; i++) {
                if (adcData[i].enob < (enobBound * 0.9) || (1 - chipControl1.adcs[i].dynamicRange / 4096.0) > calBound)
                    defect = true;
                else if (adcData[i].enob < enobBound)
                    underperf = true;
                resultBox.Update(() => resultBox.Text += "Channel " + (i + 1)
                    + Environment.NewLine + "   ENOB = " + Math.Round(adcData[i].enob,4)
                    + Environment.NewLine + "   Range = " + chipControl1.adcs[i].dynamicRange
                    + Environment.NewLine, true);
            }
            if (!underperf && !defect) {
                resultBox.Update(() => { resultBox.BackColor = Color.Green;
                    resultBox.Text += "Chip fully operational"; });
            }
            else {
                if (defect){
                    resultBox.Update(() => { resultBox.BackColor = Color.Red;
                        resultBox.Text += "Defective Chip"; });
                }else{
                    resultBox.Update(() => { resultBox.BackColor = Color.Yellow;
                        resultBox.Text += "Chip Underperforming"; });

                }
            }
        }