2

更新: 不要浪费你的时间。甚至包含的 SDK 也无法从该打印机成功获取任何状态,因此它可能不受支持。

原始问题:

我有一个漂亮的小Zjiang ZJ-5802LD 热敏收据打印机,不幸的是,除了一个非常糟糕的“SDK”之外,它没有任何文档,包括一个 jar 和几个示例。

为了绕过这些限制,我尝试使用 Javax-USB 直接发送 ESC/POS 代码,但我怀疑我对 USB 的理解不足会造成干扰。它打印得非常愉快,但我完全被困在试图从小野兽那里恢复状态。

它只有一个输入和一个输出端点,分别位于 0x81 和 0x03。下面的代码,以及我在那里找到的每组与状态相关的消息字节,总是只返回一串零,然后抛出javax.usb.UsbException: Pipe is still busy.

您是否期望以下方法编写请求并返回状态?有更好的想法如何获得状态码?

public void checkStatus(UsbPipe readpipe, UsbPipe writepipe) {
    byte[] msg= { 0x1b, 0x76 }; // ESC-v = { status, per https://www.sparkfun.com/datasheets/Components/General/Driver%20board.pdf
    //byte[] msg= { 0x00, 0x04 }; // DLE EOT is the epson standard status req
    //byte[] msg= { 0x1d, '(', 'H' }; // Another status request from somewhere.
    //byte[] msg= { 0x1d, 'a' }; // Sets Automatic Status Back (ASB) mode.
    //byte[] msg= { 0x1c, '(', 'e' }; // Another way to set ASB -- https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id= {72

    try {
        // Prepare to read response
        readpipe.open();
        byte[] data = new byte[8];
        final UsbIrp rirp = readpipe.asyncSubmit(data);
        rirp.setComplete(false);

        // Send away.
        writepipe.open();
        final UsbIrp wirp = writepipe.asyncSubmit(msg);
        wirp.waitUntilComplete(500);
        writepipe.close();

        // Wait until we get something back
        rirp.waitUntilComplete(500);
        System.out.println("returned data: " + DatatypeConverter.printHexBinary(rirp.getData()));
        readpipe.close();
    } catch (UsbNotActiveException | UsbNotClaimedException | UsbDisconnectedException | UsbException e1) {
        e1.printStackTrace();
    }
}

如果您有类似的打印机并受到启发尝试运行它,这里是完整的程序。

package posprint;

import javax.usb.*;
import javax.usb.event.*;
import javax.xml.bind.DatatypeConverter;

import java.util.List;

public class Main {
    UsbServices services;
    UsbHub roothub;
    UsbDevice dev;
    UsbInterface iface;
    UsbEndpoint endpointOut;
    UsbEndpoint endpointIn;
    UsbPipe mWritepipe;
    UsbPipe mReadpipe;

    public static void main(String[] args) throws Exception {
        Main mn = new Main(); 
        if(mn.dev == null) return;
        mn.checkStatus(mn.mReadpipe, mn.mWritepipe);
        mn.iface.release();
    }

    public Main() throws Exception {
        services = UsbHostManager.getUsbServices();
        short vid = (short) 0x0493;
        short pid = (short) 0x8760;
        roothub = services.getRootUsbHub();
        dev = findDevice(roothub, vid, pid);
        if( dev == null) {
            System.out.println("not found");
            return;
        }
        getPipes(dev);
    }

    UsbDevice findDevice(UsbHub hub, short vendorId, short productId)
    {
        for (UsbDevice device : (List<UsbDevice>) hub.getAttachedUsbDevices())
        {
            UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor();
            if (desc.idVendor() == vendorId && desc.idProduct() == productId) return device;
            if (device.isUsbHub())
            {
                device = findDevice((UsbHub) device, vendorId, productId);
                if (device != null) return device;
            }
        }
        return null;
    }

