0

I'm trying to print with a thermal printer which uses a com port. And I would like to detect whether the printer is connected or not.

I was assuming that if I try to run the codes which tries to print without connecting the printer, I would get some kind of error. So I used try-catch block. The following is what I have tried so far.

using System.IO.Ports;

private readonly SerialPort _printer = new SerialPort(Port, BaudRate, Parity, DataBits, Stopbits);

private void Print(string text)
        {            
            try
            {
                if (!_printer.IsOpen)
                    _printer.Open();               

                _printer.WriteLine(text);

                _printer.Close();
            }
            catch (Exception ex)
            {
                Logging.Log("PRINT ERROR: " + ex.Message);
            }            
        }

In most cases, if you try to print programmatically with the printer being disconnected, the code block which tries to print will throw error.

But in this case, the codes were executed as if the printer was connected and no errors were thrown.

I have also tried SerialPort.ErrorReceived event but it didn't work either.

So, I was wondering if there's a way to detect the status of the printer (whether it was connected or disconnected). Thanks for the help.

Trax
  • 341
  • 4
  • 17
  • Com ports are an old technology, it supports what it supports, more then likely you will just never know. – TheGeneral Jun 12 '19 at 04:40
  • 2
    Well, there is the [CTS (Clear to Send)](https://learn.microsoft.com/en-us/dotnet/api/system.io.ports.serialport.ctsholding?view=netframework-4.8) Signal on PIN 5 (25-Pin) or Pin 8 (9-Pin) RS232. _But_ the hardware and driver need to support it. Is that a "serial emulation" (that is USB pretending to be RS232)? In the latter case, the "PIN" may not be used at all. Then you're out of luck. – Fildor Jun 12 '19 at 05:48
  • You could use polling: send periodically a command (e.g. to request status or something). If answer don't come after 3 retries - its offline. *" the code block"* - is another problem, you don't set timeout somewhere. – Sinatr Jun 12 '19 at 07:30

1 Answers1

1

First, opening/closing the serial port every printing process is a waste of time, so it is better not to do it.

It is better to open when launching the application (POS?) And close when exiting.

The settings for hardware flow control enable ESC/POS printers connected to the serial port to distinguish online/offline.
However, it depends on the specifications of your printer, so please check the details.

  • Under normal conditions, both CTS & DSR signals are ON.

  • The CTS & DSR signal is OFF when printing can not be performed as follows.

    • Printer is not connected.
    • Paper is not set.
    • Printer cover is open.
    • Receive buffer is full.
    • Unable to print due to some error.

SerialPort.CtsHolding Property / SerialPort.DsrHolding Property

The simple way to do this is to check the above signals before printing.

In more detail, if you want to know whether the CTS & DSR signal is OFF, it is not connected or it can not be printed due to an error etc., send the following command and check the response It will be possible.

If there is no response, it can be determined that it is not connected.

The corresponding page is in Japanese.
DLE EOT

DLE EOT n (n=2 or 3)
0x10 0x04 0x02 or 0x03

0x10 0x04 0x02 : offline status
0x10 0x04 0x03 : error status

kunif
  • 4,060
  • 2
  • 10
  • 30
  • Hello kunif. First of all, thank you for your answer. I'm quite new to serial communications and com ports. I was trying to send the commands like you said. But there was no response form the printer. I'm doing it like this: `string DLE = "\u0010"; string EOT = "\u0004"; string num = "\u0002"; _printer.WriteLine(DLE + EOT + num); string rename = _printer.ReadLine(); Logging.Log("RESULT : " + rename);` But I'm not getting any response from the printer. Did I do something wrong? – Trax Jun 12 '19 at 09:08
  • 1
    Define the command as a 3-bytes byte array and send it using the Write method instead of WriteLine. And please receive not by ReadLine but by 1-byte Read method. – kunif Jun 12 '19 at 09:23
  • Thanks kunif. It WORKS!! I used the `SerialPort.DataReceived` event and was able to get the response from the printer. From this, I can now determine whether the printer was connected or not. Thank you so much for your answer, kunif. You just saved me from days of work. :) – Trax Jun 12 '19 at 10:16