通过 WebUSB JavaScript 打开钱箱

Posted

技术标签:

【中文标题】通过 WebUSB JavaScript 打开钱箱【英文标题】:Open Cash Drawer via WebUSB JavaScript 【发布时间】:2020-02-26 00:38:53 【问题描述】:

我有一个 c# 应用程序,它可以打开安装了 Windows 驱动程序的现金抽屉。非常简单,因为驱动程序使 USB 设备显示为串行端口:

 SerialPort rsPort = new SerialPort(textBox1.Text);
 byte[] openCmd = new byte[5];
 openCmd[0] = 27;
 openCmd[1] = 112;
 openCmd[2] = 0;
 openCmd[3] = 60;
 openCmd[4] = 255;
 rsPort.Open();
 Thread.Sleep(100);
 rsPort.Write(openCmd, 0, 5);
 Thread.Sleep(100);
 rsPort.Close();

我现在正尝试通过 WebUSB 打开同一个 USB 现金抽屉。我使用 ZaDig 安装了通用 USB 驱动器,Chrome 可以看到 USB 设备;可以打开设备;但是,我正在努力发送正确的命令。

这是配置的图像:

这是我当前的代码:

<!DOCTYPE html>
<html>
<body>

<h2>javascript WebUSB</h2>

<button id="myBtn">Try it</button>

<script>
document.getElementById("myBtn").addEventListener("click", talkToDrawer);

async function talkToDrawer() 
  try 
    let device = await navigator.usb.requestDevice( filters: [ vendorId: 1659 ] );
    console.log(device);
    await device.open(); // Begin a session.
    await device.selectConfiguration(1); // Select configuration #1 for the device.
    await device.claimInterface(0); // Request exclusive control over interface #2.
    result = await device.controlTransferOut(
        requestType: 'standard', // tried all combinations: standard / class / vendor
        recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
        request: 0x27,
        value: 0,
        index: 1
     );
     result = await device.controlTransferOut(
        requestType: 'standard', // tried all combinations: standard / class / vendor
        recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
        request: 0x112,
        value: 0,
        index: 1
     );
     result = await device.controlTransferOut(
        requestType: 'standard', // tried all combinations: standard / class / vendor
        recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
        request: 0x0,
        value: 0,
        index: 1
     );
     result = await device.controlTransferOut(
        requestType: 'standard', // tried all combinations: standard / class / vendor
        recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
        request: 0x60,
        value: 0,
        index: 1
     );
         result = await device.controlTransferOut(
        requestType: 'standard', // tried all combinations: standard / class / vendor
        recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
        request: 0x255,
        value: 0,
        index: 1
     );

   catch (error) 
    console.log(error);
  



</script>

</body>
</html> 

【问题讨论】:

请勿发布代码、数据、错误消息等的图片 - 将文本复制或输入到问题中。 How to Ask 【参考方案1】:

在不了解设备的情况下,我在代码中看到了两个错误,

    在 C# 示例中,命令为 [27, 112, 0, 60, 255],其值以十进制给出,而在 Javascript 示例中,值以十六进制常量给出。在 Javascript 中构建命令缓冲区的适当代码是,
const cmd = new Uint8Array([27, 112, 0, 60, 255]);
    与其使用controlTransferOut() 发送数据,不如使用transferOut() 并选择端点号3 最可能正确。Prolific USB 转串口转换器芯片实现了与标准USB 串口类类似的协议,该协议对串行数据流使用一对批量 IN 和 OUT 端点,
result = await device.transferOut(3, cmd);

剩下的悬而未决的问题是您是否需要在发送此命令之前执行任何控制传输。控制传输用于配置设备,对于 USB 转串行芯片,这通常涉及设置波特率或将 DCE 位设置为高电平等事情。在对如何与 USB 设备进行通信进行逆向工程时,我建议使用Wireshark 来查看来自工作驱动程序的 USB 流量。

请注意,如果您使用的是串行设备,则应使用Serial API。在 chrome://flags/#enable-experimental-web-platform-features 标志后面的 Chrome 中有一个实验性实现。此 API 专为专门针对串行设备的应用程序而设计,无需重新实现 USB 转串行芯片的驱动程序。

【讨论】:

以上是关于通过 WebUSB JavaScript 打开钱箱的主要内容,如果未能解决你的问题,请参考以下文章

php处理POS打印机和钱箱

WebUSB 传输到客户显示器没有任何反应

Windows 10 WebUSB 打印问题与 Zebra LP2844 DOMException:访问被拒绝

接口申领失败:该平台不支持或未实现操作

硬币游戏---代码分析与改进

关于代码