Issue
I'm currently working on a project that involves me trying to send a ZPL-Label from a Browser to a Zebra Printer (ZQ520) using Javascript and Bluetooth.
Currently I'm able to find the printer via bluetooth 4.0 using its SUUID and its name. I'm also able to send small ZPL labels to the printer via 'characteristic.writeValue' and the printer prints them correctly immediately after I've sent them.
My main problem is that there is a max length a BLE transmission of a label can have. Anything shorter than 512 characters gets transfered and printed correctly.
If my label exceeds 512 characters, the printer throws a 'DOMException' and doesn't print anything.
My current code is:
navigator.bluetooth.requestDevice({
filters:[
{ name: 'deviceName' }, { services: [ServiceUUID] }
]
}
.then(device => {
console.log(device);
return device.gatt.connect();
})
.then(server => {
console.log(server);
serverInstance = server;
return server.getPrimaryService(ServiceUUID);
})
.then(service => {
console.log(service);
return service.getCharacteristic(commandCharacteristicUUID);
})
.then(characteristic => {
var zpl = "^FS^FT66,339^A0N,68,83^FDBeispieltext^FS^FT66,439^A0N,68,83^FDBeispieltext^FS^FT66,539^A0N,68,83^FDBeispieltext^FS^FT66,639^A0N,68,83^FDBeispieltext^FS^FT66,739^A0N,68,83^FDBeispieltext^FS^FT66,839^A0N,68,83^FDBeispieltext^FS^FT66,939^A0N,68,83^FDBeispieltext^FS^PQ1,0,1,Y^XZ";
var encoder = new TextEncoder();
var data = encoder.encode(zpl);
console.log(data);
return characteristic.writeValue(data);
})
.catch(error => {
console.log('Connection failed!', error);
});
The 512 Byte limit of the BLE connection is also documented in the BLE documentation of the printer: "The amount of data that can be written to the characteristic is the minimum of the remote connection’s ATT MTU and 512 bytes." https://www.zebra.com/content/dam/zebra/software/en/application-notes/AppNote-BlueToothLE-v4.pdf
How can I circumvent the issue? The actual label that I have to send, has a size over 2500 byte.
The documentation mentions that a 'Long Write' via Bluetooth is also possible. I assume there is also a possibility to write small batches of data to the printer instead of sending the whole label at once.
I'm just currently struggling to find the right syntax on how to do that via Javascript.
Solution
I've found the solution with the help of this tutorial:
Added to the code that I had before, it basically looks like this:
var zpl = "..."; // whatever your label is
navigator.bluetooth.requestDevice({
filters:[
{ name: 'deviceName' },
{ services: [ServiceUUID] }
]
})
.then(device => {
console.log(device);
return device.gatt.connect();
})
.then(server => {
console.log(server);
serverInstance = server;
return server.getPrimaryService(ServiceUUID);
})
.then(service => {
console.log(service);
return service.getCharacteristic(commandCharacteristicUUID);
})
.then(characteristic => {
var maxChunk = 300;
var j = 0;
if ( zpl.length > maxChunk ) {
for ( var i = 0; i < zpl.length; i += maxChunk ) {
var subStr;
if ( i + maxChunk <= zpl.length ) {
subStr = zpl.substring(i, i + maxChunk);
} else {
subStr = zpl.substring(i, zpl.length);
}
setTimeout(writeStrToCharacteristic, 250 * j, subStr);
j++;
}
} else {
writeStrToCharacteristic(zpl);
}
function writeStrToCharacteristic (str) {
let buffer = new ArrayBuffer(str.length);
let dataView = new DataView(buffer);
for (var i = 0; i <str.length; i++) {
dataView.setUint8( i, str.charAt(i).charCodeAt() );
}
console.log('accessing the device');
return characteristic.writeValue(buffer);
}
})
.catch(error => {
console.log('Connection failed!', error);
});
JavaScript writes chunks of 300 bytes to the printer, until the whole label has been processed. It's important to have a small delay between each consecutive write, otherwise the printer won't respond for whatever reason.
Answered By - Anton Delticom Answer Checked By - Gilberto Lyons (PHPFixing Admin)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.