-
2021-03-05 16:54:06
我使用libusb api从java中的usb设备读取数据。我能够将数据写入设备但我无法从设备读取数据。我可以读取第一个数据组(大小:1个字节)但是当我想读取第二个数据组(大小:2个字节)时我得到超时错误(USB错误7:控制传输失败:操作超时)
我的代码就是这样;
buffer = ByteBuffer.allocateDirect(1);
//03
LibUsb.controlTransfer(handle,(byte) (LibUsb.REQUEST_TYPE_VENDOR | LibUsb.ENDPOINT_IN), (byte) 0xdb, (short) 0, (short) 0, buffer, 0);
//00 04
buffer.rewind();
buffer = ByteBuffer.allocateDirect(2);
transferred = LibUsb.controlTransfer(handle,(byte) (LibUsb.REQUEST_TYPE_VENDOR | LibUsb.ENDPOINT_IN), (byte) 0xf0, (short) 0x1c30, (short) 0, buffer, 0);
if(transferred < 0){
throw new LibUsbException("Control Transfer Failed", transferred);
}
我用C语言实现了这种数据传输,但我必须在java中实现。请帮帮我。
编辑:我正在更改超时但我的应用程序没有变化。
编辑:我可以读取1字节数据。当我想读取2字节数据时,我收到错误。
更多相关内容 -
usb4java-javax-1.3.0.tar_usb4java包_usb4java1.3.0_usb4java版本_
2021-09-29 10:00:35用于使用usb串口的jar包,版本号1.3.0 -
usb4java-javax:usb4java的javax.usb扩展
2021-05-25 02:07:23usb4java-javax 这是usb4java的扩展,并使用usb4java提供的libusb包装器作为后端来实现javax-usb。 有关更多详细信息,请访问。 -
libusb4java:usb4java使用的本机JNI库
2021-05-05 19:56:07usb4java已经包括用于以下平台的预构建库: linux-x86 linux-x86-64 linux臂 linux-aarch64 的win32-x86的 的win32-x86-64 达尔文x86-64 达尔文臂64 如果您需要在其他平台上使用该库,则可以轻松地自己编译... -
usb4java最新版1.3.0
2019-03-12 14:05:12windows下GUI开发对usb的设备的使用、监听、传输数据等等。 最近在弄usb无驱动打印,绕过驱动直接向打印机发送指令需要用到。 -
usb4java跨平台的基于 libusb1.0 开发的JavaUSB类库
2019-08-08 09:26:22usb4java跨平台的基于 libusb 1.0 开发的 Java USB 类库,通过 usb4java-javax extension 支持 javax-usb standard (JSR-80) 开发。 平台环境支持: Linux (x86 32/64 bit, ARM 32 bit) OS X (x86 32/64 ... -
usb4java-javax-1.2.0.jar
2018-06-30 21:10:01usb4java-javax-1.2.0.jar usb4java-javax-1.2.0.jar usb4java-javax-1.2.0.jar usb4java-javax-1.2.0.jar -
vstroker_for_java:使用 usb4java 读取 Vstrokers 数据
2021-06-23 11:22:17如果你在 unix 下: javac -cp '.:commons-lang3-3.2.1.jar:usb4java-1.2.0.jar:libusb4java-1.2.0-xxx*' TestVstroker.java 如果你在 windows 下: javac -cp .;commons-lang3-3.2.1.jar;usb4java-1.2.0.jar;... -
usb4java-1.3.0.rar
2020-03-12 14:48:14windows下GUI开发对usb的设备的使用、监听、传输数据等等。 最近在弄usb无驱动打印,绕过驱动直接向打印机发送指令需要用到。 -
Java使用usb4java连接usb设备实现通信
2022-04-28 16:09:18Java使用usb4java连接usb设备实现通信,全流程展示并且附带错误解决方案java使用usb4java连接usb设备实现通信
一、准备
1.pom依赖 usb4java
<dependency> <groupId>org.usb4java</groupId> <artifactId>usb4java-javax</artifactId> <version>1.2.0</version> </dependency>
2.添加配置文件
如上图,添加javax.usb.properties配置文件在resources下,内容仅一行javax.usb.services = org.usb4java.javax.Services
3.确定设备的PID和VID
若已知道PID和VID则跳过本步骤
计算机->管理->设备管理器
在通用串行总线中找到指定的USB设备
可以通过插拔观察设备的增删来确定是哪一个设备。查找到设备,右击->属性
在详细菜单一栏,选择硬件ID一项
这里十六进制的VID和PID就出来了4. 安装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,在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干货资讯,免费提供大量教程和工具下载。
-
java使用usb4java连接USB 实现数据通讯
2020-06-22 17:59:06java使用usb4java连接USB 实现数据通讯 最近公司接到一个项目,需要连接usb获取/写入数据到数显盒。 查阅了很多资料,发现可以使用usb4java 来实现,然后我就来填坑了! po代码不易,请各位小伙伴多多关注! 先上...java使用usb4java连接USB 实现数据通讯
最近公司接到一个项目,需要连接usb获取/写入数据到数显盒。 查阅了很多资料,发现可以使用usb4java 来实现,然后我就来填坑了! po代码不易,请各位小伙伴多多关注!
先上代码,代码我并没有优化,有可能有很多函数没有用到但是还写在上面,复制的时候删掉即可!只希望对大家有所帮助!
首先你的POM里需要这个 包
<dependency> <groupId>org.usb4java</groupId> <artifactId>usb4java-javax</artifactId> <version>1.2.0</version> </dependency>
其次你需要在你的项目中建立一个 javax.usb.properties 静态文件 内容就一句:
javax.usb.services = org.usb4java.javax.Services 写好保存即可。
前期准备就完成了!
创建一个java类 xxxx.java
写一个连接方法:
/** * * TODO: 连接设备 *@author Zck *@date 2020/5/20 15:48 * */ public Map<String,Object> linkDevice() throws Exception{ Map<String,Object> mainMap = new HashMap<>(); mainMap.put("code", usbConnectCSS.USB_CONNECT_TRUE.getCode()); UsbDevice device = null; //去搜索特定的设备!需要用到设备的VID PID 自己百度怎么看! if (device == null) { device = findDevice(UsbHostManager.getUsbServices() .getRootUsbHub()); } if (device == null) { mainMap.put("code", usbConnectCSS.USB_CONNECT_NOT_HAVE.getCode()); mainMap.put("msg", usbConnectCSS.USB_CONNECT_NOT_HAVE.getInfo()); System.out.println("设备未找到!"); return mainMap; } UsbConfiguration configuration = device.getActiveUsbConfiguration(); UsbInterface iface = null; if (configuration.getUsbInterfaces().size() > 0) { iface = configuration.getUsbInterface((byte) 0); } else { //未知错误 没有源码读不懂 mainMap.put("code",usbConnectCSS.USB_CONNECT_NOT_KNOW.getCode()); mainMap.put("msg", usbConnectCSS.USB_CONNECT_NOT_KNOW.getInfo()); return mainMap; } //todo:claim连接必须打开 claim 。这里 如果设备是连接状态我们把他关闭。因为我这个项目是点对点透传txt if (iface.isClaimed()){ iface.release(); } //再开启! iface.claim(new UsbInterfacePolicy() { @Override public boolean forceClaim(UsbInterface usbInterface) { return true; } }); /*CacheUtils.put("iface", iface);*/ mainMap.put("iface", iface); return mainMap; }
/** * @Description 搜索特定设备 **/ public UsbDevice findDevice(UsbHub hub) { UsbDevice device = null; List list = (List) hub.getAttachedUsbDevices(); for (int i = 0;i<list.size();i++) { device = (UsbDevice)list.get(i); UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor(); System.out.println(i+"___"+desc.idVendor()+"___"+desc.idProduct()); if (desc.idVendor() == idVendor && desc.idProduct() == idProduct) {return device;} if (device.isUsbHub()) { device = findDevice((UsbHub) device); if (device != null) return device; } } return null; }
/** * * TODO: 通讯入口 *@author Zck *@date 2020/5/21 10:29 *map参数 中包含 拼装头(类型,读写,等) data:数据主体 */ public static Map<String,Object> communicate(Map<String,Object> map){ try { /*String data = String.valueOf(map.get("data")); map.remove("data");*/ /**获取usb通讯通道*/ Map<String,Object> returnMap = new UsbUntil().useUsb(map); /**如果code不是连接成功返回错误代码*/ if (!returnMap.get("code").equals(usbConnectCSS.USB_CONNECT_TRUE.getCode())){ return returnMap; } /**连接成功,获取sendUsbPipe*/ UsbPipe sendUsbPipe = (UsbPipe)returnMap.get("sendUsbPipe"); /**校验sendUsbPipe是否为空*/ if (sendUsbPipe != null) { /**可能有多个包用list装载*/ // List<Object> list = new ArrayList<>(); /**先判断读还是写,大家可以无视这些判断,这是我自己的业务逻辑*/ if (map.get("ReadOrWrite").equals(UsbTypeConstants.WRITE.getCode())){ //时间不会超过 64字节所以不用考虑包数 if (map.get("type").equals(UsbTypeConstants.WRITE_TYPE_TIME.getCode())){ /**不为空new一个64位字节*/ byte[] buff = new byte[64]; buff[0] = (byte)0xAA; /**16进制数据 64位发送一次,这里我删除了一点我的逻辑代码。 把buff函数换成你要发送的16进制数据包就行了*/ Log.info("进入sendMassge发送数据"); sendMassge(sendUsbPipe, buff); } } } else { returnMap.put("code", usbConnectCSS.USB_CONNECT_NOT_KNOW.getCode()); returnMap.put("msg", usbConnectCSS.USB_CONNECT_NOT_KNOW.getInfo()); } return returnMap; } catch (Exception e) { CacheUtils.remove("xxxxx","routeData"); CacheUtils.remove("thisRouteDataFlag","thisRouteDataFlag"); CacheUtils.remove("xxxxxx","switchData"); CacheUtils.remove("thisSwitchDataFlag","thisSwitchDataFlag"); e.printStackTrace(); Map<String,Object> eroMap = new HashMap<>(); eroMap.put("code",usbConnectCSS.USB_CONNECT_NOT_OPEN.getCode()); eroMap.put("msg",usbConnectCSS.USB_CONNECT_NOT_OPEN.getInfo()); return eroMap; } }
public Map<String,Object> useUsb(Map<String,Object> map) throws Exception{ //连接设备 Map<String,Object> ifaceMap = new HashMap<>(); ifaceMap = linkDevice(); UsbInterface iface = (UsbInterface)ifaceMap.get("iface"); //大家可以无视判断和 map里的参数 if (!ifaceMap.get("code").equals(usbConnectCSS.USB_CONNECT_TRUE.getCode())){ return ifaceMap; } if (iface == null) { ifaceMap.put("code",usbConnectCSS.USB_CONNECT_IS_NULL.getCode()); ifaceMap.put("msg",usbConnectCSS.USB_CONNECT_IS_NULL.getInfo()); return ifaceMap; } UsbEndpoint receivedUsbEndpoint,sendUsbEndpoint; sendUsbEndpoint = (UsbEndpoint)iface.getUsbEndpoints().get(0); 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()){ sendUsbPipe.close(); sendUsbPipe.open(); } else { sendUsbPipe.open(); } //接收 final UsbPipe receivedUsbPipe = receivedUsbEndpoint.getUsbPipe(); //打开接收通道 if (!receivedUsbPipe.isOpen()){ receivedUsbPipe.open(); } Thread th= new Thread(new Runnable() { public void run() { try { //这里不需要map参数,因为业务问题所以我加入了map receivedMassge(receivedUsbPipe,map); } catch (Exception e) { e.printStackTrace(); return; } finally { receivedUsbPipe.abortAllSubmissions(); try { receivedUsbPipe.close(); }catch (Exception e){ } } } }); th.start(); if (sendUsbPipe.isOpen()){ ifaceMap.put("sendUsbPipe", sendUsbPipe); } //这里我监听了线程是否跑完了,所以 map里放了 th ifaceMap.put("th",th); return ifaceMap; }
public int syncSubmit(final byte[] data,UsbPipe usbPipe) throws UsbException { final UsbIrp irp = usbPipe.asyncSubmit(data); //这里一定要注意,若果你设置的接收时间太短了,你硬件还没反应过来通讯就结束了。建议设置为15秒。 irp.waitUntilComplete(30000); if (irp.isUsbException()) throw irp.getUsbException(); return irp.getActualLength(); }
public void receivedMassge(UsbPipe usbPipe,Map<String,Object> map) throws Exception{ //无视这个map
byte[] b = new byte[64]; int length = 0; length = syncSubmit(b,usbPipe);//返回数据的长度,我们规定的协议是64位,这里我没有写死循环来监听到底传送完了没有,因为我们的模式是我发一个数据,盒子返回给我一个数据
//这里就是硬件返回给你的数据自己进行10进制处理吧! for (int i = 0; i < length; i++) { System.out.print(Byte.toUnsignedInt(b[i])+" "); }
}
-
java使用usb4java读取usb连接的设备
2018-07-07 14:28:06但是最近在查询资料的时候,看到usb4java是写好的jar包,可以用java读取硬件设备,虽然最终不知道是什么原因一直无法读取我公司的硬件设备,但是可以查看到鼠标、键盘、手机是否连接usb。做一个参考吧。2、首先需要...1、最近在做一个java与usb通信的项目,在我原来的理解中,java是不能读取电脑底层设备信息的,所有就让人用C写一个中间程序来传递数据。但是最近在查询资料的时候,看到usb4java是写好的jar包,可以用java读取硬件设备,虽然最终不知道是什么原因一直无法读取我公司的硬件设备,但是可以查看到鼠标、键盘、手机是否连接usb。做一个参考吧。
2、首先需要查看usb连接的idVendor和idProduct;java需要根据这个来判断是哪个usb
(1)我的电脑右键--管理--设备管理器
(2)点击要查看的设备,点击详细信息,选择硬件ID;下图的idVendor=12D1;idProduct=1082的16进制数
3、代码:
(1)引入的包:
<dependency>
<groupId>org.usb4java</g -
基于usb4java实现的java下的usb通信
2019-04-02 15:53:42基于usb4java实现的java下的usb通信 项目地址:点击打开 使用java开发的好处就是跨平台,基本上java的开发的程序在linux、mac、MS上都可以运行,对应这java的那句经典名言:一次编写,到处运行。这个... -
基于usb4java的usb通讯
2019-04-02 15:48:16下载java API及lib库地址:http://usb4java.org/index.html ...内容:javax.usb.services = org.usb4java.javax.Services 目录结构如下: 3、具体代码实现如下: 1 package com.test.us... -
JAVA usb串口通讯(可用)
2018-03-13 16:53:39JAVA开发 ,usb串口接收报文 -
usb4java 访问usb接口
2014-12-26 05:57:21at org.usb4java.javax.ExceptionUtils.createPlatformException(ExceptionUtils.java:39) at org.usb4java.javax.AbstractDevice.open(AbstractDevice.java:226) at org.usb4java.javax.AbstractDevice.... -
Java访问USB设备
2021-02-28 18:00:46编者注由于需要对某usb设备获取的数值进行转发和广播,则选择最熟悉的java作为切入语言解决。历经辛苦,测试成功。JSR-80通过查看Java的标准协会在制定标准的时候是具有JSR-80的制定的。API为javax.usb。但是通过... -
在Java应用程序中访问USB设备
2021-02-27 17:23:27在本文中,研究科学家蒋清野讨论了两个项目,它们通过提供使Java应用程序可以使用USB设备的API而使这个过程变得更容易。虽然这两个项目仍然处于萌芽状态,但是它们都显示了良好的前景,并已经成为一些实用应用程序的... -
JAVA读取USB扫描枪
2015-07-15 17:23:19JAVA读取USB扫描枪 代码整洁,注释清晰, 好用 -
java调用usb并口打印机.zip
2020-07-07 17:56:28java调用并口打印机 usb并口打印 无驱打印 本地打印 -
Java自动监视usb设备,
2012-08-27 22:58:58Java自动监视usb设备,复制存储设备中指定格式文件到本地 -
基于Java的USB-HID设备通信设计与实现.pdf
2020-03-15 14:42:03基于Java的USB-HID设备通信设计与实现 针对Java语言本身没有指针的类型,使用Java语言调用API与USB—HID设备通信显得尤为困难 的问题,介绍了如何使用JNative框架实现在windows平台下访问USB—HID设备,使java开发... -
JAVA usb串口通讯
2018-08-27 17:13:15JAVA串口通讯 modbus -
JAVA USB监听器
2011-09-23 13:31:07自动监控USB设备,插上后自动复制指定类型文件到指定目录!后台运行,隐藏性能较好。