1

I'm using a Star Micronics printer with the StarIO Java SDK to print some receipts. Sometimes when I'm sending bitmap data in raster mode, the StarIOPort.writePort() method times out. However, this method doesn't throw an exception and even returns a write size > 0. In this case, the printer prints a line of random pixels or a ton of empty lines/garbage text.

I think I can detect a timeout, but I don't know how to recover from it. As far as I know, once writePort() returns, the printer has already printed the garbage data. These timeouts are extremely frequent, with 1-2 occurring per receipt. I can adjust the baud rate and perhaps enable parity checking but I don't think that will entirely eliminate the issue. Can I prevent these timeouts or at least handle them without needing to reprint? What am I missing here?

Printer settings:

<JposEntry logicalName="TSP743II_linux_serial">
    <creation factoryClass="com.starmicronics.starjavapos.ServiceInstanceFactory" serviceClass="com.starmicronics.starjavapos.POSPrinterService" />
    <vendor name="Star Micronics" url="www.star-m.jp/eng/index.htm" />
    <jpos category="POSPrinter" version="1.9" />
    <product description="Star receipt printer" name="TSP743II" url="www.star-m.jp/eng/index.htm" />
    <prop name="model" type="String" value="TSP743II" />
    <prop name="portName" type="String" value="/dev/ttyS1" />
    <prop name="portSettings" type="String" value="19200,n,8,1,h" />
    <prop name="ioTimeoutMillis" type="Integer" value="10000" />
    <prop name="doCheckedBlockPrinting" type="Boolean" value="True" />
    <prop name="memorySwitchSetting" type="String" value=":1,0100:4,0002" />
</JposEntry>

Creating the port:

final String portName = "/dev/ttyS1";
final String portSettings = "19200,n,8,1,h";
final int timeout = 10000;
try {
    port = StarIOPort.getPort(portName, portSettings, timeout);
} catch (StarIOPortException exception) {
    exception.printStackTrace();
}

The port writing logic:

byte[] command = ...;
int totalSizeCommunicated = 0;
while (totalSizeCommunicated < command.length) {
    // This returns > 0 and doesn't throw an exception on timeout!
    totalSizeCommunicated += port.writePort(command,
        totalSizeCommunicated, command.length - totalSizeCommunicated);
}

The "command" array takes the following form:

final String commandString =
    // Enter raster mode
    "\u001b*rA"
    // Top margin command 2
    + "\u001b*rT2\0"
    // Page length command 0
    + "\u001b*rP0\0"
    // Print quality command 2
    + "\u001b*rQ2\0"
    // Left margin command 7
    + "\u001b*rml7\0"
    // Set end of page mode command 1
    + "\u001b*rF1\0"
    // Set end of doc mode command 1
    + "\u001b*rE1\0";
    // Raster image data by line (not actual code but demonstrative)
    + "b" + sizeOne + size256One + pixelsOne;
    + "b" + sizeTwo + size256Two + pixelsTwo;
    + "b" + sizeThree + size256Three + pixelsThree;
    // Exit raster mode, clear raster buffer
    + "\u001b*rB\u001b*rC".getBytes();

Releasing the port:

StarIOPort.releasePort(port);

Update: enabling parity checking didn't help. At all. In fact it may have made it worse.

Update 2: Halving the baud rate to 9600 made the problem worse as well.

Graph Theory
  • 699
  • 1
  • 7
  • 18
  • 1
    *"What am I missing here?"* -- Sounds like you're sending this data faster than the printer can receive & process it, i.e. the printer is experiencing buffer overrun, hence garbage data. Are you using any ***flow control***? Most printers require flow control. – sawdust Jun 12 '17 at 23:21
  • It's currently set to hardware flow control. I tried halving the baud rate and that seemed to make the problem worse. I'm not sure if that's a case for the printer wanting data faster or slower. – Graph Theory Jun 12 '17 at 23:33
  • Verify both printer and host are set to HW flow control and the same control lines. Check the cable. Do you have a breakout box or some other means (e.g. oscilloscope) of monitoring the handshake signals? Determine the printer's receive buffer size (1KB?). Then try metering the data sent to the printer (e.g. for each write delay 30 seconds and 512 bytes per syscall). – sawdust Jun 13 '17 at 02:22
  • Method for checking if flow control is broken: disable all flow control. If same symptoms persist, then flow control is not working as expected. – sawdust Jun 13 '17 at 03:10
  • Disabling flow control didn't seem to make a difference. I've tried a few different cables and the results are still the same. Metering the data produced interesting results however. If I wait 30 seconds between each write, no timeouts occur but the printer doesn't print anything. If I wait 1 second, there's a timeout almost every write. With no wait I get a timeout every KB or two. Interestingly, the port only seems to accept a max of 40 bytes at a time. – Graph Theory Jun 14 '17 at 16:46
  • *"Disabling flow control didn't seem to make a difference."* -- That implies that when you think you have flow control enabled, it really is not active. You probably need to monitor the hardware control signals. *"the port only seems to accept a max of 40 bytes at a time."* -- Instead of your conclusions, report raw observations without your interpretations. IOW what leads you to claim this? – sawdust Jun 14 '17 at 19:25
  • The writePort method returns the number of bytes written: this is consistently 40 bytes or the remainder of the command, whichever is smaller. – Graph Theory Jun 14 '17 at 19:36

0 Answers0