【Qt】使用libusb和hidapi实现hid通信
来源:互联网 发布:数据库安装教程 编辑:程序博客网 时间:2024/06/08 03:49
使用libusb可以实现通用的usb通信,但是实现较为复杂,可以使用hidapi来封装一层,通过hidapi调用libusb。
具体流程如下:
1、编译libusb
下载地址:https://sourceforge.net/projects/libusb/files/libusb-1.0/
编译时,要加 --disable-udev参数,我们不使用这个lib
若是给本机使用:
若是交叉编译给arm开发板用
2、复制lib到系统lib环境中
3、使用hidapi
下载地址:https://github.com/signal11/hidapi/downloads,下载0.7版本
解压之后会发现里面有很多文件夹,例如hidapi, hidtest, linux, windows,其中hidapi是共用部分,linux下面有makefile,可以编译出linux下可以使用的hid读写的hidtest程式,读写的对象是vid为0x04d8,pid为0x003f。
编译demo需要修改makefile以支持我们编译的libusb路径查找。
修改内容如下:
然后make & make install
如果使用Qt,则复制3个文件,添加到工程中,hidapi文件夹下的hidapi.h,这个主要是结构体的封装,linux下的hid-libusb.c,这个主要是一些主体调用函数,hidtest中的hidtest.cpp,这个主要是测试的demo,可以直接修改自己使用,当然,不修改也可以使用demo。
编译是需要用到libusb,所以要在.pro文件中添加对应的头文件目录和lib目录,在最后面新增两行如下:
以下为C语言写法
修改hidtest.c为MainHidInterface.c和MainHidInterface.h
具体流程如下:
1、编译libusb
下载地址:https://sourceforge.net/projects/libusb/files/libusb-1.0/
编译时,要加 --disable-udev参数,我们不使用这个lib
若是给本机使用:
./configure --prefix=/opt/libusb1.0 --disable-udevmakemake install
若是交叉编译给arm开发板用
./configure --build=i686-linux --host=arm-linux --prefix=·pwd·/install CC=arm-linux-gcc CXX=arm-linux-g++ --disable-udevmakemake install
2、复制lib到系统lib环境中
cp /opt/libusb1.0/lib/libusb-1.0.so* /usr/lib
3、使用hidapi
下载地址:https://github.com/signal11/hidapi/downloads,下载0.7版本
解压之后会发现里面有很多文件夹,例如hidapi, hidtest, linux, windows,其中hidapi是共用部分,linux下面有makefile,可以编译出linux下可以使用的hid读写的hidtest程式,读写的对象是vid为0x04d8,pid为0x003f。
编译demo需要修改makefile以支持我们编译的libusb路径查找。
修改内容如下:
#LIBS = '`pkg-config libusb-1.0 libudev --libs`'LIBS = -L"/usr/lib/x86_64-linux-gnu" -lusb-1.0 -lpthread#INCLUDES ?= -I../hidapi `pkg-config libusb-1.0 --cflags`INCLUDES ?= -I../hidapi -I/opt/libusb1.0/include/libusb-1.0
然后make & make install
如果使用Qt,则复制3个文件,添加到工程中,hidapi文件夹下的hidapi.h,这个主要是结构体的封装,linux下的hid-libusb.c,这个主要是一些主体调用函数,hidtest中的hidtest.cpp,这个主要是测试的demo,可以直接修改自己使用,当然,不修改也可以使用demo。
编译是需要用到libusb,所以要在.pro文件中添加对应的头文件目录和lib目录,在最后面新增两行如下:
INCLUDEPATH += /opt/libusb1.0/include/libusb-1.0LIBS += -L"/usr/lib/x86_64-linux-gnu" -lusb-1.0
以下为C语言写法
修改hidtest.c为MainHidInterface.c和MainHidInterface.h
使用pthread来支持多线程读写,采用回调函数来返回读到的数据。
MainHidInterface.h
#ifndef DeltaHIDINTERFACE_H#define DeltaHIDINTERFACE_H#include <stdio.h>#include <wchar.h>#include <string.h>#include <stdlib.h>#include "hidapi.h"// Headers needed for sleeping.#include <unistd.h>#define hidDataLength 64//hid data receive callback functiontypedef void (*DataArriveCallBackFunc)(unsigned char *recData,unsigned char length);DataArriveCallBackFunc hidDataArriveCallBack;hid_device *handle;unsigned char isOpen;int hidApi_Init(DataArriveCallBackFunc DataArriveCallBack);int hidApi_Write(unsigned char *data, unsigned char length);//when data arrived, the function will be calledvoid hidApi_DataReceive(unsigned char *recData,unsigned char length);int hidApi_Close(void);#endif // HIDINTERFACE_H
MainHidInterface.c
#include "hidinterface.h"#include <pthread.h>void hidRead_thread(void);int hidApi_Init(DataArriveCallBackFunc DataArriveCallBack){ hidDataArriveCallBack = NULL; // Open the device using the VID, PID, // and optionally the Serial number. ////handle = hid_open(0x4d8, 0x3f, L"12345"); handle = hid_open(0x4d8, 0x3f, NULL); if (!handle) { printf("unable to open device\n"); isOpen = 0; return -1; } printf("open device success\n"); isOpen = 1; hidDataArriveCallBack = DataArriveCallBack; hidRead_thread(); // Set the hid_read() function to be non-blocking. hid_set_nonblocking(handle, 1); return 0;}int hidApi_Write(unsigned char *data, unsigned char length){ int res; unsigned char realData[length+1]; realData[0]=length; int i; for(i=0;i<length;i++) { realData[i+1]=data[i]; } res = hid_write(handle, realData, length+1); if (res < 0) { printf("Unable to write()\n"); printf("Error: %ls\n", hid_error(handle)); return -1; } printf("write success\n"); return 0;}void hidApi_DataReceive(unsigned char *recData,unsigned char length){ if(hidDataArriveCallBack==NULL) return; hidDataArriveCallBack(recData,length);}void hidApi_Read(){ unsigned char recData[hidDataLength]; int res; while (isOpen==1) { res = hid_read(handle, recData, hidDataLength); if (res == 0) ;//printf("waiting...\n"); else if (res < 0) { printf("Unable to read()\n"); return -1; } else { int i;// printf("Data read:\n ");// // Print out the returned buffer.//// for (i = 0; i < res; i++)// printf("%02hhx ", recData[i]);// printf("\n"); unsigned char length = recData[0]; unsigned char datas[length]; for(i=0;i<length;i++) { datas[i]=recData[i+1]; } hidApi_DataReceive(datas,length); } usleep(50*1000); }}void hidRead_thread(void){ pthread_t id; int ret, i; ret=pthread_create(&id,NULL,(void *) hidApi_Read,NULL); // 成功返回0,错误返回错误编号 if(ret!=0) { printf ("Create pthread error!\n"); exit (1); } //pthread_join(id,NULL); printf ("Create pthread success!\n");}int hidApi_Close(void){ hid_close(handle); isOpen = 0; /* Free static HIDAPI objects. */ hid_exit(); return 0;}
若想使用Qt C++,则要将pthread换成QThread来执行阅读,同时,不要再使用回调函数,因为回调函数不支持成员函数(含有默认指针this),仅支持static函数,不利于使用多个对象实例,可以使用信号与槽的机制将接收到的数据传输出来。
以下为Qt C++改写的范例,使用时要connect才能接收到数据。
MainHidInterface.h
MainHidInterface.cpp
MainHidInterface.h
#ifndef mMainHIDINTERFACE_H#define mMainHIDINTERFACE_H#include <iostream>#include <QThread>#include <QCoreApplication>#include "hidapi.h"// Headers needed for sleeping.#include <unistd.h>using namespace std;#define hidDataLength 64//typedef void (*DataRecCallbackFunc)(unsigned char *recData,unsigned char length);class MainHidInterFace : public QThread{ Q_OBJECTpublic: //Initial and set hid data receive callback function MainHidInterFace(); int hidApi_Write(unsigned char *data, unsigned char length); int hidApi_Close(void);signals: void hidDataArrived(unsigned char *data, unsigned char length);private: hid_device *handle; unsigned char isOpen;protected: void run() ;};#endif // HIDINTERFACE_H
MainHidInterface.cpp
/******************************************************* Windows HID simplification Alan Ott Signal 11 Software 8/22/2009 Copyright 2009, All Rights Reserved. This contents of this file may be used by anyone for any reason without any conditions and may be used as a starting point for your own applications which use HIDAPI.********************************************************/#include "hidinterface.h"MainHidInterFace::MainHidInterFace(){ // Open the device using the VID, PID, // and optionally the Serial number. ////handle = hid_open(0x4d8, 0x3f, L"12345"); handle = hid_open(0x4d8, 0x3f, NULL); if (!handle) { printf("unable to open device\n"); isOpen = 0; return; } printf("open device success\n"); isOpen = 1; // Set the hid_read() function to be non-blocking. hid_set_nonblocking(handle, 1); emit hidDataArrived(NULL,0); return;}int MainHidInterFace::hidApi_Write(unsigned char *data, unsigned char length){ int res; unsigned char realData[length+1]; realData[0]=length; int i; for(i=0;i<length;i++) { realData[i+1]=data[i]; } res = hid_write(handle, realData, length+1); if (res < 0) { printf("Unable to write()\n"); printf("Error: %ls\n", hid_error(handle)); return -1; } printf("write success\n"); return 0;}void MainHidInterFace::run(){ unsigned char recData[hidDataLength]; int res; while (isOpen==1) { res = hid_read(handle, recData, hidDataLength); if (res == 0) ;//printf("waiting...\n"); else if (res < 0) { printf("Unable to read()\n"); return; } else { int i;// printf("Data read:\n ");// // Print out the returned buffer.//// for (i = 0; i < res; i++)// printf("%02hhx ", recData[i]);// printf("\n"); unsigned char length = recData[0]; unsigned char datas[length]; for(i=0;i<length;i++) { datas[i]=recData[i+1]; } emit hidDataArrived(datas,length); } usleep(50*1000); }}int MainHidInterFace::hidApi_Close(void){ hid_close(handle); isOpen = 0; /* Free static HIDAPI objects. */ hid_exit(); delete handle; return 0;}
0 0
- 【Qt】使用libusb和hidapi实现hid通信
- Qt USB通信--hidapi的使用
- Qt USB通信--hidapi的使用
- qt mac 使用libusb
- QT HIDAPI应用笔记
- 基于libusb的mtp通信实现
- 如何在Linux下利用Libusb与HID USB设备通信!
- libusb介绍和使用例子
- libusb使用
- libusb使用
- libusb的使用教程和例子
- libusb的使用教程和例子
- libusb的使用教程和例子
- libusb的使用教程和例子
- libusb的使用教程和例子
- Android设备使用libusb和usb声卡
- QT - USB-driver - libusb
- QT - USB-driver - libusb
- 多进程与多线程的区别?
- QWidget关系图及部件
- android.view.WindowManager$BadTokenException
- 丑数(某一些数可以只由给定集合的元素的幂次相乘获得)模板
- 信息熵、条件熵、信息增益
- 【Qt】使用libusb和hidapi实现hid通信
- Python拾遗之类属性和实例属性(一)
- hadoop编程之mapreduce,计算总数和平均数
- 并发与并行的理解
- make 命令参数笔记
- DNS域名系统
- 窗口坐标和布局
- 在linux下用C语言编写发牌程序
- Mac下配置tomcat