B4J Question How to get data from HID device?

Discussion in 'B4J Questions' started by bjfhs, Jan 4, 2019.

  1. bjfhs

    bjfhs Active Member Licensed User

    Code:
    #AdditionalJar: purejavahidapi
    #AdditionalJar: jna-4.0.0

       
    Dim hdi As JavaObject
        hdi.InitializeStatic(
    "purejavahidapi.HidDeviceInfo")
        
    'initial PureJavaHidApi
        Dim jo As JavaObject
        jo.InitializeStatic(
    "purejavahidapi.PureJavaHidApi")
        
    'list all usb hid
        Dim lst As List
        lst = jo.RunMethodJO(
    "enumerateDevices"Null)
        
    'open usb hid
        Dim obj As JavaObject
        obj.InitializeStatic(
    "purejavahidapi.HidDeviceInfo")
        
    Dim tmp As Boolean
        
    Dim PD As Long ,VD As Long
        tmp=
    False
        
    For i=0 To lst.Size-1
            
    Log("lst:" & lst.Get(i))
            
    'ListView1.Items.Add("lst:"  & lst.Get(i))
            obj = lst.Get(i)
            PD=obj.RunMethod(
    "getProductId",Null)
            VD=obj.RunMethod(
    "getVendorId",Null)
            
    If  PD=0x1001 And VD=0x6816 Then
               tmp=
    True
               
    Exit
            
    End If
          
        
    Next
        
    If tmp=False Then
            fx.Msgbox(MainForm, 
    "没有发现设备!""警告")
            
    Return
        
    End If
      
        
    Dim getPath As String
        getPath = obj.RunMethod(
    "getPath",Null)
        getPath=getPath.Trim
        
    Log(getPath)
        
    Dim hd As JavaObject
        hd.InitializeStatic(
    "purejavahidapi.HidDevice")
        hd = jo.RunMethod(
    "openDevice",  Array As String(getPath))
    log:
    Code:
    Waiting for debugger to connect...
    Program started.
    lst:purejavahidapi.windows.HidDeviceInfo@10c98a4
    lst:purejavahidapi.windows.HidDeviceInfo@1f3046d
    lst:purejavahidapi.windows.HidDeviceInfo@936f4f
    \\?\hid
    #vid_6816&pid_1001#7&5dc41fe&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
    Error occurred on line: 
    59 (Main)
    java.lang.RuntimeException: Method: openDevice 
    not matched.
        at anywheresoftware.b4j.object.JavaObject.RunMethod(
    JavaObject.java:129)
        at b4j.example.main._appstart(main.java:
    200)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
    62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
    43)
        at java.lang.reflect.Method.invoke(Method.java:
    498)
        at anywheresoftware.b4a.shell.Shell.runMethod(
    Shell.java:625)
        at anywheresoftware.b4a.shell.Shell.raiseEventImpl(
    Shell.java:237)
        at anywheresoftware.b4a.shell.Shell.raiseEvent(
    Shell.java:168)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
    62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
    43)
        at java.lang.reflect.Method.invoke(Method.java:
    498)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    90)
        at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:
    94)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    77)
        at b4j.example.main.start(main.java:
    38)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$
    162(LauncherImpl.java:863)
        at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$
    175(PlatformImpl.java:326)
        at com.sun.javafx.application.PlatformImpl.lambda$
    null$173(PlatformImpl.java:295)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$
    174(PlatformImpl.java:294)
        at com.sun.glass.ui.InvokeLaterDispatcher$
    Future.run(InvokeLaterDispatcher.java:95)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$
    null$148(WinApplication.java:191)
        at java.lang.Thread.run(
    Thread.java:745)
    some about purejavahidapi
    https://github.com/nyholku/purejavahidapi/commit/4388fde3328ef5e8eb7d13ef82c91a79741f0b0a
     
    Last edited: Jan 4, 2019
  2. Daestrum

    Daestrum Well-Known Member Licensed User

    Looking at the source code openDevice wants a HidDeviceInfo passed to it, have you tried just passing your obj variable to it, as that is a HidDeviceInfo variable?
     
  3. bjfhs

    bjfhs Active Member Licensed User

    Yes, I have tried it, but I got a error.
    hd = jo.RunMethod("openDevice", obj)
     
  4. Daestrum

    Daestrum Well-Known Member Licensed User

    Think it would be
    Array(obj) in the RunMethod
     
    bjfhs likes this.
  5. bjfhs

    bjfhs Active Member Licensed User

    Thank you very much,you are right.
    But the next
    Code:
    Dim data(132As Byte    '65 and 132 are test
    Dim ival As Int
    ival = hd.RunMethod(
    "getFeatureReport"Array As Object( data, data.Length ))
    I can't get any data,ival always is -1
     
  6. Daestrum

    Daestrum Well-Known Member Licensed User

    *** just realized the buffer is 132 bytes and the first byte must be 1
    Code:
    Dim data(132As Byte     '65 and 132 are test
    data(0) = 1
    Dim ival As Int
    ival = hd.RunMethod(
    "getFeatureReport"Array As Object( data, data.Length ))
     
    Last edited: Jan 5, 2019
  7. bjfhs

    bjfhs Active Member Licensed User

    Dim data() As Byte = 132 ,can't use in B4J, Array expected.
     
  8. Daestrum

    Daestrum Well-Known Member Licensed User

    ** see my edited post #6

    If the value of ival >= 0 then the call worked and the data buffer will contain int's that contain the information.
     
  9. bjfhs

    bjfhs Active Member Licensed User

    Thank Daestrum, you are great.
    All My code,ival always is -1.
    Code:
    #AdditionalJar: purejavahidapi
    #AdditionalJar: jna-4.0.0
    Sub Process_Globals
        
    Private fx As JFX
        
    Private MainForm As Form
        
    Private Button1 As Button
        
    Private Button2 As Button
        
    Private Button3 As Button
        
    Dim hd As JavaObject
        
    Dim zx As Boolean    '设备是否在线
        Private Timer1 As Timer
        
    Private Label1 As Label
    End Sub
    Sub AppStart (Form1 As Form, Args() As String)
        MainForm = Form1
        MainForm.RootPane.LoadLayout(
    "main"'Load the layout file.
        MainForm.Show
        setAlwaysOnTop(MainForm, 
    True)
        
    '''''''''''''''''''''''''''''''''''''''''''''''
        Dim hdi As JavaObject
        hdi.InitializeStatic(
    "purejavahidapi.HidDeviceInfo")
        
    'initial PureJavaHidApi
        Dim jo As JavaObject
        jo.InitializeStatic(
    "purejavahidapi.PureJavaHidApi")
        
    'list all usb hid
        Dim lst As List
        lst = jo.RunMethodJO(
    "enumerateDevices"Null)
        
    'open usb hid
        Dim obj As JavaObject
        obj.InitializeStatic(
    "purejavahidapi.HidDeviceInfo")
     
        
    Dim PD As Long ,VD As Long
        zx=
    False
        
    For i=0 To lst.Size-1
            
    Log("lst:" & lst.Get(i))
            
    'ListView1.Items.Add("lst:"  & lst.Get(i))
            obj = lst.Get(i)
            PD=obj.RunMethod(
    "getProductId",Null)
            VD=obj.RunMethod(
    "getVendorId",Null)
            
    If  PD=0x1001 And VD=0x6816 Then
               zx=
    True
               
    Exit
            
    End If
        
        
    Next
        
    If zx=False Then
            fx.Msgbox(MainForm, 
    "No device!""Error")
            
    Return
        
    End If
     
        
    Dim getPath As String
        getPath = obj.RunMethod(
    "getPath",Null)
        getPath=getPath.Trim
        
    Log(getPath)
     
        hd.InitializeStatic(
    "purejavahidapi.HidDevice")
        hd = jo.RunMethod(
    "openDevice",  Array(obj))
        Timer1.Initialize(
    "Timer1"200)
        
    If zx Then Timer1.Enabled=True
    End Sub
    'Return true to allow the default exceptions handler to handle the uncaught exception.
    Sub Application_Error (Error As Exception, StackTrace As StringAs Boolean
        
    Return True
    End Sub
    Sub MainForm_CloseRequest (EventData As Event)
        Timer1.Enabled=
    False
        
    If zx Then
        
    Dim hdCl As JavaObject
        hdCl.InitializeStatic(
    "purejavahidapi.HidDevice")
        hdCl = hd.RunMethod(
    "close",Null)
        
    End If
    End Sub
    Sub Timer1_Tick
        
    Dim data(132As Byte
        
    For i=0 To 63
            data(i)=
    0xFF
        
    Next
        data(
    0)=1
            
    If zx Then
            
    Dim ival As Int
            ival = hd.RunMethod(
    "getFeatureReport"Array As Object( data, data.Length ))
            Label1.Text=ival
            
    If ival>0 Then
                
    Dim tmpp As String
                
    For i=0 To 63'ival-1
                    tmpp=tmpp & data(i)
                
    Next
                Label1.Text=tmpp
    '            fx.Msgbox(MainForm,tmpp,"fg")
            End If
        
    End If
    End Sub
    Sub setAlwaysOnTop(frm As Object, Value As Boolean)
        
    Dim frmJO As JavaObject = frm
        
    Dim stage As JavaObject = frmJO.GetField("stage")
        stage.RunMethod(
    "setAlwaysOnTop"Array(Value))
    End Sub
     
    Last edited: Jan 5, 2019
  10. Daestrum

    Daestrum Well-Known Member Licensed User

    Does it return the information now?
     
  11. bjfhs

    bjfhs Active Member Licensed User

  12. Christian García S.

    Christian García S. Active Member Licensed User

    Hi @bjfhs,

    I am trying to implement a project with similiar Keypad.

    I tried with your code and I receive -1.

    You were able to receive the data from the HID device ??

    Thanks
     
  13. bjfhs

    bjfhs Active Member Licensed User

    Yes,I can do it with Daestrum's help.
    Code:
    #Region Project Attributes 
     
    #MainFormWidth: 600
     
    #MainFormHeight: 600 
     
    #AdditionalJar: purejavahidapi
     
    #AdditionalJar: jna-4.2.1
    #End Region

    Sub Process_Globals
     
    Private fx As JFX
     
    Private MainForm As Form
     
    Private Button1 As Button
     
    Private Button2 As Button
     
    Private Button3 As Button
     
    Dim lst As List
     
    Dim tb1 As TableView
     
    Dim currentDeviceInfo As JavaObject
     
    Dim currentDevice As JavaObject
    End Sub
    Sub AppStart (Form1 As Form, Args() As String)
     MainForm = Form1
     
    'MainForm.RootPane.LoadLayout("main") 'Load the layout file.
     MainForm.Show
     tb1.Initialize(
    "devices")
     tb1.SetColumns(
    Array("VendorID","ProductID"))
     tb1.SetColumnWidth(
    0,200)
     tb1.SetColumnWidth(
    1,190)
     lst.Initialize
     Button1.Initialize(
    "openDevice")
     Button1.Text=
    "open selected device"
     Button2.Initialize(
    "readDeviceFeatures")
     Button2.Text = 
    "read selected device features"
     Button3.Initialize(
    "closeDevice")
     Button3.Text = 
    "close selected device"
     MainForm.RootPane.AddNode(tb1,
    10,10,400,400)
     MainForm.RootPane.AddNode(Button1,
    10,500,400,20)
     MainForm.RootPane.AddNode(Button2,
    10,530,400,20)
     MainForm.RootPane.AddNode(Button3,
    10,560,400,20)
     setAlwaysOnTop(MainForm, 
    True)
     asJO(Me).RunMethod(
    "getDeviceList",Array(lst))
     
    For Each item As Object In lst
      
    Dim vendor As Short = asJO(Me).RunMethod("getVendorId",Array(item))
      
    Dim product As Short = asJO(Me).RunMethod("getProductId",Array(item))
      tb1.Items.Add(
    Array(vendor,product))
     
    Next
    End Sub
    Sub asJO(o As JavaObjectAs JavaObject
     
    Return o
    End Sub
    Sub devices_SelectedRowChanged(Index As Int, Row() As Object)
     
    Log("item selected : "&lst.Get(Index))
     currentDeviceInfo = lst.Get(Index)
    ' lst contains real item tableview just to show vendor etc
     'Log(GetType(currentDeviceInfo))
    End Sub
    Sub openDevice_Click
     currentDevice = asJO(Me).RunMethod(
    "openDevice",Array(currentDeviceInfo))
     
    'Log(currentDevice)
    End Sub
    Sub readDeviceFeatures_Click
     
    Dim data() As Byte = asJO(Me).RunMethod("getFeatureReport",Array(currentDevice))
     
    Dim sb As StringBuilder
     sb.Initialize
     
    For Each b As Byte In data
      sb.Append(b&
    " ")
     
    Next
     
    Log(sb.ToString.Trim)
    End Sub
    Sub closeDevice_Click
     asJO(Me).RunMethod(
    "closeDevice",Array(currentDevice))
    End Sub
    'Return true to allow the default exceptions handler to handle the uncaught exception.
    Sub Application_Error (Error As Exception, StackTrace As StringAs Boolean
     
    Return True
    End Sub
    Sub setAlwaysOnTop(frm As Object, Value As Boolean)
     
    Dim frmJO As JavaObject = frm
     
    Dim stage As JavaObject = frmJO.GetField("stage")
     stage.RunMethod(
    "setAlwaysOnTop"Array(Value))
    End Sub
    #if java
    import java.util.List;
    import purejavahidapi.*;
    import java.io.*;
    volatile static boolean deviceOpen = false;
    public static List getDeviceList(List lst) {
     lst.clear();
     try {
      HidDeviceInfo devInfo = null;
      if (!deviceOpen) {
       System.out.println("scanning");
       List<HidDeviceInfo> devList = PureJavaHidApi.enumerateDevices();
       for (HidDeviceInfo info : devList) {
        System.out.println(info.getVendorId());
        System.out.println(info.getProductId());
        lst.add(info);
       }
      } 
     } catch (Throwable e) {
      e.printStackTrace();
     }
     return lst;
    }
    public static Short getVendorId(HidDeviceInfo hid){
     return hid.getVendorId();
    }
    public static Short getProductId(HidDeviceInfo hid){
     return hid.getProductId();
    }
    public static HidDevice openDevice(HidDeviceInfo devInfo) throws IOException{
     final HidDevice dev;
     if (devInfo == null) {
      System.out.println("device not found");
      dev = null;
     } else {
      System.out.println("device found");
      if (true) {
       deviceOpen = true;
       dev = PureJavaHidApi.openDevice(devInfo);
       dev.setDeviceRemovalListener(new DeviceRemovalListener() {
        @Override
        public void onDeviceRemoval(HidDevice source) {
            System.out.println("device removed");
         deviceOpen = false;
        }
       });
       dev.setInputReportListener(new InputReportListener() {
        @Override
        public void onInputReport(HidDevice source, byte Id, byte[] data, int len) {
         System.out.printf("onInputReport: id %d len %d data ", Id, len);
          for (int i = 0; i < len; i++)
           System.out.printf("%02X ", data[i]);
           System.out.println();
        }
       });
      } 
     }
     return dev; 
    }
    public static void closeDevice(HidDevice hid){
     if (!deviceOpen) return;
     hid.close();
     deviceOpen = false;
    }
    public static byte[] getFeatureReport(HidDevice dev){
     byte[] data = new byte[132];
     data[0] = (byte)1;
     int len = 0;
     if (((len = dev.getFeatureReport(data, data.length)) >= 0) && true) {
      int Id = data[0];
      System.out.printf("getFeatureReport: id %d len %d data ", Id, len);
      for (int i = 0; i < data.length; i++)
       System.out.printf("%02X ", data[i]);
      System.out.println();
     }
     return data;
    }
    #End If
     
  14. Christian García S.

    Christian García S. Active Member Licensed User

    Thanks @bjfhs,

    But when I run the B4J program the device is not listed, do you think I need a special driver ??

    The device is:

    USB\VID_03EB&PID_5500&REV_1000

    in USB Input Device
     

    Attached Files:

  15. Christian García S.

    Christian García S. Active Member Licensed User

    I had to execute a program that looks for the missing drivers, after executing that program and installing the missing drivers it is now recognized.

    Thanks for your help
     
  16. bjfhs

    bjfhs Active Member Licensed User

    My code is used for human interface device(HID),if your device is not a HID,you can not use it, you need special driver.
     
  17. Christian García S.

    Christian García S. Active Member Licensed User

    Thanks @bjfhs, now I can get data from device, the issue was that missing a driver.

    I can see the data when I click in buttons, but I don't know how put the values in to a B4J variable , can you help me with this?

    Code:
    dev.setInputReportListener(new InputReportListener() {
        @Override
        
    public void onInputReport(HidDevice source, byte Id, byte[] data, int len) {
         System.out.printf(
    "onInputReport: id %d len %d data "Id, len);
          
    for (int i = 0; i < len; i++)
           System.out.printf(
    "%02X ", data[i]);
           System.out.println();
        
    }
    Thanks
     
  18. bjfhs

    bjfhs Active Member Licensed User

    You can raise a event from it. and then get data from B4J.(ba.raiseEventFromUI)
     
    Last edited: Jan 31, 2019
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice