edrosten/adafruit-thermal-printer-driver

Printer is out of paper

0x62 opened this issue · 8 comments

0x62 commented

Hi @edrosten. First of all, thanks so much for putting this together, the Adafruit driver seems to be completely broken on recent models.

I've got a weird error where it usually prints fine, but if the device runs out of paper it's impossible to reset it. Tried pushing the paper feed button, restarting CUPS, restarting printer, opening cover but seems to have no effect.

This also sometimes happens even when there is paper in the device.

Hm this is interesting. I might have seen it before but was unable to reproduce the bug.

The paper out detection is pretty sketchy to be honest: none of the proper methods really work (not sure if you've read my excessively long blog post on it). The only way I found of detecting paper out was by abusing an entirely different feature of the printer.

After sending each line of pixels, I send a printer command that simply sends a byte back. That way I can count the number of bytes, i.e. lines returned. If that number stops incrementing, then I assume the printer is out of paper, and report this to CUPS. I also track the difference in lines sent and lines processed and stop sending data if that's too large, since I have a strong suspicion that there's a bug in the buffering and the printer just starts trashing data if you send too much.

CUPS doesn't do much with the info except inform you. This logic is entirely in the driver program (not CUPS itself or the printer), which probably explains why resetting everything except that doesn't work. CUPS sets jobs running in the background precisely so CUPS going down won't kill a big print job.

If you can find the pid of the program (maybe pgrep rastertoadafruitmini) you can kill it and at that point you might be able to send new jobs. That would also confirm my hypothesis that it's the driver getting stuck.

There are solutions, but since I wasn't able to reliably reproduce the bug I don't know what will work.

Looking at the code, I now have a hypothesis this might underflow. If the computer zones out for a while and stops sending lines to the point where the printer prints everything in it's buffer, I think it will stall out entirely, since it won't send the ping bytes back and so the number stops changing.

I'm going to prep a branch which might fix the bug.

hmm actually scratch that. I'm no longer sure that's right. Do you have the logs anywhere?

My diver is quite verbose and should have spammed the CUPS logs full of debug messages.

Double scratch that. I need to read the code REALLY carefully 😆

OK, so if you can trigger this problem, then send me the CUPS log that would be really handy.

In the mean time, you might be able to mitigate it:

one choice is to increase the timeout which might make the problem rarer. On line 132 of the .cc file, change 2500ms to something larger like 5000ms or even 10s. I doubt a 10s pause before detecting paper out would be terrible.

Another option is to disable paper out detection entirely. If you comment out or delete these lines (line 409):

			transmit_status();
			lines_sent++;
			wait_for_lines(lines_sent, read_back, 80);

that will remove all the paper out and buffer control. If the printer line count is flakey (this wouldn't be unexpected, everything about the USB version is. Someone clearly just shoved a USB-serial chip on a printer that was designed to be RS-232 plus extra control lines. I suspect then no one tested it for long print jobs because who on earth is printing more than 10cm of receipts at a time 🤣) then removing buffering could work, but it might cause corruption too since the printer buffering is also flakey.

Would it be possible for you to try those two? I don't have a printer right now, and I could never trigger the failure mode anyway.

0x62 commented

Edward – first of all, I'm so sorry it took me this long to respond to this issue, I'm really grateful for your very detailed response. I ended up getting very frustrated with the project and put it back on the shelf, then life got in the way and I completely forgot about it. Recently I've had more time, and decided to take another look at getting it working.

Completely understand if you're not interested in helping debug this further, but I've followed the above suggestions and produced a writeup of the results along with images and the error log:

https://github.com/0x62/adafruit-printer-debug

Please let me know if you have any more ideas. I'll continue to update the repo with my attempts, and hopefully will serve as a resource to get this working again as it seems Adafruit has abandoned support for it.

Can you send some plain text to the printer? Is it a serial or USB printer?

0x62 commented

It's serial. On a fresh install I was able to run gv2_thermal_printer_config.py successfully, and it is now printing text and images via the Adafruit driver without garbage, however the print quality isn't great (which leads me back to why I found your driver!).

IMG_0120

Even with the printer reconfigured by the adafruit setup script, I still hit the same issue with printer out of paper using your driver, however it no longer prints garbage like in my attempt #2 in the debug repo.

I also ran into an odd issue with this driver when printing photos via network via the iOS print dialog. For most prints it works fine, but sometimes instead of printing an image it just spits out endless garbage text that exhausts the entire print roll.

Can you try disabling the out of paper check (the note I sent above).

I'm not going to lie, the out of paper check is a massive hack. I think the printer is designed to run off a serial port, but doesn't really work properly off USB (the model I had). But I thin kit does paper checks differently on the serial port (the documentation implied this but wasn't very clear). Not having a paper check will mean CUPS can't report anything, but if the printer is right next to you, it doesn't matter.