锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

Java使用usb4java连接usb设备实现通信

时间:2023-01-19 08:30:00 20usb连接器2usb3连接器

java使用usb4java连接usb通信设备

  • 一、准备
    • 1.pom依赖 usb4java
    • 2.添加配置文件
    • 3.确定设备PID和VID
    • 4. 安装libusbK
    • 5.下载zadig更换设备驱动
  • 二、Java开发
    • 1. 查找USB设备
    • 2. 请打开设备并接收数据
    • 3.发送数据到USB设备
  • 三、开发注意事项
    • 1.不支持报错操作
    • 2. 报错USB无权限
    • 3.更换驱动器后
    • 4.关于usb4java
  • 最后

一、准备

1.pom依赖 usb4java

<dependency>     <groupId>org.usb4javagroupId>     <artifactId>usb4java-javaxartifactId>     <version>1.2.0version> dependency> 

2.添加配置文件

在这里插入图片描述
如上图所示,添加javax.usb.properties配置文件在resources下面,内容只有一行

javax.usb.services = org.usb4java.javax.Services 

3.确定设备PID和VID

若已知道PID和VID跳过这一步
计算机->管理->设备管理器
在通用串行总线中找到指定的USB设备

哪种设备可以通过插拔观察设备的增删来确定。

找到设备,右击->属性
在详细的菜单栏中,选择硬件ID一项

这里十六进制VID和PID就出来了

4. 安装libusbK

libusbK官网

5.下载zadig更换设备驱动

usb设备默认是windows自带驱动,这个驱动是无法开发访问的,会报告以下错误

USB error 12: Can't open device Bus 001 Device 012: ID 28e9:0289: Operation not supported or unimplemented on this platform 

需要下载zadig替换驱动程序,下面两个下载链接可以选择下载

Zadig Downloads
zadig-2.3

下载后打开zadig,在options菜单中选择list all devices 列出所有设备,选择自己的设备USB设备

选择设备后,记得用上下箭头切换后面的驱动器libusb,然后replace driver 更换设备驱动为libusb,这样才能开发使用。

二、Java开发

1. 查找USB设备

 public static void main(String[] args){ 
          UsbDevice device = findDevice(UsbHostManager.getUsbServices().getRootUsbHub(), vid, pid);
}

public UsbDevice findDevice(UsbHub hub, int vid, int pid) throws UsbException { 
        
    List<UsbDevice> list = hub.getAttachedUsbDevices();
    for (UsbDevice device:list) { 
        
      UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor();
      if (desc.idVendor() == vid && desc.idProduct() == pid) { 
        
        return device;
      }
      if (device.isUsbHub()) { 
        
        device= findDevice((UsbHub) device, vid, pid);
        if(device!=null){ 
        
          return device;
        }
      }
    }
    return null;
  }

2. 请求打开设备并接收数据

	// 初始化设备,请求获取、打开并接收数据
	public void initUseDevice(UsbDevice device){ 
        
	 if (device.getActiveUsbConfiguration().getUsbInterfaces().size() > 0) { 
        
        iface = (UsbInterface) device.getActiveUsbConfiguration().getUsbInterfaces().get(0);
      }
      if (iface != null) { 
        
        try { 
        
          if(iface.isClaimed()==false){ 
        
            iface.claim(usbInterface -> true);
          }
          connectSuccess=true;
          UsbEndpoint receivedUsbEndpoint, sendUsbEndpoint;
          sendUsbEndpoint = (UsbEndpoint) iface.getUsbEndpoints().get(0);
          // 注意管道区别,OUT输usb设备输出数据的管道
          if (!sendUsbEndpoint.getUsbEndpointDescriptor().toString().contains("OUT")) { 
        
            receivedUsbEndpoint = sendUsbEndpoint;
            sendUsbEndpoint = (UsbEndpoint) iface.getUsbEndpoints().get(1);
          } else { 
        
            receivedUsbEndpoint = (UsbEndpoint) iface.getUsbEndpoints().get(1);
          }
          //发送
          UsbPipe sendUsbPipe = sendUsbEndpoint.getUsbPipe();
          if(sendUsbPipe.isOpen()==false){ 
        
            sendUsbPipe.open();
          }
          //接收
          final UsbPipe receivedUsbPipe = receivedUsbEndpoint.getUsbPipe();
          if(receivedUsbPipe.isOpen()==false){ 
        
            receivedUsbPipe.open();
          }
          // 接收操作放到子线程实现异步回调
          new Thread(() -> { 
        
            try { 
        
              receivedMassge(receivedUsbPipe);
            } catch (Exception e) { 
        
              e.printStackTrace();
            }
          }).start();
        } catch (Exception e) { 
        
          //e.printStackTrace();
        }finally { 
        
        	// 最后一定要关闭usb设备释放资源
          iface.release();
        }
      }
   }

	// 轮询读取USB发送回来的数据
  private void receivedMassge(UsbPipe usbPipe) throws Exception { 
        
    byte[] buffer = new byte[64];
    int length;
    while (true) { 
        
      length = usbPipe.syncSubmit(buffer);
      for (int i = 0; i < length; i++) { 
        
        // do something
      }
    }
  }

3.发送数据到USB设备

	// 发送数据
  public int send(UsbPipe usbPipe,byte[] buffer) throws UsbException { 
        
    return usbPipe.syncSubmit(buffer);//阻塞
    //usbPipe.asyncSubmit(buff);//非阻塞
  }

三、开发注意事项

1.报错操作不支持

在开发过程中遇到了一个错误 USB error 12: Can’t open device Bus 001 Device 012: ID 28e9:0289: Operation not supported or unimplemented on this platform
这是在调用claim时报错的,原因是因为直接在windows原驱动上开发,使用zadig替换驱动为libusb后即可。

2. 报错USB无权限

在项目启动后,若报错Access denied (insufficient permissions),这是因为未安装libusbK,在步骤1.4中安装libusbK即可。

3.替换驱动后

替换为libusb驱动后,该设备就无法再设备管理器上找到,只能使用libusb(即我们开发方式)访问usb设备,切记!!!

4.关于usb4java

有文章说usb4java仅支持usb2.0的开发,对3.0接口容易出现插拔的bug,关于这点还未验证,不过的确usb4java是相对比较早期的开发库,而且java本身对底层设备的访问支持就不是很良好,有条件还是使用c或c++写个dll库给java使用JNA方式调用更靠谱。

最后

有兴趣的小伙伴可以扫码关注公众号【暴走的怪兽君】,常更新Java干货资讯,免费提供大量教程和工具下载。

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章