I need your help.
I’m developing a web application (Flutter) that needs to communicate with thermal printers (EPSON, STAR or even the more common and cheaper mini ones). I tried using WEBUSB API and it didn’t work on Windows, only on the MacBook. Since I’m using a thermal printer, the WEBSERIAL API worked on Windows, but it doesn’t work for EPSON thermal printers.
I researched how iFood handles this and discovered that an .exe is downloaded that makes this communication with the printer and their web application. So, I tried to develop something that would allow local communication of my application with the USB port, using a node.js server, with escpos, escpos-usb, express, usb-detection, serial port libraries. After several attempts, I always get the same error: LIBUSB_ERROR_IO. I checked and discovered that I would need to use another drive in my printer to make the communication I need. However, I didn’t want to have to mess with the driver since the printer will be used by other applications, including ifood, and this driver update may stop it from working. Does anyone have any idea what I can do to get around this situation?
Thank you and sorry for my bad English.
I tried to develop something that would allow local communication of my application with the USB port, using a node.js server, with escpos, escpos-usb, express, usb-detection, serial port libraries.
Some codes:
const usb = require('usb'); // Biblioteca para comunicação USB
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
// Função para converter string em buffer binário
function stringToBuffer(str) {
return Buffer.from(str, 'utf-8');
}
// Middleware para processar os dados binários (raw)
app.use(bodyParser.raw({ type: 'application/octet-stream' }));
// Função para enviar mensagem simples para a impressora
async function sendTestMessage() {
return new Promise((resolve, reject) => {
try {
// Detecta todos os dispositivos USB conectados
const devices = usb.getDeviceList();
const printerDevice = devices.find(device => {
console.log(device.deviceDescriptor);
const { idVendor, idProduct } = device.deviceDescriptor;
console.log(`Dispositivo encontrado: VendorId=${idVendor}, ProductId=${idProduct}`);
// Filtra pelo VendorId e ProductId conhecidos
return idVendor === 1155 && idProduct === 22304;
});
if (!printerDevice) {
reject(new Error('Nenhuma impressora USB encontrada.'));
return;
}
// Abre o dispositivo USB
printerDevice.open();
// Acesse a interface de comunicação (normalmente interface 0)
const iface = printerDevice.interfaces[0];
if (iface.isKernelDriverActive()) {
iface.detachKernelDriver(); // Desvincula o driver do kernel (se necessário)
}
// Ativa a interface para enviar dados
iface.claim();
// Identificar endpoints de saída (OUT)
const outEndpoints = iface.endpoints.filter(endpoint => endpoint.direction === 'out');
if (outEndpoints.length === 0) {
reject(new Error('Nenhum endpoint de saída (OUT) encontrado.'));
return;
}
// Usar o primeiro endpoint de saída disponível
const endpoint = outEndpoints[0];
console.log(`Usando endpoint de saída número ${endpoint.address}`);
// Mensagem curta para teste
const testMessage = stringToBuffer('Teste de impressão');
// Enviar a mensagem curta para o endpoint de saída
endpoint.transfer(testMessage, (err) => {
if (err) {
reject(new Error('Erro ao enviar dados para o dispositivo USB: ' + err.message));
} else {
console.log('Mensagem enviada com sucesso para o dispositivo USB!');
resolve('Mensagem enviada com sucesso para o dispositivo USB!');
}
});
// Fechar o dispositivo após a impressão
printerDevice.close();
} catch (error) {
reject(new Error('Erro ao imprimir via USB: ' + error.message));
}
});
}
// Endpoint para enviar uma mensagem curta de teste
app.get('/send-test', async (req, res) => {
try {
const result = await sendTestMessage();
res.send(result); // Envia uma resposta de sucesso
} catch (error) {
console.error('Erro ao tentar imprimir:', error);
res.status(500).send('Erro ao tentar imprimir: ' + error.message);
}
});
// Rodando o servidor na porta 3000
app.listen(3000, () => {
console.log('Servidor rodando em http://localhost:3000');
});
I try WEBUSB API, WEBSERIAL API and node.js server.