none
Reading Input Data From Joystick in visual basic RRS feed

  • Question

  • Hi all;

    i'm new at programming in visual basic. i have project that controlling a machine at 3-axis with a joystick hence i have to read input data of joystick in vb. 

    how could i make this reading data event ?

    could somebody tell me simply  how i can do this?

    Friday, May 10, 2013 4:39 PM

Answers

  • Imports System.Runtime.InteropServices
    
    Public Class Form1
    
      Declare Function joyGetPosEx Lib "winmm.dll" (ByVal uJoyID As Integer, ByRef pji As JOYINFOEX) As Integer
    
      <StructLayout(LayoutKind.Sequential)> _
      Public Structure JOYINFOEX
        Public dwSize As Integer
        Public dwFlags As Integer
        Public dwXpos As Integer
        Public dwYpos As Integer
        Public dwZpos As Integer
        Public dwRpos As Integer
        Public dwUpos As Integer
        Public dwVpos As Integer
        Public dwButtons As Integer
        Public dwButtonNumber As Integer
        Public dwPOV As Integer
        Public dwReserved1 As Integer
        Public dwReserved2 As Integer
      End Structure
    
      Dim myjoyEX As JOYINFOEX
    
      Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    
        ' Get the joystick information
        Call joyGetPosEx(0, myjoyEX)
    
        With myjoyEX
          Label10.Text = .dwXpos.ToString          'Up to six axis supported
          Label11.Text = .dwYpos.ToString
          Label12.Text = .dwZpos.ToString
          Label13.Text = .dwRpos.ToString
          Label14.Text = .dwUpos.ToString
          Label15.Text = .dwVpos.ToString
          Label16.Text = .dwButtons.ToString("X")  'Print in Hex, so can see the individual bits associated with the buttons
          Label17.Text = .dwButtonNumber.ToString  'number of buttons pressed at the same time
          Label18.Text = (.dwPOV / 100).ToString     'POV hat (in 1/100ths of degrees, so divided by 100 to give degrees)
        End With
      End Sub
    
      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        myjoyEX.dwSize = 64
        myjoyEX.dwFlags = &HFF ' All information
        Timer1.Interval = 200  'Update at 5 hz
        Timer1.Start()
      End Sub
    End Class

    This code is very useful. It detects all buttons and axises.

    • Proposed as answer by Mr. Monkeyboy Monday, May 13, 2013 2:18 PM
    • Marked as answer by Schumie Monday, May 13, 2013 3:58 PM
    Monday, May 13, 2013 12:32 PM

