-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for the VEC Footpedal #89
Changes from all commits
664b49d
c57f599
c22e084
a9cef2c
94b3b90
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1147,4 +1147,23 @@ export const PRODUCTS: { [name: string]: Product } = { | |
backLight2offset: 0, | ||
//timestamp: none, RailDriver has no time stamp | ||
}), | ||
VECFootpedal: literal<Product>({ | ||
name: 'VEC Footpedal', | ||
hidDevices: [[255, 0]], | ||
bBytes: 1, | ||
bBits: 4, // Bit 1=left pedal, bit 2=middle pedal, bit 3=right pedal, bits 4-8=0. | ||
colCount: 3, // 3 pedals in a row | ||
rowCount: 1, // number of physical rows | ||
hasPS: false, // | ||
backLightType: BackLightType.NONE, // no back light LEDs | ||
backLight2offset: 0, | ||
//timestamp: none, VECFootpedal has no time stamp | ||
btnLocation: [ | ||
[0, 0], | ||
[1, 1], | ||
[1, 2], | ||
[1, 3], | ||
], | ||
disableButtons: [0], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if this is required or not, if I set it to 1 it does fire left pedal presses. |
||
}), | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -112,6 +112,23 @@ export class XKeys extends EventEmitter { | |
for (let i = 0; i < 15; i++) { | ||
data[i] = rdData[i] | ||
} | ||
} else if (deviceInfo.productId === 255) { | ||
// Note: The VEC Footpedal is an older device, which doesn't follow the rest of xkeys data structure. | ||
// To make it easy for us, we'll just remap the data to work for us. | ||
|
||
const rdData = new Uint8Array(32) | ||
rdData[0] = 0 // this sets the Unit ID to 0 always | ||
if (!this._firmwareVersionIsSet) { | ||
rdData[1] = 214 // Fake initial message to set _firmwareVersion | ||
} else if (!this._unitIdIsSet) { | ||
rdData[1] = 3 // Fake initial message to set _unitId | ||
Comment on lines
+121
to
+124
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The first up and down events seem to get swallowed, can we not force extra messages here which I assume would solve this? Presumably this is also the same for the RailDriver? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Am I correct in assuming that this device doesn't really have the concept of a unitId? (That would make sense, since it won't accept the inititial write of If so, I suggest that we solve this by adding
into the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given it only ever returns the two bytes, and doesn't accept any writes, I don't think so! Although conversely I've never worked out what the second byte is for (some more generic underlying product/interface) The device has no serial number via lsusb either (but maybe that's common to all xkeys?).
Do you think this would solve it missing the first keypress and release too when run as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Adding that into the top of the init method (without removing my other changes) certainly doesn't break anything. Although the first press and release are still silently swallowed by the library currently. |
||
} else { | ||
rdData[1] = 0 // no pg switch, byte is always 0 | ||
} | ||
rdData[2] = data.readUInt8(0) // remap button bits | ||
rdData[3] = data.readUInt8(1) // remap button bits | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what, if anything, happens with this second byte? |
||
|
||
data = Buffer.from(rdData) | ||
} | ||
|
||
//------------------------ | ||
|
@@ -333,18 +350,21 @@ export class XKeys extends EventEmitter { | |
|
||
/** Initialize the device. This ensures that the essential information from the device about its state has been received. */ | ||
public async init(): Promise<void> { | ||
const pReceivedVersion = new Promise<void>((resolve) => { | ||
this.receivedVersionResolve = resolve | ||
}) | ||
const pReceivedGenerateData = new Promise<void>((resolve) => { | ||
this.receivedGenerateDataResolve = resolve | ||
}) | ||
if (this.deviceInfo.productId !== 255) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A question for you: I'm thinking that if it crashes we might want to guard against writing to it in some other methods as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I ever try and write to it, I get the following (so the device doesn't crash, but node does):
So I did the protection in each place that calls write, as it often needed other steps to work around it, but maybe it should be done more centrally? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have been away, but earlier you asked if I could assist. Not sure if I can, the VEC foot pedal is a proprietary device made specifically for VEC and their software. It is not an X-keys so not sure if it belongs here. It is very limited in its capabilities, however, 3 bits is just 3 bits, so it does that. As you are finding there will be a lot of work arounds to make it work. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Fair enough, I'd found lots of other hits on the Internet, and it's just integrated into Linux via the Event stuff, so I didn't realise it was originally designed just for VEC's software.
That seems quite similar with the RailDriver ( https://xkeys.com/xkeys/rdproducts.html ) stuff too, looking at some of the workarounds for that in the code too. I would say conversely, they're all P.I. Engineering devices, the VID confirms that, and the fact there's an official XKeys device which looks like later revisions of the VEC Infinity range it would seem a bit of a shame to me if the support wasn't added: |
||
// Note: The VEC Footpedal is an older device, which doesn't accept any writes so we don't do any initialization for it | ||
const pReceivedVersion = new Promise<void>((resolve) => { | ||
this.receivedVersionResolve = resolve | ||
}) | ||
const pReceivedGenerateData = new Promise<void>((resolve) => { | ||
this.receivedGenerateDataResolve = resolve | ||
}) | ||
|
||
this._getVersion() | ||
this._generateData() | ||
this._getVersion() | ||
this._generateData() | ||
|
||
await pReceivedVersion | ||
await pReceivedGenerateData | ||
await pReceivedVersion | ||
await pReceivedGenerateData | ||
} | ||
|
||
this._initialized = true | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I leave this out, the right pedal causes exceptions.