Print Graphic and Text to Epson TM-T88v

Posted on 2016-09-07
Last Modified: 2016-09-21
Hello Experts;

I need a solution to print a logo at the top of a receipt printed from an Epson TM-T88V printer. I've attempted to use examples for ESC/POS from the net without any success including writing various ESC commands to the printer port. Currently I'm writing the receipt data to a text file and sending it to the printer as text and re- writing the text file to the printer port.

The following is a simplistic approach that doesn't work because the printer cuts the paper off after the logo prints with the 'EndDoc' command...

procedure TForm1.Button7Click(Sender: TObject);
  Port: System.Text;
  Bitmap: TBitmap;
  F, F1: TextFile;
  Lines: TStringList;
  Index: Integer;
  with Printer do
  Lines := TStringList.Create;
  Printer.Canvas.Font.Size := 10;
  for Index := 0 to Lines.Count-1 do
  Writeln(F, Lines[Index]);

Help with either an ESC/POS solution or printing text and graphic together using TPrinter would be greatly appreciated.

Thank you,
Question by:visionetv
LVL 37

Expert Comment

by:Geert Gruwez
ID: 41789095
you are printing 2 sheets
first with a logo
second with the text

you'll have to use the first method to print the whole document if you als want text left or right of the logo
usually such printer cuts the sheet after each document

EndDoc and CloseFile indicate to the printer the document is finished

you'll have to scale everything you print
look for Delphi TPrinter BeginDoc EndDoc in google and you'll find multiple solutions
they usually all start with inquiring for the paper size and calculating the scale and font sizes to use

there is a lengthy discussion here too:

efg has an extensive page of links too:

it takes a bit of work to print everything nicely
you could create bitmap first and then stretch it to the printer canvas
like in the first freepascal link
LVL 26

Expert Comment

by:Dr. Klahn
ID: 41789165
I looked into a similar problem some years back.  In that situation the problem was being caused by the unwanted insertion of an FF (form feed) character after sending the graphics.  I suspect you're going to find that a similar issue is causing the unwanted form eject.  If that's the case, it might be workable to programmatically merge the header and the text into one file, then spool that file.
LVL 26

Expert Comment

by:Sinisa Vuk
ID: 41792902
I work with Epson TM-T88 a lot....Will send example but not before Monday...
In short - I use Epson Opos engine to print receipts...Your way is printing as graphics... and this is so slow.... Using ESC codes and com port component is a much better....
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.


Author Comment

ID: 41792927
Hi Sinisa;

Please send the ESC example on Monday for the T-88 that is how I want to access the printer.

LVL 26

Expert Comment

by:Sinisa Vuk
ID: 41795547
Ok, little later....
First, I define bitmap data in a printer and then start print buffer...
const ESC_ESC             = #$1B;
const ESC_FS              = #$1C;
const ESC_GS              = #$1D;

function BmpFileToDataList(sLogo: String; var xL, xH, yL, yH: Integer): String;
  Graphic: TGraphic;
  c: Byte;
  bmp: TBitmap;
  x, y, w, h, i: Integer;
  Result := '';
  xL := 0;
  xH := 0;
  yL := 0;
  yH := 0;
    bmp := TBitmap.Create;
      bmp.PixelFormat := pf24bit;
      bmp.Monochrome := True;
      bmp.PixelFormat := pf1bit; //convert to two color

      w := (bmp.Width div 8);
      if (bmp.Width mod 8) > 0 then Inc(w);
      w := w * 8;
      h := bmp.Height;

      xL := w mod 256;
      xH := w div 256;
      yL := h mod 256;
      yH := h div 256;

      //iterate pixels
      for y := 0 to h-1 do
        for x := 0 to (w div 8)-1 do
          //pack 8 x 1 pixel bits into one byte
          c := 0;
          for i := 0 to 7 do
            if (x * 8 + i) < bmp.Width then
              if Cardinal(bmp.Canvas.Pixels[x * 8 + i, y]) = 0 then  //is black?
                c := c or (1 shl (7-i));  //shift pixels into byte
          Result := Result + char(c);
    Result := '';

