저는 Windows 컴퓨터에 연결하고 컴퓨터의 터치 스크린을 시뮬레이트하는 Arduino 장치를 만들고 있습니다. 이 화면은 Arduino에 속하지 않지만 Arduino는 HID 터치 메시지를 USB를 통해 Windows 10 컴퓨터에 전달합니다.USB HID 멀티 터치 직렬보고
내가 한 첫 번째 작업은 Digitizer 이벤트 대신 AbsoluteMouse 이벤트를 릴레이하는 것이 었습니다. 이것은 나를 위해 잘 일했다. 그러나 내 장치가 여러 터치를 지원하므로 AbsoluteMouse 대신 멀티 터치 HID 메시지를 사용하고 싶습니다. 개념의 증거로서, 나는 단지 하나의 손가락의 데이터만을 중계하는 것으로 시작하고있다. (나는 이것을 작동 시키면 더 많은 손가락을 추가 할 계획이다). 내가 AbsoluteMouse를 사용하는 많은 예제를 발견
- https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/sample-report-descriptor--serial-reporting-mode-
- https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/selecting-packet-reporting-modes-in-multitouch-drivers
그래서 기본적으로 내가하지 않았다 : 구현하는 가장 쉬운 것으로 보인다 나는 SerialReport 접근 방식을 복용하고 HID 보고서를 복사하여 붙여 넣는 것보다 훨씬 많은 작업을 수행 할 수 있습니다. 그러나 터치 스크린을 사용하면 코드 샘플을 찾기가 매우 어렵습니다. (나는 단지 시냅스 터치 패드 샘플이 터치 스크린이 아닌 것을 발견했다). 이와 같이 터치 메시지를보고하기 위해 자체 코드를 구현하려고했습니다. 그러나 이것은 실패합니다. HID 설명자를 해석하는 방법을 이해할 수는 있겠지만 이것이 처음이기 때문에 확실하지 않습니다 ... 메시지 구조에 문제가 있습니까?
typedef union {
struct{
uint8_t TipSwitchLsb4Bits_InRange_Confidence_Empty2Bits;
uint8_t Padding8_10Minus2;
int16_t xAxis;
int16_t yAxis;
int16_t width;
int16_t height;
int16_t ContactId;
uint8_t MaximumCount;
};
} HID_SerialTouchReport;
void reportTouch(unsigned int x, unsigned int y) {
HID_SerialTouchReport report;
report.TipSwitchLsb4Bits_InRange_Confidence_Empty2Bits=0xff;
report.xAxis=x;
report.yAxis=y;
report.width=4;
report.height=4;
report.ContactId=0;
report.MaximumCount=1;
HID().SendReport(REPORTID_MTOUCH,&report,sizeof(report));
}
...
static HIDSubDescriptor node(_hidSerialMultiTouchDescriptor, sizeof(_hidSerialMultiTouchDescriptor));
HID().AppendDescriptor(&node);
...
//Move the pointer diagonally across the screen:
for(unsigned int x=0;x<32767;x+=1000) {
reportTouch(x,x);
delay(50);
}
테스트 코드가 MSPAINT에 오른쪽 아래 왼쪽 상단에서 대각선을 그릴 예정이다 :
#define REPORTID_MTOUCH 1
static const uint8_t _hidSerialMultiTouchDescriptor[] PROGMEM = {
//https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/sample-report-descriptor--serial-reporting-mode-
//linked from: https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/selecting-packet-reporting-modes-in-multitouch-drivers
0x05, 0x0d, // USAGE_PAGE (Digitizers)
0x09, 0x04, // USAGE (Touch Screen)
0xa1, 0x01, // COLLECTION (Application)
0x85, REPORTID_MTOUCH, // REPORT_ID (Touch)
0x09, 0x22, // USAGE (Finger)
0xa1, 0x00, // COLLECTION (Physical)
0x09, 0x42, // USAGE (Tip Switch)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x03, // INPUT (Cnst,Ary,Abs)
0x09, 0x32, // USAGE (In Range)
0x09, 0x47, // USAGE (Confidence)
0x95, 0x02, // REPORT_COUNT (2)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x0a, // REPORT_COUNT (10)
0x81, 0x03, // INPUT (Cnst,Ary,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desk..
0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767)
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x01, // REPORT_COUNT (1)
0x65, 0x00, // UNIT (None)
0x09, 0x30, // USAGE (X)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x31, // USAGE (Y)
0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x0d, // USAGE PAGE (Digitizers)
0x09, 0x48, // USAGE (Width)
0x09, 0x49, // USAGE (Height)
0x95, 0x01, // REPORT_COUNT (2)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x81, 0x03, // INPUT (Cnst,Ary,Abs)
0x09, 0x51, // USAGE (Contact Identifier)
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x02, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x55, // USAGE(Maximum Count)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x08, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x01, // REPORT_COUNT (1)
0xb1, 0x02, // FEATURE (Data,Var,Abs)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
이 말했다 메시지의 내 구현입니다.
내가 이것을 AbsoluteMouse 서술자/메시지로 테스트 할 때 모든 것이 작동합니다. 그래서 나는 HID_SerialTouchReport 정의에 문제가 있다고 추정한다. 내 관심을 잡고있다
어떤 것들은 : 여전히 "USAGE (Y)"를 정의하는 동안
- 왜 "PHYSICAL_MAXIMUM (0)"오지 않습니다. 그것은 Y와 관련이 있으며 X가 아닌 것입니까? 그리고 그것은 왜 "0"입니까?
- 높이와 너비에 대한 "INPUT (Cnst, Ary, Abs)"의 "Ary"의 의미는 무엇입니까?
- "report.TipSwitchLsb4Bits_InRange_Confidence_Empty2Bits = 0xff;"로 일종의 "푸딩"을합니다. 그러나 이것은 모든 비 패드 비트가 "1"로 설정되어야한다고 생각하기 때문에 나에게 괜찮은 것처럼 보입니다.
- report.MaximumCount를 설정해야할지 잘 모르겠습니다. 나는 다른 수의 실험을 시도했다. & Id 값은 모두 효과가 없었다.
- 내 Arduino는 장치 관리자에 "복합 장치"로 표시되므로 모든 문제가 잘못된 것은 아닙니다.
- "직렬 패킷"모드는 레거시 Windows 7 용으로 연결되었으며 Windows 10을 사용하고 있습니다.하지만 문제는 아닙니다.
- Microsoft 사이트에서 직접 HID 설명자를 복사했지만 메시지 구조를 제대로 구성하지 못했습니다. (약간의 비트를 잊어 버렸습니까?)
아니면 코드가 완전히 작동하지 않는 것입니까?
은 0x09, 0x48, // USAGE (폭) 은 0x09, 0x49까지는, // USAGE (높이) 에 0x95, 0x01로는, // REPORT_COUNT (2) 는 ...해야한다 : 은 0x09, 0x48, // 0x39, 0x49, // USAGE (높이) 0x95, 0x02, // REPORT_COUNT (2) (들여 쓰기에 대한 죄송합니다. – aja