-
Notifications
You must be signed in to change notification settings - Fork 281
USB
Tres Finocchiaro edited this page Apr 26, 2021
·
5 revisions
- ✅ 2.1 | ✅ 2.0 | ⛔ 1.9 | ...
Read and write raw data to an attached USB device.
Note: Many HID is strongly recommended instead, if available.
- USB communication to HID devices will not work on MacOS use HID instead.
- Claims device based on hardware information using
claimDevice(vendorId, productId, ifa)
- Reads data from device using
readData(vendorId, productId, endpoint, responseSize)
- Releases device using
releaseDevice(vendorId, productId)
// Hardware info (modify to match hardware)
var usb = {
vendor: '0x0EB8',
product: '0xF000',
interface: '0x00',
endpoint: '0x81'
};
// Generic error handler
var err = function(e) { console.error(e); }
// Generic data handler
var process = function(data) { console.log(data); }
// Handler to release claimed device
var release = function() {
qz.usb.releaseDevice(usb.vendor, usb.product).catch(err);
}
// Connect to QZ Tray, claim, read, release
qz.websocket.connect().then(function() {
return qz.usb.claimDevice(usb.vendor, usb.product, usb.interface);
}).then(function() {
return qz.usb.readData(usb.vendor, usb.product, usb.endpoint, '8'); // *
}).then(process).then(release).catch(err);
// Note: Some hardware such as Fairbanks scales use '6' for byte length. Adjust as needed
- Send data to a claimed USB device using
sendData(vendorId, productId, endpoint, data)
function sendUsbData() {
qz.usb.sendData('0x0EB8', '0xF000', '0x81', data).catch(displayError);
}
qz.print(config, data).catch(function(e) { console.error(e); });
- Parses data returned from USB port to determine status, weight, units and precision. Compatible with most USB attached scales (Stamps.com, Mettler Toledo, Dymo, etc).
- Requires read data example above.
var process = function(data) {
// Filter erroneous data
if (data.length < 4 || data.slice(2, 8).join('') == "000000000000") {
return null;
}
// Get status
var status = parseInt(data[1], 16);
switch(status) {
case 1: // fault
case 5: // underweight
case 6: // overweight
case 7: // calibrate
case 8: // re-zero
status = 'Error';
break;
case 3: // busy
status = 'Busy';
break;
case 2: // stable at zero
case 4: // stable non-zero
default:
status = 'Stable';
}
// Get precision
var precision = parseInt(data[3], 16);
precision = precision ^ -256; //unsigned to signed
// xor on 0 causes issues
if (precision == -256) { precision = 0; }
// Get units
var units = parseInt(data[2], 16);
switch(units) {
case 2:
units = 'g';
break;
case 3:
units = 'kg';
break;
case 11:
units = 'oz';
break;
case 12:
default:
units = 'lbs';
}
// Get weight
data.splice(0, 4);
data.reverse();
var weight = parseInt(data.join(''), 16);
weight *= Math.pow(10, precision);
weight = weight.toFixed(Math.abs(precision));
// Log data to the console
console.log(weight + units + ' - ' + status);
}
Although not advised for selecting a device, it is often useful to selecting the nth
interface or the nth
endpoint for a particular device. For example, rather than hard-coding endpoint = '0x81'
into the code, endpoint = endpoints[0]
may be desired instead.
// Generic error handler
var err = function(e) { console.error(e); }
// Generic data handler
var process = function(data) { console.log(data); }
// Stores device information
var usb = { vendor: null, product: null, interface: null, endpoint: null };
qz.websocket.connect().then(function() {
// First device
return qz.usb.listDevices(false);
}).then(function(devices) {
usb.vendor = "0x" + devices[0].vendorId;
usb.product = "0x" + devices[0].productId;
// First interface
return qz.usb.listInterfaces(usb.vendor, usb.product);
}).then(function(interfaces) {
usb.interface = "0x" + interfaces[0];
// First endpoint
return qz.usb.listEndpoints(usb.vendor, usb.product, usb.interface);
}).then(function(endpoints) {
usb.endpoint= "0x" + endpoints[0];
return qz.usb.claimDevice(usb.vendor, usb.product, usb.interface);
// process, release, err
}).then(function() {
return qz.usb.readData(usb.vendor, usb.product, usb.endpoint, '8');
}).then(process).then(release).catch(err);