计数并行端口输入频率-C# [英] Count Parallel port input frequency - C#

查看:89
本文介绍了计数并行端口输入频率-C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在555定时器IC上对第13针上并行端口的输入频率进行计数,实际频率应为3-4 Hz(ON脉冲)左右.我尝试了几次,几次,但是每次它们给出不同的值.我尝试了以下代码:

I have to count the input frequency of the parallel port at Pin no.13, comming from a 555 timer IC, the real frequency should be around 3-4 Hz (ON Pulse). I have tried several codes, several times but every time those are giving different values. I have tried the following code:

    [DllImport("inpout32.dll", EntryPoint = "Inp32")]
    public static extern int Input(int adress);

    private void button1_Click(object sender, EventArgs e)
    {
        int currentState = Input(889);
        int LastState;
        while (true)
        {
            int State = Input(889);
            if (State != currentState)
            {
                if (Input(889) == 120)
                {
                    LastState = 0;
                }
                else
                {
                    LastState = 1;
                }
                break;
            }
        }
        GetFreq(LastState);

    }
    void GetFreq(int LastPulse)
    {
        int highPulseFreq = 0;
        int lowPulseFreq = 0;
        if (LastPulse == 1)
        {
            highPulseFreq++;
        }
        if (LastPulse == 0)
        {
            lowPulseFreq++;
        }
        int startTime = DateTime.Now.Second;
        while (true)
        {
            if (startTime == DateTime.Now.Second)
            {
                if (Input(889) != 120)// ON
                {
                    if (LastPulse == 0)
                    {
                        highPulseFreq++;
                        LastPulse = 1;
                    }
                }
                else
                {
                    if (LastPulse == 1)
                    {
                        lowPulseFreq++;
                        LastPulse = 0;
                    }
                }
            }
            else
            {
                MessageBox.Show("ON Pulses: " + highPulseFreq.ToString() + Environment.NewLine + "OFF Pulses: " + lowPulseFreq.ToString());
                break;
            }
        }
    }

输出:

我应该怎么做才能获得准确的频率?我的代码有什么问题吗? 我正在使用inpout32.dll来控制并行端口.

What should I do, to get accurate frequency? Is any thing wrong in my code? I am using the inpout32.dll to control parallel port.

推荐答案

您需要以至少是信号最高频率两倍的速率对信号进行采样.如果您预期的最高频率约为4Hz,则在15-20Hz的任何地方对信号进行采样应该会产生良好的结果.

You need to sample your signal at rate that is at least twice the highest frequency in your signal. If your expected highest frequency is about 4Hz, then sampling the signal anywhere from 15 - 20Hz should give good results.

幸运的是,可以在Windows上使用高精度计时器(如果您不需要很高的准确性)进行过多操作的情况下,以这种速率进行采样. 20Hz的采样率对应于50ms的采样周期,因此您可以使用一个循环,在两次采样之间记录大约50ms的睡眠时间.您不会在样本之间获得超精确的delta-T(每个样本之间的时间可能会出现15-30ms的变化,具体取决于您的系统),但是对于您正在处理的频率来说,它应该足够好

Fortunately, sampling at this rate is something that can be done without too much futzing around with high precision timers on Windows (if you don't require a lot of accuracy). A 20Hz sample rate corresponds to a sample period of 50ms, so you can use a loop where you sleep for about 50ms between recording sample values. You won't get a super precise delta-T between samples (you may see variations of up to 15-30ms in the time between each sample, depending on your system), but it should be good enough for the frequencies you're dealing with.

您可以记录几秒钟的样本(以及相关的时间戳),然后将数据导出到电子表格.进入电子表格后,您可以进行一些分析和制图.或者,您可以找到一些时间序列分析代码来分析样本列表,例如使用傅立叶变换(FFT)将信号从时域转换到频域.

You can record several seconds worth of samples (and associated timestamps), and then export the data to a spreadsheet. Once in the spreadsheet, you can do some analysis and graphing. Or you can find some time series analysis code to analyze the list of samples, such as using a Fourier transform (FFT) to convert a signal from the time domain to the frequency domain.

这里是创建样本的示例.如果确实需要更精确的时间戳,则可以在GetInputSamples中将DateTime.Now替换为StopWatch.

Here is an example of creating the samples. You can replace the use of DateTime.Now with a StopWatch in GetInputSamples if you really need more accuracy in the timestamps.

[DllImport("inpout32.dll", EntryPoint = "Inp32")] 
public static extern int Input(int adress); 

struct Sample 
{
    public int Value;
    public int Milliseconds;
};

private void button1_Click(object sender, EventArgs e) 
{ 
    TimeSpan duration = TimeSpan.FromSeconds(5);
    TimeSpan samplePeriod = TimeSpan.FromMilliseconds(50);

    var samples = GetInputSamples(889, duration, samplePeriod);
    SaveSamplesCSV(samples, "test.csv");
} 

private static List<Sample> GetInputSamples(int inputPort, TimeSpan duration, TimeSpan samplePeriod)
{ 
    List<Sample> samples = new List<Sample>();

    var oldPriority = Thread.CurrentThread.Priority;
    try
    {
        Thread.CurrentThread.Priority = ThreadPriority.Highest;

        DateTime start = DateTime.Now;
        while (DateTime.Now - start < duration)
        {
            int value = Input(inputPort); 
            TimeSpan timestamp = DateTime.Now - start;

            samples.Add(new Sample() { Value = value, Milliseconds = (int)timestamp.TotalMilliseconds });

            Thread.Sleep(samplePeriod);
        }
    }
    finally
    {
        Thread.CurrentThread.Priority = oldPriority;
    }

    return samples;
}

private static void SaveSamplesCSV(List<Sample> samples, string fileName)
{
    using (StreamWriter writer = File.CreateText(fileName))
    {
        writer.WriteLine("Sample, Time (ms)");
        foreach (var sample in samples)
        {
            writer.WriteLine("{0}, {1}", sample.Value, sample.Milliseconds);
        }
    }
}

这篇关于计数并行端口输入频率-C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