How do I handle a printing queue when the USB printer is busy?

Oct 22, 2026 Last reply: 1 day ago 4 Replies

First reply

CedarFixer

I hit exactly this wall with a receipt printer on a Pi 4 that prints shopping lists and a chore rota. My first attempt at a status check was the printer's own status command, the one where you send a couple of bytes and wait for it to reply. Do not do that over USB. Some…

Read the full reply

I am trying to get a Raspberry Pi to print scheduled updates, like a daily family menu, using a thermal receipt printer plugged into the USB port. The scheduling part works fine, but the actual printing seems to get stuck if the printer is doing something else or if I try to print a document while it is out of paper.



Right now, my script just sends the data and then assumes it worked. If the printer is busy, the script just hangs for a long time. I'm looking for a way to check the status before I send the print job. There are a few kernel ioctl calls I've read about that might work, but I am worried about messing up the USB connection or locking the whole link.



Does anyone know a clean way to check if the device is ready or if it is just busy so I can put the job into a proper queue and try again later? I am using the generic usb-to-printer driver so I am avoiding specific printer utilities.


I hit exactly this wall with a receipt printer on a Pi 4 that prints shopping lists and a chore rota. My first attempt at a status check was the printer's own status command, the one where you send a couple of bytes and wait for it to reply. Do not do that over USB. Some printers just never answer if something is wrong, like the cover open or the cutter jammed, and your write sits there waiting til the whole connection is wedged. I had to unplug the printer to get the link back. The fix is the status read that the usblp driver allready supports. If you open /dev/usb/lp0 and issue an ioctl with LPGETSTATUS, the driver sends a quick control request over USB and hands you back a status byte. Nothing stays pending on the device side, so it cannot hang or lock the link. The bits in that byte tell you paper out, cover open, and a few error conditions. Check it, and if anything is wrong, park the job.

My flow now is: check status, and only if it comes back clean do the actual write. If the printer is busy or out of paper, the job goes back in a little queue on disk and a timer retries every minute or so. Tickets that failed overnight just print in the morning once someone refills the roll. Also open the device non-blocking so a write can never stall your script even if something odd happens between the status check and the send.

One extra tip: read the status right before every job, not once at startup, because the printer can sit fine for hours and then run dry mid-day. That has saved me more than once.

I'd push back on the non-blocking advice though. Opening the device non-blocking doesn't stop a write stalling, it just makes it bail out instantly with an error instead. If your script ignores that return code you end up sending half a receipt and never knowing. I ran that exact setup for a chores list and learned to treat a failed or partial write the same as a bad status check, shove the whole job back in the queue and retry from the top. Also worth printing a test job with the cover open once so you actualy know wich bits in that status byte matter for your model, they aren't the same across printers.

One thing that bit me on my kitchen printer setup, a Pi Zero 2 W with a 58mm roll printing at 6:45 every morning, was the write itself hanging even when the status looked fine right before it. Race between the check and the send. What saved me was wrapping the whole print command in timeout with 15 seconds, so if anything wedges the job just dies and goes back in the queue instead of the timer stalling all day. Costs nothing to add and my retry loop has run clean for about eight months now.

Update: took the timeout advice and wrapped the whole write in one, and it fixed the hanging. Now I have the opposite problem, when the timeout fires partway thru, the printer spits out half a receipt. That lines up with what the second reply said about bailing mid-write. So do you just buffer the whole job, check the status again, and resend the entire thing from the top?

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required