2

I try to setup my raspberry pi 3 as a virtual printer. My scenario is the following:

Legacy System (running Windows 7) -> COM port -> cross-wired rs232 cable -> rpi rs232 extension board for GPIO -> /dev/ttyAMA0 port on latest Raspbian

I try to read the incoming printing jobs at the rpi end. I cannot get this working. When using pyserial, I can exchange data between my windows system and my rpi using the following code:

Raspberry (receiving end):

import serial

with serial.Serial(port='/dev/ttyAMA0', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=0, rtscts=0) as ser:
  x = ser.readline()
  print x

Windows (sending end):

PS> [System.IO.Ports.SerialPort]::getportnames()
COM1,9600,None,8,one
PS> $port= new-Object System.IO.Ports.SerialPort COM1,9600,None,8,one
PS> $port.open()
PS> $port.WriteLine("Hello world")
PS> $port.Close()

Result: "Hello world" is printed on the rpi's console.
Issue: However, the same COM port does not work as a "Generic / Text only" printer. No data is delivered to the rpi.

Question: What is missing on the receiving end to act as a standard printer (such as those using the ESC/POS printer control language)? It seems like Windows does not treat the rpi as a printer. What am I missing here?

  • Did you specify the correct speed for the printer? Is there a reason why you don't use the network? – RalfFriedl Jun 12 '19 at 03:14
  • My use case is the following: there is a legacy system (POS) which prints receipts via the COM port. That is why I have to use that interface =\ – Martin Löper Jun 12 '19 at 16:19
  • I do not know how to find out the exact settings which the POS places on the serial interface (COM port). I just guessed the baudrate and other settings (from above), by opening the windows settings for the COM port. However, I do not know if applications can override these settings when opening a connection. – Martin Löper Jun 12 '19 at 16:21
  • There are not many common speeds, you can try them. You can also look at the printer port settings. In the Windows spooler, is the job considered done, or does it stay in the queue? – RalfFriedl Jun 13 '19 at 16:49
  • Thanks for your hint Ralf. Unfortunately, the baud rate was not the issue. If the baud rate would have been an issue, I would get an input at the rpi side which is malformed. However, I did not get any output at all which was because of Hardware flow control being enabled on WinPC and not understood by the rpi. – Martin Löper Jun 16 '19 at 01:32

2 Answers2

2

Thanks for the comments and answers which guided me into the right direction!

It turns out that the following was the issue: The Windows software which sends the printing jobs uses Hardware flow-control and the rpi does not support it out of the box with common rs232-gpio adapters such as [1].

Since I did not write the software nor was I able to decompile it, I had to turn on a COM port sniffer and observe the low-level API calls to find out what was going on.

I used HDD Serial Port Monitor [2]. The following showed up:

005163: I/O Request (DOWN): 2019-06-12 23:41:07,2618080 +0,0000064
 IOCTL_SERIAL_SET_HANDFLOW: Set handshake information
    · Control lines        = SERIAL_DTR_CONTROL | SERIAL_CTS_HANDSHAKE (0x9)
    · Flow control         = SERIAL_RTS_HANDSHAKE (0x80)
    · Xon Limit            = 256
    · Xoff Limit           = 256


005164: I/O Request (UP): 2019-06-12 23:41:07,2618112 +0,0000032
 IOCTL: IOCTL_SERIAL_SET_HANDFLOW (0x1b0064)

The SERIAL_CTS_HANDSHAKE part indicates the use of hardware flow control. Another control message which indicates the use of hardware flow control is the following one:

005178: I/O Request (UP): 2019-06-12 23:41:12,4249200 +0,0000112
 IOCTL_SERIAL_GET_COMMSTATUS: Retrieve COM status
    · Errors                    = 0
    · Hold reasons              = SERIAL_TX_WAITING_FOR_CTS (0x1)
    · In queue                  = 0
    · Out queue                 = 0
    · EOF received              = false
    · Wait for immediate        = false

The Windows PC was waiting for the CTS signal to go high (as indicated by SERIAL_TX_WAITING_FOR_CTS).

I solved this issue by shorting the CTS and RTS lines in the serial cable on the Windows PC side.

[1] https://www.reichelt.de/raspberry-pi-konverter-gpio-auf-seriell-rpi-gpio-2-rs232-p154883.html
[2] https://www.hhdsoftware.com/serial-monitor

1

Question

Why Rpi cannot pretend to be a serial printer, receiving printer data stream from WinPC?

Answer

Well, WinPC to Rpi can send and receive text over UART without any problem.

But for WinPC to print something, Win need to handshake with the printer first. For example, WinPC might say, "OK, so are you a printer?" If WinPC gets the reply from the other side such as "Yes, I am a printer, send over stuff to print". Then WinPC starts sending something.

In other words, WinPC and Rpi need to speak a printer language.

Moreover, the simplest WinPC/Rpi serial cable may consists of only 3 lines, TxD, RxD, and Ground. But many serial cables for printers may contains up to 9 lines for miniature serial cables (DB9) and up to 25 pins for standard serial cables (DB25). The extra signals beside TxD, RxD are CTS (Clear To Send), RTS (Request to send) etc. See Appendix A below for more details.

References

Epson Standard Code for Printers - Wikipedia

Hewlett-Packard Printer Command Language - Wikipedia

IBM Personal Printer Data Stream - Wikipedia

Appendices

Appendix A - Honeywell Printer Cable Example

honeywell printer cable

tlfong01
  • 4,384
  • 3
  • 9
  • 23
  • Thank you for the detailed answer! That makes sense indeed! However, I do not know how to find out which "printer language" windows speaks for a Generic Printer. Do you know how to find out how the serial at the rpi must be configured, e.g. is there any microsoft documentation or a standardized protocol. As far as I understand the ESC/POS communication takes place once the serial connection is established. But in my case establishing the serial connection is the issue because I cannot read any data at the rpi end. Maybe windows thinks the printer is busy... – Martin Löper Jun 12 '19 at 16:17
  • @Martin Löper, to check out what the Win7 side is speaking at the start, I suggest not to use Rpi for now, and use a WinPC program called "Real Term“ (google "Real Term" and "SparkFun") . Connect TxD and RxD at the far end of the serial cable, to loop back what is sent from Win. RealTerm can log long strings. So you can study the string at leisure. This post has something about "RealTerm" - https://raspberrypi.stackexchange.com/questions/96184/serial-to-arduino-totally-non-responsive – tlfong01 Jun 13 '19 at 01:17
  • There you are - RealTerm info from SparkFun - https://learn.sparkfun.com/tutorials/terminal-basics/real-term-windows Now you can loop back TxD to RxD to check out what Win7 says when handshaking with the printer. – tlfong01 Jun 13 '19 at 01:47