通过 C# 控制舵机,Windows 10 物联网和 Magellanic.ServoController - CPU 问题以及如何解决它们?

Control a Servo by C#, Windows 10 IoT and the Magellanic.ServoController - CPU issues and how to resolve them?

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

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

基于滑块的计算和移动工作正常,我唯一的问题是,当我执行伺服移​​动时,这个过程占用了 CPU 容量的 30%(当运动完成)。这导致我可以执行 3 次运动,此后 CPU 接近 100%,并且第 4 次运动将无法正确执行(因为硬件我使用 raspberry pi 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:这里是 link 到 NuGet 插件的代码:

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

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

有一个解决方法:首先实例化 ServoController 并仅调用 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();
    }