1

This will print (although still ugly) on the Zebra QL220 belt printer from my CE/CF app running on a Motorola MC3100 handheld:

public void PrintBarcode(string barcode, string UPC, string description, decimal listPrice)
{
    using (SerialPort serialPort = new SerialPort())
    {
        serialPort.BaudRate = 19200;
        serialPort.Handshake = Handshake.XOnXOff; 
        serialPort.DataBits = 8;
        serialPort.Parity = Parity.None;
        serialPort.StopBits = StopBits.One; // other choice is Two (see p. 14-21 in CPCL pdf)
        serialPort.PortName = "COM1:"; 

        serialPort.Open(); 

        Thread.Sleep(2500); // I don't know why this is needed, or if it really is...

        serialPort.Write("! 0 200 200 210 1\r\n");

        serialPort.Write("TEXT 4 0 30 40 Hola el Mundo\r\n"); //Bonjour le Monde --- Hola el Mundo --- Hallo die Welt
        serialPort.Write("TEXT 4 0 30 40 \r\n");

        serialPort.Write("BARCODE-TEXT 7 0 5\r\n"); 
        serialPort.Write(string.Format("BARCODE 128 1 1 50 150 10 {0}\r\n", barcode));
        serialPort.Write("TEXT 4 0 30 40\r\n");
        serialPort.Write("FORM\r\n");
        serialPort.Write("PRINT\r\n");

        serialPort.Close();
    }
}

...but all together, like half-manic teens in a mosh pit - the barcode, printed last, is actually at the highest point on the paper, and the "Hola el Mundo" and what looks like "FOIPM" (how did that get there?!?), too.

If "TEXT 4 0 30 40\r\n" is not a way to send CRLFs, what is?

UPDATE

I noticed I had a typo in the args to print the barcode. This:

    serialPort.Write(string.Format("BARCODE 128 1 1 50 150 10 {0}\r\n", barcode));

...this should have been this:

    serialPort.Write(string.Format("BARCODE 128 1 1 50 150 130 {0}\r\n", barcode));

...but when I "fixed" it (changed the vertical starting point from 10 to 130), the printed result was identical! Excuse my French, but what the North Dakota is going on here?!?

UPDATE 2

Never mind, once I add the fix to the right place, it does actually work (changing "10" to "130"). Now I've got to make it "smart" in that it will take into account previous printing areas and always print subsequent lines below the starting point + height of prior printings.

B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862

3 Answers3

3

It look's like you're writing CPCL directly to the printer. The TEXT command that you are using includes x and y coordinates itself in the command - namely, the '30' and '40' that you are writing is telling your printer to always print each line of text at the coordinates 30,40. Try changing these coordinates with each subsequent line of text that you want to print. To my knowledge, there is no 'auto-wrap' feature for CPCL, so you will have to do this manually for each line of text.

Alternatively, you can put the printer in line-print mode. In this mode, the printer will simply print any text that it receives, and '\r\n' will cause the printer to start printing on the next line. You can toggle line print mode by sending the following command to the printer:

! U1 setvar "device.languages" "line_print" [NEW LINE CHARACTER HERE]

source: CPCL Manual - http://www.zebra.com/content/dam/zebra/manuals/en-us/printer/cpcl-pm-en.pdf

jason.zissman
  • 2,750
  • 2
  • 19
  • 24
  • So if I use line print mode, subsequent calls to TEXT and BARCODE, etc. would simply omit the positional args? IOW, this: serialPort.Write("TEXT 4 0 30 40 Hallo die Welt\r\n\r\n"); ...would become this: serialPort.Write(string.Format("! U1 setvar {0} {1}"), "device.languages", "line_print")); serialPort.Write("TEXT 4 0 Hallo die Welt\r\n\r\n"); ? – B. Clay Shannon-B. Crow Raven Feb 11 '13 at 16:18
  • Not Quite - If you send the Line Print Mode command, absolutely anything that you send will be printed (except the command to leave line print mode and a few others!). So, writing serialPort.Write("Apples: $4.99\r\n"); serialPort.Write("Bananas: $1.99"); would result in two lines of text, one on top of the other. It's that simple. The CPCL manual should contain a section on how to perform line printing. – jason.zissman Feb 11 '13 at 16:25
  • Okay, but appending "\r\n" to those Write lines would advance subsequent lines to the next line, right? – B. Clay Shannon-B. Crow Raven Feb 11 '13 at 16:51
  • Yup! In this context, the printer interprets '\r\n' as a new line (or you can use System.Environment.Newline instead!) and the subsequent text will appear on the next line. – jason.zissman Feb 11 '13 at 18:19
  • I'm using a StringBuilder to aggregate all of the commands I'm going to send the printer; if I use AppendLine() instead of Append(), will this obviate the need to append "\r\n" to each line? – B. Clay Shannon-B. Crow Raven Feb 12 '13 at 17:06
  • I'm not familiar with append() and appendLine(), but it sounds logical that appendLine() will include a new line character at the end. Check with the documentation to see if it does. If so, you will not have to append yourself. However, it'd be far more rewarding just to test it yourself by actually trying both methods! – jason.zissman Feb 14 '13 at 14:53
1

As a general rule, consider using System.Environment.Newline

However, in this case, it sounds like you may need to check what your device ( Zebra QL220 ) expects / requires for a linefeed.

John
  • 633
  • 4
  • 9
1

I don't know how to write to a Zebra printer, but:

I see codes for "Start of Text" (TEXT 4 0 30 40) and "Start of Barcode" (BARCODE 128 1 1).

Should there be some code for "End of Text" or "End of Barcode"?

How about a code for "Next Line"?