procedure TForm1.Button12Click(Sender: TObject);
  sData, sCmd, sReaded, sPrnCmd: String;
  xL, xH, yL, yH, m, ln, p1 ,p2, p3, p4: Integer;
  //bmp > nibble
  sData := BmpFileToDataList('C:\test.bmp', xL, xH, yL, yH);    
  //check if bmp data is valid
  if (Length(sData)> 0) and (xH <= 255) and (yH <= 8) then
    m     Mode
    0, 48 Normal
    1, 49 Double-width
    2, 50 Double-height
    3, 51 Quadruple
    m := 48;
    ln := 10 + Length(sData);
    p1 := (ln mod 256);
    p2 := ((ln div 256) mod 256);
    p3 := ((ln div 65536) mod 256);
    p4 := ((ln div 16777216) mod 256);

    sCmd := ESC_ESC + '@';

    n	    Justification
    0, 48	Left justification
    1, 49	Centered
    2, 50	Right justification
    //centered:  ESC	   	a	   	n
    sCmd := ESC_ESC + 'a' + Char(49);
    //define bmp data: GS 8 L p1 p2 p3 p4 m fn a bx by c xL xH yL yH
    sCmd := sCmd + ESC_GS + '8' + 'L' + Char(p1) + Char(p2) + Char(p3) + Char(p4) + Char(m) +
      Char(112) + Char(48) + Char(1) + Char(1) + Char(49) + Char(xL) + Char(xH) + Char(yL) + Char(yH);

    //print: 	GS 8 L p1 p2 p3 p4 m fn
    sPrnCmd := ESC_GS + '(' + 'L' + Char(2) + Char(0) + Char(m) + Char(50);

    DirectPrintToCom('COM1', br38400, sCmd + sData + sPrnCmd, sReaded);

Open in new window

I use TComPort component thnx to Dejan Crnila (created runtime)
Note: printing this way is a little slow ... data must be transferred all time. For printing logos you can use NV defined bitmaps (always stored in a printer)
Common text is printing by simple sending to com port.
    DirectPrintToCom('COM1', br38400, 'My text', sReaded);

Open in new window

For bolding, justifying ... use ESC commands for a chars...

Author Comment

ID: 41796748
Hi Sinisa;

Thank you for the example. Using the code in my question I can print the logo and text but the printer cuts the paper after the logo is printed and then prints the text. As an alternative I stored the logo on board the T-88V but I can't figure out how to implement the ESC command in Delphi for printing the logo first then the text directly to the printer's virtual USB port.

I need to print the logo first either stored or directly and then the receipt text as a single sheet.


Author Comment

ID: 41802211
Hi Experts;

My need is to print a logo stored in non-volatile memory (NV) onboard an Epson TM-T88V receipt printer together with transaction data stored in a text file. The ESC/P commands in the Epson developer guide are listed as ASCII, Hex, or Decimal. According to my research the commands need to be converted to 'AnsiStrings' to be Delphi compatible for sending instructions to the printer

For example, the ESC/P ASCII 'cut paper' command listed in the Epson manual is '#GS V 0' which converts to AnsiString 'CHR($1D)+'V'+CHR(0)' for use in Delphi which I have tested and it works.  The ESC/P ASCII command for printing the content of the printer's NV is 'GS(L <function 69>) which I do not know how to convert to an AnsiString.

Another possible approach is using the ESC/P (Escape) functions in the WinAPI and call ShellExecute() to send to the printer. I haven't yet determined what the ESC/P command syntax and structure need to be to use the WinAPI as an alternative.

Any help, direction, or comments will be greatly appreciated, I've been stuck on this issue for several days.

Thank you,
LVL 26

Expert Comment

by:Sinisa Vuk
ID: 41802410
i will produce example in a few days...sorry very busy these days...
Under which key id you stored logo in NV memory?

Author Comment

ID: 41802447
Hi Sinisa;

Thank you that would be great. Key id is 48,49 "01".
LVL 26

Accepted Solution

Sinisa Vuk earned 500 total points
ID: 41805948
For a additional info about print NV logo with Function 69 go here...and for setting NV logo (but you've done that - go here...)

(with help of my functions to send data to com port...)
  sReaded, sPrnCmd: String;
  m: Integer;
  kc1, kc2: Integer;
  //Print the specified NV graphics data - Function 69
  m := 48;
  kc1 := 48;
  kc2 := 49;

  //GS	   	(	   	L	   	pL	   	pH	   	m	   	fn	   	kc1	   	kc2	   	x	   	y
  sPrnCmd := ESC_GS + '(' + 'L' + Char(6) + Char(0) + Char(m) + Char(69) + Char(kc1) + Char(kc2) + Char(1) + Char(1);

  DirectPrintToCom('COM8', br38400, sPrnCmd, sReaded);

Open in new window


Author Closing Comment

ID: 41809249
Thank you for the example. I overlooked the settings in the 'Document Settings' of the TM-T88V 'Printing Preferences' which also provides control over the NV onboard graphics.

Thanks again for the help,
LVL 26

Expert Comment

by:Sinisa Vuk
ID: 41809701
You're welcome...
I use OPOS drivers...So I code once and work with most different printers...and simplify printing becouse there are no ESC commands, just simple functions to call...

Featured Post

Portable, direct connect server access

The ATEN CV211 connects a laptop directly to any server allowing you instant access to perform data maintenance and local operations, for quick troubleshooting, updating, service and repair.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to create virtual printer while installing my application 5 61
Delphi...Split view - idea? 1 87
Breakpoint doesn't stop in my variable 3 30
NCR Printer 7156 1 35
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Printers have changed substantially in the last 30 or so years, not just in technical capabilities but in cost and usage as well.  Printers were originally used for interfacing with the operator, not necessarily for printing copy or pictures. In …
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…
In an interesting question ( here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

792 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question