none
GamePad mit RaspberryPI auslesen(Windows Iot) RRS feed

  • Frage

  • Hallo,

    Wie die Überschrift schon sagt versuche ich das Logitech RumblePad 2 mit dem RaspberryPi auszulesen. Als Hilft hab ich mir das Robot-Kit tutorial von der Windows iot Seite genommen weil da ein Xbox 360 Controller genutzt wird. Das Gamepad zu erkennen funktioniert schon, jetzt möchte ich das HidDevice.InputReportReceived Event einbauen um die Werte auszulesen. ich bekomme aber jedesmal die Fehlermeldung: "Delegate to an instance method cannot have null 'this'."

    Mein Code:

    private async void EnumerateHidDevices()
    {
       try
       {
          string selector = HidDevice.GetDeviceSelector(0x01,0x04);
          var devices = await DeviceInformation.FindAllAsync(selector);
           if (devices.Count > 0)
           {
               HidDevice device = await HidDevice.FromIdAsync(devices.ElementAt(0).Id,FileAccessMode.ReadWrite);
               device.InputReportReceived += InputReportReceived;
               textBlock.Text = "Xbox360 controller found!";
            }
            else
            {
               textBlock.Text = "No Xbox360 controller found!";
            }
         }
         catch (Exception x)
         {
            textBlock.Text += x.Message;
         }
    }
    
    public void InputReportReceived(HidDevice sender, HidInputReportReceivedEventArgs args)
    {
       textBlock.Text += "Anderung";
    }

    Samstag, 5. September 2015 10:59

Antworten

  • Hallo,

    Versuch mal  dispatcher nicht in WorkerThread sondern UI-Thread zu initialisieren (wenn deine Form mit textBlock den Fokus bekommen hat) .

    Grüße

    • Als Antwort markiert jojo_hau Donnerstag, 17. September 2015 15:43
    Mittwoch, 16. September 2015 08:37
  • Danke für die Info,

    jetzt funktioniert der Code und ich kann die Daten vom Gamepad auswerten.

    CoreDispatcher dispatcher;
    
    public MainPage()
    {
      dispatcher = Window.Current.CoreWindow.Dispatcher;
      EnumerateHidDevices();
    }
    
    private async void EnumerateHidDevices()
    {
      try
      {
         string selector = HidDevice.GetDeviceSelector(0x01, 0x04,0x46D,0xC218);
         var devices = await DeviceInformation.FindAllAsync(selector);
         foreach (DeviceInformation d in devices)
         {
           HidDevice Gamepad = await HidDevice.FromIdAsync(d.Id, Windows.Storage.FileAccessMode.Read);
           if (Gamepad != null)
           {
              Gamepad.InputReportReceived += new TypedEventHandler<HidDevice, HidInputReportReceivedEventArgs>(InputReportReceived);
            }                
          }
       }
       catch (Exception x)
       }
          textBlock.Text += x.Message;
       }
    }
    
    public void ControllerInput(int Dpad)
    {
        listBox1.Items.Add("Dpad:" + Dpad);
    }
    
    public async void InputReportReceived(HidDevice sender, HidInputReportReceivedEventArgs args)
    {
       int dPad1 = (int)args.Report.GetNumericControl(0x01, 0x39).Value;
       await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ControllerInput(dPad1));
    }
    

    • Als Antwort markiert jojo_hau Donnerstag, 17. September 2015 15:51
    Donnerstag, 17. September 2015 15:51

