2017-07-07 4 views
0

Je suis actuellement en train d'apprendre C# et la première chose que j'ai essayé est de construire une application universelle, l'exécuter sur Windows 10 IoT et de contrôler un servomoteur. Mon idée est d'avoir un curseur qui contrôle la direction du servo. Pour contrôler le servo-je utiliser le plug-in NuGet Magellanic.ServoController (par Jeremy Lindsay)Contrôler un Servo par C#, Windows 10 IoT et le Magellanic.ServoController - Problèmes de CPU et comment les résoudre?

Les calculs et le mouvement sur la base du curseur fonctionne bien, la seule question que j'ai, est que quand j'exécute un mouvement du servo, ce processus prend 30% de la capacité du CPU (événement lorsque le mouvement est terminé). Cela résulte dans la situation que je peux exécuter 3 mouvements et après cela le CPU est à près de 100% et le 4ème mouvement ne sera pas exécuté correctement (comme matériel j'utilise un framboise pi 3).

Voici le code que j'utilise

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; 
    } 
} 
} 

Je pense actuelle est que certains fournisseur de code n'est pas déchargé correctement ou quelque chose comme ça.

Un grand merci d'avance pour votre aide!

PS: Voici un lien vers le code du NuGet PlugIn:

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

+0

* N'utilisez pas 'async void'! C'est seulement destiné aux événements. La méthode résultante ne peut pas être attendue et aucune exception ne peut être interceptée. Changez la signature en async Task et attendez l'appel à la méthode. –

+0

Ce qui signifie que toutes les méthodes devraient devenir 'async Task' sauf' Slider) Value_Changed' qui devrait devenir 'async void Slider_Value_Changed' –

+0

Merci beaucoup pour cet indice! J'ai corrigé comme vous l'avez suggéré - je l'ai également testé à nouveau, mais le problème avec l'utilisation du processeur est toujours là. – Unkown13

Répondre

1

Cette question ressemble causée par appel à plusieurs reprises cette ligne ServoGpioPin = pwmController.OpenPin(ServoPin); de ServoController.Connect() méthode, mais je ne sais pas quelle est la cause sous-jacente.

Il existe une solution: instancier le ServoController et appeler ServoController.Connect() qu'une seule fois au début au lieu de faire ce travail chaque fois que la méthode MoveServoToCentre(). Échantillon de code comme ceci:

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

Parfait! Merci beaucoup qui a réglé le problème! – Unkown13