如何在一定的间隔时间内计算脉冲输入?

时间:2017-03-27 19:36:27

标签: raspberry-pi iot windows-10-iot-core

我开发了一个带有windows 10 iot核心的覆盆子pi中的脉冲计数器(硬币计数器),我需要计算间隔时间为25毫秒的脉冲,如下所示:

0,05€ - 1脉冲 0,10€ - 2个脉冲 0,20€ - 4个脉冲 0,50€ - 10个脉冲 1欧元 - 20个脉冲 2€ - 40脉冲

喜欢这张图片:pulses

当间隔时间不同于25毫秒时,我需要打印脉冲数(插入值)。

我有这段代码:

public MainPage()
    {
        this.InitializeComponent();
        InitGPIO();
    }

    private void InitGPIO()
    {
        var gpio = GpioController.GetDefault();

        if (gpio == null)
        {
            GpioStatus.Text = "There is no GPIO controller on this device.";
        }

        coinPin = gpio.OpenPin(coin_Pin);

        if (coinPin.IsDriveModeSupported(GpioPinDriveMode.InputPullUp))
        {
            coinPin.SetDriveMode(GpioPinDriveMode.InputPullUp);
        } else
        {
            coinPin.SetDriveMode(GpioPinDriveMode.Input);
        }

        coinPin.DebounceTimeout = TimeSpan.FromMilliseconds(25);

        coinPin.ValueChanged += coinPin_ValueChanged;

        GpioStatus.Text = "GPIO pins initialized correctly.";
    }

    private void coinPin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e)
    {
        if (e.Edge == GpioPinEdge.FallingEdge)
        {
            counter++;
        }

        var task = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            if (e.Edge == GpioPinEdge.FallingEdge)
            {
                //counter++;
                var time = PulseIn(coinPin, e.Edge);
                value = (counter * 5);
                value100 = value / 100;
                //money.Text = "Eur: " + (decimal)value100 + " €";

                if (time != 25)
                {
                    money.Text = "Eur: " + (decimal)value100 + " €";
                    GpioStatus.Text = "" + time;
                } else
                {
                    GpioStatus.IsEnabled = false;
                }
                //GpioStatus.Text = "" + time + "";
            } else
            {
                ///GpioStatus.Text = "" + coinPin.DebounceTimeout;
            }


        });
    }

    private double PulseIn(GpioPin pin, GpioPinEdge edge)
    {
        var sw = new Stopwatch();

        while (edge.Equals(GpioPinEdge.RisingEdge))
        {
            //sw.Start();
        }

        sw.Start();

        if (!edge.Equals(GpioPinEdge.RisingEdge))
        {
            //sw.Stop();
        }

        sw.Stop();

        return sw.Elapsed.TotalMilliseconds;
    }


    private const int coin_Pin = 24;
    private int counter = 0;
    private double value = 0;
    private double value100 = 0;
    private GpioPin coinPin;
你能帮帮我吗? 非常感谢你。

1 个答案:

答案 0 :(得分:0)

从您的代码中

    sw.Start();

    if (!edge.Equals(GpioPinEdge.RisingEdge))
    {
        //sw.Stop();
    }

    sw.Stop();

它实际上衡量ifsw.Start()之间sw.Stop()语句的执行时间。这根本不符合逻辑。下降沿到达时记录watch.Elapsed.TotalMilliseconds并重新启动秒表以测量脉冲间隔时间。为此,我在counter++下添加以下两个代码行,删除var time = PulseIn(coinPin, e.Edge)并在timeinterval中使用GpioStatus.Text = "" + timeinterval代替。

            timeinterval = watch.Elapsed.TotalMilliseconds;
            watch.Restart();

以下是完整的代码:

    private Stopwatch watch = new Stopwatch();
    private void coinPin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e)
    {
        double timeinterval = 0;
        if (e.Edge == GpioPinEdge.FallingEdge)
        {
            counter++;
            timeinterval = watch.Elapsed.TotalMilliseconds;
            watch.Restart();
        }

        var task = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            if (e.Edge == GpioPinEdge.FallingEdge)
            {
                //var time = PulseIn(coinPin, e.Edge);
                value = (counter * 5);
                value100 = value / 100;

                if (timeinterval != 25)
                {
                    money.Text = "Eur: " + (decimal)value100 + " €";
                    GpioStatus.Text = "" + timeinterval;
                }
                //...
            }
        });
    }

您可以尝试上面的代码片段,看它是否符合您的准确度要求。

注意:不适合在软件级别测量硬件脉冲间隔,因为软件抖动总是不可预测的。