    void getPipes(UsbDevice device) throws Exception {
        UsbConfiguration configuration = device.getActiveUsbConfiguration();
        List<UsbInterface> ifaces = configuration.getUsbInterfaces();
        for ( UsbInterface ifac : ifaces ) { 
            System.out.println(ifac.toString());
        }

        iface = configuration.getUsbInterface((byte) 0);
        iface.claim(new UsbInterfacePolicy() {            
            @Override public boolean forceClaim(UsbInterface usbInterface)          {
                return true;
            }
        });

        List<UsbEndpoint> eps = iface.getUsbEndpoints();
        for( UsbEndpoint ep : eps ) {
            UsbEndpointDescriptor desc = ep.getUsbEndpointDescriptor();
            System.out.println(ep.toString() + " has endpoint: " + desc.bEndpointAddress());
        }

        endpointOut = iface.getUsbEndpoint((byte) 0x03);
        mWritepipe = endpointOut.getUsbPipe();

        endpointIn = iface.getUsbEndpoint((byte) 0x81); // -127
        mReadpipe = endpointIn.getUsbPipe();
    }

    public void checkControlStatus() throws UsbNotActiveException, UsbNotClaimedException, UsbDisconnectedException, UsbException {
        int ret = 0;
        byte[] readbuf = new byte[2]; 
        try { 
            // Write status request
            UsbControlIrp devirp = mWritepipe.createUsbControlIrp(
                    (byte) (UsbConst.REQUESTTYPE_DIRECTION_IN
                            | UsbConst.REQUESTTYPE_TYPE_STANDARD
                            | UsbConst.REQUESTTYPE_RECIPIENT_DEVICE),
                    UsbConst.REQUEST_GET_STATUS, //UsbConst.REQUEST_GET_CONFIGURATION,
                    (short) 0,
                    (short) 0
                    );
            devirp.setData(readbuf);
            dev.syncSubmit(devirp);
            System.out.println(DatatypeConverter.printHexBinary(devirp.getData()));
        } catch (RuntimeException e) {
            System.out.println(e.getMessage());
            return;
        }
        System.out.println( "Control status: " + DatatypeConverter.printHexBinary(readbuf));
    }

    private class MyListener implements UsbPipeListener {
        public MyListener(String prefix) {this.prefix = prefix; }
        String prefix;
        // used with
        // mReadpipe.addUsbPipeListener(new MyListener("read"));  // For backup, because the async read isn't working.
        @Override public void errorEventOccurred(UsbPipeErrorEvent event) {
            System.out.println(prefix + " pipe error: " + event.toString());
        }
        @Override public void dataEventOccurred(UsbPipeDataEvent event) {
            System.out.println(prefix + " listener data: " + DatatypeConverter.printHexBinary(event.getData()));
        }                   
    }

    public void checkStatus(UsbPipe readpipe, UsbPipe writepipe) {
        byte[] msg= { 0x1b, 0x76 }; // ESC-v = { status, per https://www.sparkfun.com/datasheets/Components/General/Driver%20board.pdf
        //byte[] msg= { 0x00, 0x04 }; // DLE EOT is the epson standard status req
        //byte[] msg= { 0x1d, '(', 'H' }; // Another status request from somewhere.
        //byte[] msg= { 0x1d, 'a' }; // Sets Automatic Status Back (ASB) mode.
        //byte[] msg= { 0x1c, '(', 'e' }; // Another way to set ASB -- https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id= {72

        try {
            // Prepare to read response
            readpipe.open();
            byte[] data = new byte[8];
            final UsbIrp rirp = readpipe.asyncSubmit(data);
            rirp.setComplete(false);

            // Send away.
            writepipe.open();
            final UsbIrp wirp = writepipe.asyncSubmit(msg);
            wirp.waitUntilComplete(500);
            writepipe.close();

            // Wait until we get something back
            rirp.waitUntilComplete(500);
            System.out.println("returned data: " + DatatypeConverter.printHexBinary(rirp.getData()));
            readpipe.close();
        } catch (UsbNotActiveException | UsbNotClaimedException | UsbDisconnectedException | UsbException e1) {
            e1.printStackTrace();
        }
    }
}
4

0 回答 0