All replies

  • Example here - http://settorezero.blogspot.com/2010/11/using-joysticks-from-vbnet.html

    Please post back if this helps so others may know.

    Saturday, May 11, 2013 4:43 AM
  • This is supposed to do it but it reads my joysticks collective as the third axis rather than my twist. Using a USB connected Logitech Extreme 3D Pro.

    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        Public Declare Function joyGetPos Lib "winmm.dll" Alias "joyGetPos" (ByVal uJoyID As Integer, <MarshalAs(UnmanagedType.Struct)> ByRef pji As JOYINFO) As Integer
    
        <StructLayout(LayoutKind.Sequential)> _
            Public Structure JOYINFO
            Dim dwXpos As Integer
            Dim dwYpos As Integer
            Dim dwZpos As Integer
        End Structure
    
        Dim joypos1 As JOYINFO
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Timer1.Interval = 1
            Timer1.Start()
        End Sub
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            joyGetPos(0, joypos1) '0 is the joystick id
            Label1.Text = CStr("Left Right = " & joypos1.dwXpos & "    Forward Back = " & joypos1.dwYpos & "     Collective = " & joypos1.dwZpos)
        End Sub
    
    End Class


    You've taught me everything I know but not everything you know.

    Saturday, May 11, 2013 9:56 PM
  • Thank you Mr. monkeyboy  

    It works really good for 2 axis(x, y) but as you said 3rd axis is missing.

    If i could read the 3rd axis , it would be excellent.

    I'll try to figure this out.


    Sunday, May 12, 2013 11:00 AM
  • There's another Pinvoke called JoyGetPosEX that is supposed to work on more than 3 axis joysticks but I couldn't get it to work and nowhere on the Net could I find where anybody got it to work. So I wouldn't bother with it if you find it.

    You've taught me everything I know but not everything you know.

    Sunday, May 12, 2013 3:48 PM
  • if i find a solution about it , i'll share that 

    until then i'm waitng for your help 


    • Edited by Schumie Sunday, May 12, 2013 11:38 PM
    Sunday, May 12, 2013 10:28 PM
  • if i find a solution about it , i'll share that 

    until then i'm waitng for your help 


    I'm onto something now using these four functions but it will take me another day or two to figure it all out because the documentation is so poor for all of it.

    <DllImport("User32.dll")> _
        Private Shared Function GetRawInputDeviceList(ByVal pRawInputDeviceList As IntPtr, ByRef uiNumDevices As UInteger, ByVal cbSize As UInteger) As UInteger
        End Function
    
        <DllImport("User32.dll")> _
        Private Shared Function GetRawInputDeviceInfo(ByVal hDevice As IntPtr, ByVal uiCommand As UInteger, ByVal pData As IntPtr, ByRef pcbSize As UInteger) As UInteger
        End Function
    
        <DllImport("User32.dll")> _
        Private Shared Function RegisterRawInputDevices(ByVal pRawInputDevice As RAWINPUTDEVICE(), ByVal uiNumDevices As UInteger, ByVal cbSize As UInteger) As Boolean
        End Function
    
        <DllImport("User32.dll")> _
        Private Shared Function GetRawInputData(ByVal hRawInput As IntPtr, ByVal uiCommand As UInteger, ByVal pData As IntPtr, ByRef pcbSize As UInteger, ByVal cbSizeHeader As UInteger) As UInteger
        End Function

    See the Image below and now I'm just trying to figure out how to "Register" it then start getting its "RawInputData". So it's going to take me a bit.


    You've taught me everything I know but not everything you know.



    Monday, May 13, 2013 5:41 AM
  • Imports System.Runtime.InteropServices
    
    Public Class Form1
    
      Declare Function joyGetPosEx Lib "winmm.dll" (ByVal uJoyID As Integer, ByRef pji As JOYINFOEX) As Integer
    
      <StructLayout(LayoutKind.Sequential)> _
      Public Structure JOYINFOEX
        Public dwSize As Integer
        Public dwFlags As Integer
        Public dwXpos As Integer
        Public dwYpos As Integer
        Public dwZpos As Integer
        Public dwRpos As Integer
        Public dwUpos As Integer
        Public dwVpos As Integer
        Public dwButtons As Integer
        Public dwButtonNumber As Integer
        Public dwPOV As Integer
        Public dwReserved1 As Integer
        Public dwReserved2 As Integer
      End Structure
    
      Dim myjoyEX As JOYINFOEX
    
      Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    
        ' Get the joystick information
        Call joyGetPosEx(0, myjoyEX)
    
        With myjoyEX
          Label10.Text = .dwXpos.ToString          'Up to six axis supported
          Label11.Text = .dwYpos.ToString
          Label12.Text = .dwZpos.ToString
          Label13.Text = .dwRpos.ToString
          Label14.Text = .dwUpos.ToString
          Label15.Text = .dwVpos.ToString
          Label16.Text = .dwButtons.ToString("X")  'Print in Hex, so can see the individual bits associated with the buttons
          Label17.Text = .dwButtonNumber.ToString  'number of buttons pressed at the same time
          Label18.Text = (.dwPOV / 100).ToString     'POV hat (in 1/100ths of degrees, so divided by 100 to give degrees)
        End With
      End Sub
    
      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        myjoyEX.dwSize = 64
        myjoyEX.dwFlags = &HFF ' All information
        Timer1.Interval = 200  'Update at 5 hz
        Timer1.Start()
      End Sub
    End Class

    This code is very useful. It detects all buttons and axises.

    • Proposed as answer by Mr. Monkeyboy Monday, May 13, 2013 2:18 PM
    • Marked as answer by Schumie Monday, May 13, 2013 3:58 PM
    Monday, May 13, 2013 12:32 PM
  • Cool. YOU got it to work. I haven't found that anywhere I've searched on the net. And I tried to get it to work but never could. I just tried your code and it works great. Thanks.

    I proposed you as the answer but you need to mark yourself as the answer.


    You've taught me everything I know but not everything you know.


    Monday, May 13, 2013 2:17 PM
  • Yippie ! !

    This is fantastic. Thanks Monkeyboy and Schumie for developing this simple but very effective code.

    I also have a Logitech Extreme 3D Pro. I set timer to 20 hertz and it does'nt miss a beat! !

    Thanks


    Leon C Stanley - - A dinky di VB'er - -

    Tuesday, May 14, 2013 3:11 AM
  • It is awesome. I added a little bit to it in this way.

    Option Strict On
    
    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        ' Mostly done by Schumie http://social.msdn.microsoft.com/profile/schumie/?ws=usercard-mini
    
        ' XP visual styles disabled in application properties
    
        Declare Function joyGetPosEx Lib "winmm.dll" (ByVal uJoyID As Integer, ByRef pji As JOYINFOEX) As Integer
    
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure JOYINFOEX
            Public dwSize As Integer
            Public dwFlags As Integer
            Public dwXpos As Integer
            Public dwYpos As Integer
            Public dwZpos As Integer
            Public dwTpos As Integer
            Public dwUpos As Integer
            Public dwVpos As Integer
            Public dwButtons As Integer
            Public dwButtonNumber As Integer
            Public dwPOV As Integer
            Public dwReserved1 As Integer
            Public dwReserved2 As Integer
        End Structure
    
        Dim Joypos1 As JOYINFOEX
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.BackColor = Color.Black
            ProgressBar1.Minimum = 0
            ProgressBar1.Maximum = 65535
            ProgressBar1.BackColor = Color.White
            ProgressBar1.ForeColor = Color.Red
            ProgressBar1.Style = ProgressBarStyle.Continuous
            ProgressBar1.Increment(1)
            ProgressBar2.Minimum = 0
            ProgressBar2.Maximum = 65535
            ProgressBar2.BackColor = Color.White
            ProgressBar2.ForeColor = Color.Turquoise
            ProgressBar2.Style = ProgressBarStyle.Continuous
            ProgressBar2.Increment(1)
            Me.Text = "JOYGETPOSEX"
            Joypos1.dwSize = 64
            Joypos1.dwFlags = &HFF ' All information
            Timer1.Interval = 1
            Timer1.Start()
        End Sub
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            Panel1.Refresh()
    
            joyGetPosEx(0, Joypos1)
    
            Label1.Text = "X = " & Joypos1.dwXpos.ToString          'Up to six axis supported
            Label2.Text = "Y = " & Joypos1.dwYpos.ToString
            Label3.Text = "Z = " & Joypos1.dwZpos.ToString
            ProgressBar1.Value = Joypos1.dwZpos
            Label4.Text = "T = " & Joypos1.dwTpos.ToString
            ProgressBar2.Value = Joypos1.dwTpos
            Label5.Text = "U = " & Joypos1.dwUpos.ToString
            Label6.Text = "V = " & Joypos1.dwVpos.ToString
            Label7.Text = "Button Number = " & Joypos1.dwButtons.ToString
            Label8.Text = "Number Of Buttons" & vbCrLf & "Pressed = " & Joypos1.dwButtonNumber.ToString  'number of buttons pressed at the same time
            Label9.Text = "Hat = " & (Joypos1.dwPOV / 100).ToString   'POV hat (in 1/100ths of degrees, so divided by 100 to give degrees)
            If Label9.Text = "Hat = 655.35" Then Label9.Text = "Hat = Centered" '655.35 is what my Hat reads when centered
            Dim Cross As Cursor
            Cross = Cursors.Cross
            Dim graphics As Graphics = Panel1.CreateGraphics()
            Dim rectangle As New Rectangle(New Point(CInt(Math.Round((Joypos1.dwXpos / 65535) * (Panel1.Width - Cross.Size.Width))), CInt(Math.Round((Joypos1.dwYpos / 65535) * (Panel1.Height - Cross.Size.Height)))), New Size(Cross.Size.Width, Cross.Size.Height))
            Cross.Draw(graphics, rectangle)
    
        End Sub
    
    End Class


    You've taught me everything I know but not everything you know.


    Tuesday, May 14, 2013 3:55 AM
  • It seems cool Monkeyboy, thank you.
    • Edited by Schumie Tuesday, May 14, 2013 10:21 AM
    Tuesday, May 14, 2013 10:20 AM
  • Dude; this is amazing code! Very short; very effective! Clean enumeration, props sir!
    Monday, September 2, 2013 3:19 AM