Alle Antworten

  • Hallo,

    versuch mal folgendes:

    HidDevice device = await HidDevice.FromIdAsync(devices.ElementAt(0).Id,FileAccessMode.ReadWrite);
               
    if(device!=null)
    {
      device.InputReportReceived +=new TypedEventHandler<HidDevice, HidInputReportReceivedEventArgs>(this.InputReportReceived);
    }

    Grüße

    Samstag, 5. September 2015 11:25
  • Danke für die Antwort, ich hab den code getestet, jetzt gibt es zwar keine Fehlermeldung mehr aber die if Schleife wird nie ausgeführt, fehlen dem device irgendwelche werte?

    Samstag, 5. September 2015 13:04
  • Hallo,

    das (device==null)  heißt, dass die Verbindung mit dem Gerät fehlgeschlagen ist. Prüfe, ob der Treiber richtig installiert wurde. Auch kannst Du versuchen die Schnittstelle nicht in ReadWrite sondern in Read Modus zu öffnen.

    Es gibt hier ein Bespiel für HID Communication.

    Grüße

    Samstag, 5. September 2015 17:19
  • Danke für die Antwort,

    mit Read anstatt ReadWrite hab ich probiert macht aber keinen unterschied. Soweit ich weiß nutzt das teil den standard Windows HIDTreiber, weiß jemand wie man den auf dem RaspberryPI installiert bzw. ob der schon installiert ist?

    Ich hab nochmal verschiedene Sachen probiert, leider ohne Erfolg. Da ich mir auch nicht sicher war das die Adresse stimmt hab ich mir eine art Scanner gebaut der die Adressen 0x00 bis 0x0A durchprobiert, bei den zwei Adressen 0x01,0x02 und 0x01 und 0x04 findet der das Gampad aber bei beiden ist das Device = null.

    Sonntag, 6. September 2015 07:22
  • Hallo,

    hier steht, dass  Usage Page = 0x01 und Usage ID = 0x05 für Game Pad sind. 

    Es gibt ein Beispiel für HID Device List. Ich denke, dass folgende Links (das und das) für Dich auch interessant seien könnten.

    Grüße

    • Als Antwort vorgeschlagen Tobias Scholze Montag, 7. September 2015 07:58
    Sonntag, 6. September 2015 15:40
  • Danke für die Links, die haben mir echt weiter geholfen.

    Das Problem war dass das HID-Device nicht im app Mainfest deklariert war. In <Capabilities>... </Capabilities> folgenden Code Hinzugefügt:

    <DeviceCapability Name="humaninterfacedevice">
        <Device Id="any">
           <Function Type="usage:0001 0004"/>
           <Function Type="usage:0001 0005"/>
        </Device>
    </DeviceCapability>
    Damit lässt sich jetzt das Gamepad abrufen und das InputReportReceived-Event hinzufügen. Wenn ich aber die ausgelesenen Werte in einem anderen Programmteil verwenden will, kommt die Fehlermeldung: "Exception from HRESULT:0x8001010E (RPC_E_WRONG_THREAD)" Mir ist klar dass das Event in einem Parallelem Thread verarbeitet wird und dadurch der Fehler entsteht, leider weiß ich aber nicht wie ich die Daten verarbeiten muss. Kennt jemand eine gute Anleitung/Tutorial wo das gut erklärt wird?

     

    Montag, 7. September 2015 17:01
  • Hallo,

    Du kannst CoreDispatcher.Dispatcher.Invoke (InvokeAsync) Methode verwenden.
    myUIObject.Dispatcher.Invoke(..);

    Grüße
    • Bearbeitet Iso7 Samstag, 12. September 2015 21:44
    Montag, 7. September 2015 17:30
  • Danke für die Info mit dem Dispatcher, aber leider gibt es die System.Windows.Threading-API bei Windows-Runtime-Apps nicht. Gibt es dafür einen art Nachfolger für Win-Apps?

    Grüße

    Samstag, 12. September 2015 16:56
  • Hallo,

    CoreDispatcher aus Windows.UI.Core.

    Grüße

    Samstag, 12. September 2015 21:49
  • Hallo,

    Danke für die Info mit dem CoreDispatcher, leider hab ich noch nicht verstanden wie dieser Funktioniert. Mein ziel ist es die Variable Dpad in einem TextBlock anzuzeigen und in anderen Programteilen verwenden zu können.

    Hier mein Code:

    CoreDispatcher Dispatcher;
    
    public void ControllerInput(int Dpad)
    {
      textBlock.Text += Dpad;
    }
    
    public async void InputReportReceived(HidDevice sender, HidInputReportReceivedEventArgs args)
    {
      int dPad1 = (int)args.Report.GetNumericControl(0x01, 0x39).Value;
      await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ControllerInput(dPad1));
    }

    Sonntag, 13. September 2015 09:12
  • Hallo,

    Dispatcher muss noch initialisiert werden:

    Dispatcher = Window.Current.CoreWindow.Dispatcher;

    Hier gibt es kleine Beschreibung für CoreDispatcher.

    Grüße

    Sonntag, 13. September 2015 12:03
  • Danke für die Beschreibung,

    Den dispatcher hab ich jetzt auch initialisiert, leider funktioniert das Programm immer noch nicht und hängt sich auf sobald man eine Taste auf den Gamepad drückt.

    Ein Problem war auf jeden fall dass die name "Dispatcher" schon im Kontext vorhanden ist, leider funktioniert es trotzdem nicht. Hier nochmal der Code:

    CoreDispatcher dispatcher;
    
    public void ControllerInput(int Dpad)
    {
      textBlock.Text += Dpad;
    }
    
    public async void InputReportReceived(HidDevice sender, HidInputReportReceivedEventArgs args)
    {
      dispatcher = Window.Current.CoreWindow.Dispatcher; 
      int dPad1 = (int)args.Report.GetNumericControl(0x01, 0x39).Value;
      await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ControllerInput(dPad1));
    }

    Dienstag, 15. September 2015 17:41
  • Hallo,

    Versuch mal  dispatcher nicht in WorkerThread sondern UI-Thread zu initialisieren (wenn deine Form mit textBlock den Fokus bekommen hat) .

    Grüße

    • Als Antwort markiert jojo_hau Donnerstag, 17. September 2015 15:43
    Mittwoch, 16. September 2015 08:37
  • Danke für die Info,

    jetzt funktioniert der Code und ich kann die Daten vom Gamepad auswerten.

    CoreDispatcher dispatcher;
    
    public MainPage()
    {
      dispatcher = Window.Current.CoreWindow.Dispatcher;
      EnumerateHidDevices();
    }
    
    private async void EnumerateHidDevices()
    {
      try
      {
         string selector = HidDevice.GetDeviceSelector(0x01, 0x04,0x46D,0xC218);
         var devices = await DeviceInformation.FindAllAsync(selector);
         foreach (DeviceInformation d in devices)
         {
           HidDevice Gamepad = await HidDevice.FromIdAsync(d.Id, Windows.Storage.FileAccessMode.Read);
           if (Gamepad != null)
           {
              Gamepad.InputReportReceived += new TypedEventHandler<HidDevice, HidInputReportReceivedEventArgs>(InputReportReceived);
            }                
          }
       }
       catch (Exception x)
       }
          textBlock.Text += x.Message;
       }
    }
    
    public void ControllerInput(int Dpad)
    {
        listBox1.Items.Add("Dpad:" + Dpad);
    }
    
    public async void InputReportReceived(HidDevice sender, HidInputReportReceivedEventArgs args)
    {
       int dPad1 = (int)args.Report.GetNumericControl(0x01, 0x39).Value;
       await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ControllerInput(dPad1));
    }
    

    • Als Antwort markiert jojo_hau Donnerstag, 17. September 2015 15:51
    Donnerstag, 17. September 2015 15:51