Closed mikeditto closed 1 year ago
HPGL file that generated the above plot:
Overall I see two possibilities how sending too much data without breaks could cause issues. Either device can't physically keep up with commands sent and there is no proper flow control. Or some of the buffer handling doesn't properly handle when there is too much data in single "chunk".
Since the process is spooled and goes through the linux printing system. I don't think there is much we can do to send the data slower. Although if this was the problem and there was no flow control in the communication at all I would expect that once the fails to keep up it would corrupt a lot more than single point.
So it seems more likely that some flow control is there, but it doesn't work quite right and corrupts a byte when some buffer fills up.
Looking that positions of corruptions "Hello" seems like the corrupted point happens every ~ 68-72 bytes. Will later try to write a script to more precisely test this theory.
@mikeditto Are you interested in cooperating to further investigate this problem? It likely won't result in much better fix than what you already sent, but who knows. If you have no interest at all feel free to ignore the following, otherwise if you need more help with any the stuff bellow let me know.
I am curios how exactly your system recognized as printer. Can you send the output of lsusb -v
just the block corresponding to plotter is fine. Also I wonder if Cups has found a .ppd it. What do you have in /etc/cups/printers.conf
and /etc/cups/ppd
?
Third potential interesting thing to look at would be at the raw USB packets with and without the extra newlines. That should make it clearer whether extra newlines have effect on how cups sends the data to device or if it's purely on device end. Should be doable using wireshark and usbmon. Just a reminder that when you capture usb trafick it might also capture data from other USB devices on the same bus. So if you are not sure about properly checking and configuring that, you might want to avoid having usb security devices (stuff likey ubikey) attached or typing passwords during capture or send me the capture results privately.
I could probably also prepare some test hpgl files to better confirm the nature of when exactly corruption happens.
Here is the syslog excerpt from the first time I plugged it in, showing the USB enumeration and lp auto-setup:\ syslog.txt
Here is the printers.conf excerpt:
<Printer MH365>
PrinterId 548
UUID urn:uuid:a44e6149-7f33-3ea7-616f-2cd97ca489ac
Info Series
MakeModel Generic Text-Only Printer
DeviceURI usb://USCutter/Series
State Idle
StateTime 1672681982
ConfigTime 1672282426
Type 12292
Accepting Yes
Shared Yes
JobSheets none none
QuotaPeriod 0
PageLimit 0
KLimit 0
OpPolicy default
ErrorPolicy retry-job
</Printer>
There is a quite large PPD file but I think it is generic, it starts with
*PPD-Adobe: "4.3"
*%%%% PPD file for Generic Text-Only Printer with CUPS.
*%%%% Created by the CUPS PPD Compiler CUPS v2.3.1.
*% (c) 2014 OpenPrinting
*FormatVersion: "4.3"
*FileVersion: "1.0"
I will upload it if you want but as I said, I think it is completely generic for plain text printers.
Here are the USB descriptors:
lsusb -v -d 7447:
Bus 001 Device 031: ID 7447:5419 GenesysLogic USB2.0 Hub
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x7447
idProduct 0x5419
bcdDevice 12.08
iManufacturer 0
iProduct 0
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0020
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 64mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 7 Printer
bInterfaceSubClass 1 Printer
bInterfaceProtocol 1 Unidirectional
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 0
Device Status: 0x0000
(Bus Powered)
Yes, I would enjoy working on debugging this problem further and am willing to spend some time on it to get a better understanding and better solution.
I have a USB analyzer and could capture some data transfers.
I, too, had thought of preparing some reduced HPGL data to narrow down where the glitches happen; my first step there was to insert the newlines so that I could more easily use an editor to trim the data down... but voila, the problem was fixed. :-)
Incidentally, I have used another MH plotter successfully with Ubuntu and inkcut a few years ago. It was probably an MH-721 but I'm not sure. But I used it via a USB-RS232 cable and the plotter's RS232 port. I suspect that if I did that on this plotter it also would work (I think all the MH series plotters are identical except for mechanical differences - width and stand, etc.). In other words, I suspect it's a problem with the plotter's USB implementation.
removing every 72th aligns perfectly with most of HELLO, but it doesn't hit the position which causes spikes on O.
Also I am not sure how it manages to only produce horizontal spikes but no vertical ones. My theory was that horizontal spikes happen when one of digits in X coordinate gets removed resulting in 3digit number which small but not identical to others. But if it works that way
So I guess the defect is little bit more complex than simply dropping every nth symbol. Maybe it gets overwritten by some junk value thus resulting in somehing that's harder to guess but still repeatable on the actual hardware.
I'm going to collect some captures at the syscall and USB level.
But I already made another small discovery that probably explains everything:
If I send the file using cat test.hpgl >/dev/usb/lp1
instead of lp -d MH365 test.hpgl
the plotter receives and handles it correctly.
This suggests it is not USB or the kernel or the plotter causing the corruption but the lp/CUPS subsystem.
I will investigate further, but right now my guess is that this will not require an inkcut change at all, but simply a change to lp configuration or configuring inkcut to use the device directly instead of the lp printer.
I will investigate further, but right now my guess is that this will not require an inkcut change at all, but simply a change to lp configuration or configuring inkcut to use the device directly instead of the lp printer.
Sure enough, adding -o raw
to the lp
or lpr
command makes the problem go away.
I modified inkcut/device/transports/printer/plugin.py
- self._protocol, 'lpr', ['lpr', '-P', t.config.printer]
+ self._protocol, 'lpr', ['lpr', '-P', t.config.printer, '-o', 'raw']
and now the file plots/cuts correctly from inkcut.
That is probably an appropriate fix so that even if the CUPS printer is nominally mis-configured, inkcut can still spool HPGL through the printer system.
I got a new MH-365 MK2 plotter and hooked it up by USB to my Ubuntu laptop, which recognized it as a printer. When sending HPGL from inkcut (or directly using the
lp
command) it corrupts some commands, either dropping them or mis-interpreting the X coordinates. See attached photo of pen+paper plot that went wrong - same file sent two times, corruption is nearly identical.I discovered accidentally that appending a newline to each command fixes the problem. I will send an inkcut patch to allow adding this padding.