Look at those huge, razor-sharp image prints! You want some?
The following…
- Is an undocumented printer feature and is NOT guaranteed to work.
- May require modifying your printer — a warranty-voiding operation! Continue at your own risk.
You should only attempt this if all of the following apply:
- Have first confirmed that the printer works as expected when operated through conventional procedures.
- Have a genuine performance bottleneck that cannot be adequately resolved by adjusting the printer timing and thermal settings first.
- Are comfortable opening things and soldering.
These printers have a limited serial receive buffer. Push bits to the printer faster than it can physically heat dots and feed paper, and you experience an “overflow” — bitmap images become garbled, text and formatting commands may be skipped.
The thermal printer library tries to throttle data to the printer at just the right rate. Too fast and an overflow occurs. Too slow and it wastes your time; the printer isn’t operating at peak throughput. This is an imperfect process…though we use very conservative timing estimates, the actual speed through the printer is impossible to predict…sometimes overflows still occur.
Hardware handshaking is a means by which a printer or other device can report to the microcontroller that it’s ready to receive more data, virtually eliminating buffer overflows while operating at peak throughput…the paper feed stops only when it physically absolutely must. Optimal performance.
It appears that some varieties of these thermal printers support hardware handshaking (e.g. firmware v2.64, 2.68). This is barely mentioned in the datasheet, and in fact there isn’t even a physical connection for this on the outside of the printer. A little surgery is in order…
Parts and Tools Needed
- Small Phillips head screwdriver
- Pliers
- Soldering iron and related paraphernalia
- A bit of wire…but ideally a female jumper wire
Take the back plate off, then remove the two (or sometimes four) Phillips screws holding the circuit board in place.
These screws are a little smaller than the back-holding ones…don’t get them mixed up!
Carefully, so as not to unseat or unplug the connectors, turn the circuit board over and look for the unpopulated via labeled “DTR.”
There are some other interesting solder points in here, if you’re so inclined. “HV” is the raw 5–9 Volts from the power supply. On the right is a 3.3V pin, though I don’t know the available current. Conceivably one could bring these out to reduce overall cabling in a project…or even install a tiny microcontroller right inside!
Cut an end off a female jumper wire and strip & tin the end.
This will be hanging out of the printer…so a female jumper prevents accidental contact with things if you’re not using the connection. If you only have regular wire, that’s fine, just be careful not to leave a bare end dangling.
Solder the wire to the DTR pad. Top, bottom, doesn’t matter…it’s right up against the serial connection plug, so use whatever path works best for you, there’s ample room for routing the wire around either way.
Language pedants may note that this isn’t technically a DTR pin, but rather CTS. It’s long-standing thing among printer manufacturers…apparently the misnomer was made decades ago but has stuck for consistency.
On the back plate, there’s a small metal “finger” between the serial and power sockets. Using pliers, this can be bent back to provide an exit route for the DTR wire.
Screw the controller board back in place (check that neither of the cables has come unseated), routing the DTR wire around between the two sockets, then screw the back on.
Finished with the hardware!
You can then reconnect the power and serial sockets, and wire those up as before.
Use a jumper wire to connect DTR to any available Arduino pin. In our examples, we’ll use digital pin 4.
The printer electronics operate at 3.3V (but are “5V safe”), so no level shifting is needed with 3.3V boards (Arduino Due, etc.)…this can safely be connected directly.
Code Changes
Just one line…the Adafruit_Thermal constructor…needs changing. It can accept an optional parameter, a pin number to use for DTR:
Adafruit_Thermal printer(&mySerial, 4);
This works just as well with a hardware serial port (e.g. Arduino Mega or Due):
Adafruit_Thermal printer(&Serial1, 4);
No other changes are necessary. Try this with one of the example sketches…you’ll find the printer is suddenly lots faster! That’s because the software throttle is no longer used…the printer continually reports its actual “ready” state to the microcontroller.
The printBitmap() function can output images from an open stream or stored in PROGMEM (flash memory)…as explained on the “Printing Bitmaps” page.
Although the Arduino Mega has a whopping 256K flash space, a limitation of the AVR microcontroller is that a single array can’t exceed 32K…that’s about a 384x680 pixel bitmap image. If you try to embed a larger image in your code, the compiler will report an error.
One workaround might be to break really long images into multiple smaller images, and print these out consecutively without a feed() in between.
Another is to use a non-AVR Arduino-compatible board, such as the 32-bit Arduino Due. This has no problem with massive arrays. The Chrysler Building image above is 384x1132 pixels!
Other Things to Know
This type of printer fares best with light line art and sometimes dithered photographic images as long as the overall dot density is fairly low, like under 50%. Large solid-filled areas exhibit strange streaky artifacts…this isn’t a bug of the library or printer firmware, but just a side-effect of how receipt printers operate, that they can only heat so many dots at a time and have to pull shenanigans to go beyond that, else they jam.
Here are a couple examples from fancy commercial receipt printers.
Notice in the first one that the “solid black” area isn’t really solid black…examining it closely, you can see it’s densely dithered, but not 100% filled.
The second does have solid fills, but limits the total area. On any given row, only so many pixels are set.
If you try to print a “dense” image and the paper jams (image gets squashed vertically), pass a lower density value to printer.begin(). Default value is 120. So for example:
printer.begin(80);
DTR support is not a panacaea. Glitches occasionally do still happen…sometimes overflows, sometimes “framing errors” with serial data. But overall it seems fairly reliable and buttery smooth!
Text editor powered by tinymce.