0

我目前正在学习 C#,我尝试的第一件事是构建一个通用应用程序,在 Windows 10 IoT 上运行它并通过它控制伺服电机。我的想法是有一个滑块来控制伺服的方向。为了控制伺服,我使用 NuGet 插件 Magellanic.ServoController (by Jeremy Lindsay)

https://jeremylindsayni.wordpress.com/2016/05/16/a-servo-library-in-c-for-raspberry-pi-part-3-implementing-the-interface/

基于滑块的计算和移动工作正常,我唯一的问题是,当我执行伺服的移动时,这个过程占用了 30% 的 CPU 容量(移动完成时的事件)。这导致我可以执行 3 次运动,之后 CPU 接近 100%,第 4 次运动将无法正确执行(因为硬件我使用树莓派 3)。

这是我使用的代码

 using Windows.UI.Xaml;
 using Windows.UI.Xaml.Controls;
 using Magellanic.ServoController;
 using System;
 using System.Threading.Tasks;

 namespace App5
 {

 public sealed partial class MainPage : Page
 {
    public MainPage()
    {
        this.InitializeComponent();           
    }



    private async Task MoveServoToCentre(double MovementTime, double CalculatedFrequency)
    {
        using (var servo = new ServoController(5))
        {
            servo.Frequency = Convert.ToInt32(CalculatedFrequency);
            await servo.Connect();
            servo.SetPosition(90).AllowTimeToMove(Convert.ToInt32(MovementTime)).Go();
            servo.Dispose(); 
        }
    }

    private async void Slider_Value_ChangedAsync(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
    {
        Slider slider = sender as Slider;

        if (slider.Value < 50)
        {
            await CalculationAsync(slider.Value);

        }
        else if (slider.Value > 50)
        {

            await CalculationAsync(slider.Value);

        }

    }

    public string PreviousValue;
    public double RequiredFrequenz;



    private async Task CalculationAsync(double value)
    {
        if (PreviousValue != null)
        {
            double Result = System.Math.Abs(Convert.ToDouble(PreviousValue)) - value;


            if (Result < 0)
            {
                RequiredFrequenz = 100;
            }
            else if (Result > 0)
            {
                RequiredFrequenz = 200;
            }

            double TimeToMove = System.Math.Abs(((int)Math.Round(Result * 3.8)));

            System.Diagnostics.Debug.WriteLine(TimeToMove);
            System.Diagnostics.Debug.WriteLine(Result);
            System.Diagnostics.Debug.WriteLine(value);
            System.Diagnostics.Debug.WriteLine(PreviousValue);
            System.Diagnostics.Debug.WriteLine(RequiredFrequenz);

            await MoveServoToCentre(TimeToMove, RequiredFrequenz);

            TimeToMove = 0;
        }
        else
        {
            if (value > 50)
            {
                double TimeToMove = ((int)Math.Round((value - 50) * 3.8));
                RequiredFrequenz = 100;

                System.Diagnostics.Debug.WriteLine(TimeToMove);
                System.Diagnostics.Debug.WriteLine(value);
                System.Diagnostics.Debug.WriteLine(PreviousValue);
                System.Diagnostics.Debug.WriteLine(RequiredFrequenz);

                await MoveServoToCentre(TimeToMove, RequiredFrequenz);

                TimeToMove = 0;

            }
            else if (value < 50)
            {
                double TimeToMove = System.Math.Abs(((int)Math.Round((value - 50) * 3.8)));
                RequiredFrequenz = 200;

                System.Diagnostics.Debug.WriteLine(TimeToMove);
                System.Diagnostics.Debug.WriteLine(value);
                System.Diagnostics.Debug.WriteLine(PreviousValue);
                System.Diagnostics.Debug.WriteLine(RequiredFrequenz);
                await MoveServoToCentre(TimeToMove, RequiredFrequenz);

                TimeToMove = 0;
            }
        }


        PreviousValue = value.ToString();
        value = 0;
    }
}
}

我目前的猜测是某些代码提供程序未正确卸载或类似情况。

非常感谢您的帮助!

PS:这里是 NuGet 插件代码的链接:

https://github.com/jeremylindsayni/Magellanic.ServoController/blob/master/ServoController.cs

4

1 回答 1

1

这个问题看起来像是由于反复调用这行方法引起的ServoGpioPin = pwmController.OpenPin(ServoPin);ServoController.Connect()但我不确定根本原因是什么。

有一个解决方法:首先实例化ServoControllerand 只调用ServoController.Connect()一次,而不是每次在MoveServoToCentre()方法中都做这个工作。像这样的代码示例:

    ServoController servo = new ServoController(5);

    protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
        await servo.Connect();
    }

    private void MoveServoToCentre(double MovementTime, double CalculatedFrequency)
    {
        servo.Frequency = Convert.ToInt32(CalculatedFrequency);

        servo.SetPosition(90).AllowTimeToMove(Convert.ToInt32(MovementTime)).Go();
    }
于 2017-07-12T06:37:51.990 回答