0

My client has bought a new Cash Drawer for his POS system.
Features fo the cash drawer as follows:

Model: D41SRB
SKU: D41SRB
Electronic Cash Drawer Black 16",
Roller, 24V Epson STD RJ11, Stainless front
5 Bill/5 Coin
1mm steel case
Two extra brackets inside top of case for added durability`

Its connected to the reciept printer EPSON TM-T88V Receipt. I need to open this drawer from a click of button in my C# application, however when I set the drawer to open after print from Printer Preference it works. So , I am sure its connected fine. I need something similar to this ARTICLE but in C#. So please help

theMayer
  • 15,456
  • 7
  • 58
  • 90
mark
  • 623
  • 3
  • 21
  • 54
  • FWIW You can convet C# <-> VB.Net pretty reliably online. https://www.carlosag.net/tools/codetranslator/ is one example. If it's anything like the cash drawers I sued to interact with, you needed to send a certain stream of characters to the (parallel/serial) port. Should be the same logic as printing a plain text string [Edit: Better converter link which supports this code] – Basic Mar 01 '18 at 16:04
  • Here are some other ways to to this. I’ve done it before in c# so later on I might be able to give you that code. http://www.beaglehardware.com/howtoprogramcashdrawer.html – theMayer Mar 01 '18 at 16:05
  • @theMayer how do I use those in c#, any code example? – mark Mar 01 '18 at 18:25

3 Answers3

1

To open the drawer on the TM-T88 series, you have to have it connected via a serial or network port.

The following command sequence is what I used. This is really old code, but it should do the job. You have to open the port and initialize the printer before doing anything else, so that's in there too.

private SerialPort serialPort1 = new SerialPort();

public void OpenPort()
{
    serialPort1.PortName = "COM1";
    serialPort1.Encoding = Encoding.ASCII;
    serialPort1.BaudRate = 38400;
    serialPort1.Parity = System.IO.Ports.Parity.None;
    serialPort1.DataBits = 8;
    serialPort1.StopBits = System.IO.Ports.StopBits.One;
    serialPort1.DtrEnable = true;
    serialPort1.Open();
}

public void InitializePrinter()
{
    serialPort1.Write(Char.ConvertFromUtf32(27) + char.ConvertFromUtf32(64));
}

public void OpenDrawer()
{
    serialPort1.Write(char.ConvertFromUtf32(27) +
       char.ConvertFromUtf32(112) + 
       char.ConvertFromUtf32(0) +
       char.ConvertFromUtf32(5) + 
       char.ConvertFromUtf32(5));
}
theMayer
  • 15,456
  • 7
  • 58
  • 90
  • Drawer is connected to printer via RJ11. How can I determine which port its connected to? – mark Mar 02 '18 at 10:36
  • You need to specify the _printer_ port in the program. Above program instructs the _printer_ to activate the cash drawer that is connected to the RJ11 port. – Marc Balmer Mar 02 '18 at 12:47
  • Along with this- you may have to install some software from Epson if it’s connected via Ethernet. This is all really beyond the scope of what Stack overflow is useful for though. – theMayer Mar 02 '18 at 13:37
  • When I checked port no. from Printer Propeties it has "ESDPRT001" checked so I tried opening that port but it gave me an error – mark Mar 02 '18 at 17:01
  • @mark- I hate to say this, but you seem to be in well over your head here, and I don't think I can provide much more help. Some of this is stuff you'll have to figure out on your own. – theMayer Mar 02 '18 at 17:49
  • @theMayer sorry for delay response, was trying few things none worked. I found code for TM-T88V to open cash drawer ie;27,112,48,55,121, should I replace this in `OpenDrawer()` function? – mark Mar 07 '18 at 05:46
  • Sure. I think the last couple of arguments are time parameters. – theMayer Mar 07 '18 at 18:09
1

I am able to solve my issue I used

RawPrinterHelper.SendStringToPrinter("EPSON TM-T88V Receipt", System.Text.ASCIIEncoding.ASCII.GetString(new byte[] { 27, 112, 48, 55, 121 }));

got this drawer code from http://keyhut.com/popopen.htm

Heres My whole code:

 public class RawPrinterHelper
    {
        // Structure and API declarions:
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public class DOCINFOA
        {
            [MarshalAs(UnmanagedType.LPStr)]
            public string pDocName;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pOutputFile;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pDataType;
        }
        [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);

        [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool ClosePrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);

        [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool EndDocPrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool StartPagePrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool EndPagePrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);

        // SendBytesToPrinter()
        // When the function is given a printer name and an unmanaged array
        // of bytes, the function sends those bytes to the print queue.
        // Returns true on success, false on failure.
        public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
        {
            Int32 dwError = 0, dwWritten = 0;
            IntPtr hPrinter = new IntPtr(0);
            DOCINFOA di = new DOCINFOA();
            bool bSuccess = false; // Assume failure unless you specifically succeed.

            di.pDocName = "RAW Document";
            // Win7
            di.pDataType = "RAW";

            // Win8+
            // di.pDataType = "XPS_PASS";

            // Open the printer.
            if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
            {
                // Start a document.
                if (StartDocPrinter(hPrinter, 1, di))
                {
                    // Start a page.
                    if (StartPagePrinter(hPrinter))
                    {
                        // Write your bytes.
                        bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
                        EndPagePrinter(hPrinter);
                    }
                    EndDocPrinter(hPrinter);
                }
                ClosePrinter(hPrinter);
            }
            // If you did not succeed, GetLastError may give more information
            // about why not.
            if (bSuccess == false)
            {
                dwError = Marshal.GetLastWin32Error();
            }
            return bSuccess;
        }

        public static bool SendFileToPrinter(string szPrinterName, string szFileName)
        {
            // Open the file.
            FileStream fs = new FileStream(szFileName, FileMode.Open);
            // Create a BinaryReader on the file.
            BinaryReader br = new BinaryReader(fs);
            // Dim an array of bytes big enough to hold the file's contents.
            Byte[] bytes = new Byte[fs.Length];
            bool bSuccess = false;
            // Your unmanaged pointer.
            IntPtr pUnmanagedBytes = new IntPtr(0);
            int nLength;

            nLength = Convert.ToInt32(fs.Length);
            // Read the contents of the file into the array.
            bytes = br.ReadBytes(nLength);
            // Allocate some unmanaged memory for those bytes.
            pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
            // Copy the managed byte array into the unmanaged array.
            Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
            // Send the unmanaged bytes to the printer.
            bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
            // Free the unmanaged memory that you allocated earlier.
            Marshal.FreeCoTaskMem(pUnmanagedBytes);
            fs.Close();
            fs.Dispose();
            fs = null;
            return bSuccess;
        }
        public static bool SendStringToPrinter(string szPrinterName, string szString)
        {
            IntPtr pBytes;
            Int32 dwCount;
            // How many characters are in the string?
            dwCount = szString.Length;
            // Assume that the printer is expecting ANSI text, and then convert
            // the string to ANSI text.
            pBytes = Marshal.StringToCoTaskMemAnsi(szString);
            // Send the converted ANSI string to the printer.
            SendBytesToPrinter(szPrinterName, pBytes, dwCount);
            Marshal.FreeCoTaskMem(pBytes);
            return true;
        }
    }
 private void button1_Click(object sender, EventArgs e)
    {
        RawPrinterHelper.SendStringToPrinter("EPSON TM-T88V Receipt", System.Text.ASCIIEncoding.ASCII.GetString(new byte[] { 27, 112, 48, 55, 121 }));
    }

After this by clicking on button1 it kicks the drawer.

mark
  • 623
  • 3
  • 21
  • 54
0

assume your serial port is called "port".

Just use: port.writeLine("\x10\x14\x01\x00\x08"); // For Cash Drawer 0

Just use: port.writeLine("\x10\x14\x01\x01\x08"); // For Cash Drawer 1

as the printer can talk to 2 cash drawers.

Commands:

ASCII DCE DC4 n m t

Hex 10 14 n m t

Decimal 16 20 n m t

Where n = 1, m = 0 or 1 (cash drawer #), t <= 1, t <=8

Daniel Steele
  • 33
  • 1
  • 1
  • 7