2017-07-07 41 views
0

目前我在學習C#和我想的第一件事情的過程是建立一個通用的應用程序,在Windows 10物聯網運行它,並通過它來控制伺服電機。我的想法是有一個控制伺服方向的滑塊。對於(由傑里米·林賽)的基礎上滑塊通過C#,Windows 10 IoT和Magellanic.ServoController控制伺服器 - CPU問題以及如何解決它們?

的計算和運動控制我使用的NuGet插件Magellanic.ServoController伺服工作正常,唯一的問題我有,是,當我執行伺服的移動,這個過程佔用CPU容量的30%(移動完成時的事件)。這導致了我可以執行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

+0

*不要*使用'async void'!它只適用於事件。無法等待產生的方法,並且無法捕獲它引發的任何異常。將簽名更改爲「異步任務」並*等待對該方法的調用。 –

+0

這意味着,所有的方法應該成爲'異步任務',除了'滑塊)Value_Changed'應該變成'async void Slider_Value_Changed' –

+0

非常感謝那個提示!我按照你的建議更正了 - 我也再次測試過,但CPU使用率的問題仍然存在。 – Unkown13

回答

1

這個問題貌似造成多次撥打該行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(); 
    } 
+0

完美!非常感謝,解決了這個問題! – Unkown13

相關問題