Close

If You Can't Beat 'Em, Beat 'Em Into Submission

A project log for HP 82240B IR Receiver and Printer Interface

This is an IR receiver and interface for adapting a commodity receipt printer to be 82240B-compatible.

ziggurat29ziggurat29 07/21/2017 at 02:340 Comments

Summary:

A quirk of one of the printers, the APS EPM203-MRS, could not be disabled, but was worked-around.

This project is now functionally complete.

Deets:

Yesterday I had mentioned that one of my printers, the APS EPM203-MRS has a quirk whereby it gratuitously advances the paper before printing bitmaps.  Moreover, it only does this sometimes, when there has not been prior output for 'a while'.  This made my output look weird on that printer, and I don't like weird things.  (OK, that's a general lie, but in this limited case, it's true.)

I scoured the manual looking for some way to turn off the paper advance feature/wart/whatever.  Look as I may, and look as I might, there was no such feature found that night.  I spoke 'the uncommon words of anguish', and retired for the night.

This morning I awoke to discover that I had turned into a giant cockroach.  This situation only lasted a few minutes, but when it had ended I was left with a kooky idea:  maybe I can just compensate for the paper advancing by doing a reverse paper feed before emitting the graphic.  The sand in that vaseline is that the paper advance only happens /sometimes/, after there has been a period of output quiescence.  If the data stream keeps coming to the printer with some reasonable pacing, no gratuitous paper feed is done.  (Thank the maker for that little blessing -- really every horizontal line of pixels is it's own distinct graphic.  It would be quite a mess if there was a paper feed between each horizontal line!)

So, sometimes, if you are faced with an inability to make things reliably the way you want them to be, you can as an alternative approach make them reliably the way you /don't/ want them to be.  If I can make /every/ graphic output reliably have the unwanted paper feed, then I can reliably always do the workaround of the reverse paaper feed beforehand.

The approach I took wound up being a fairly surgical change:

OK, subtle detail on the timer rollover:  we covered the usual case of 'I started just before the counter rolled over, and checked after it did, how do I handle that' with the unsigned 2s complement subtraction, but there is another issue when you rollover twice or more.  Then the 2s complement doesn't help you.  OK, the timer rollover will happen after 49 days, so you'd have to wait twice that time, so over 3 months of powered on but disuse before you'd be at risk of it.  But I'm taking this thing to Jupiter and I can't have Hal telling me 'I'm sorry Dave, I can't open the pod bay doors until I get the output from your thermal printer.' and have to wait for 49/2=25 days while oxygen runs out.  (Hal does love its petty torments.)

So I covered that scenario with a little hack.  A 'haque', really -- it's not that dirty.  The printer rasterizer process blocks waiting for a signal that a birmap is ready to be rasterized.  That blocking has a timeout, which I arbitrarily set at 5 seconds.  The intention of that is to let the thread awaken to realize that there hasn't been anything to do for a while, but that is nonetheless still alive, and it can just carry on blocking again.  This opportunity can be used to reset watchdogs or other idle-time activities.  In this case, I made an idle-time activity of forwarding notification of that event into the rasterizer.  The rasterizer then simply updates the last transmit time (g_nLastTx) to 'now'.  It's not /really/ the last transmit time, but I only care about the time difference being below a certain amount, so just means that g_nLastTx represent 'it happened at least this long ago in the past, but maybe longer'.  OK, so now it's safe to go to Jupiter....

The result... worked.  It was interesting.  It certainly made for quite a jittery printout experience, I could possibly embed a covert Morse code signal in the jumpiness, or maybe the printer can double as a massager.  I became practical again and decided to 'window' the jitterbug action into an upper bound (which I had already done:  if there hasn't been enough time, sleep and then do the reverse feed), and a lower bound (if new output has come in surely and safely soon enough, then don't even jitterbug at all -- just do like all the sane printers do and send data freely).

This worked best.  Here is the new final result, side-by-side with a real HP printer output.  I set my contraption near the HP printer, so their bathing in the same sunlight and outputting simultaneously from the same IR signal.

Pretty darn close!  I marked the two printouts 'HP' from a real HP82240B printer, and 'APS' from this project using the APS EPM203-MRS driver (the GoojPrt driver is also supported.  The Kashino driver is incomplete -- that printer doesn't have flow-control, so I would need to add transmission pacing before I could call that 'supported'.)

This takes it about to the limit of what I intend to do on this project at this time.  The physical differences in the printer mechanisms preclude getting the output pixel-perfect, but I think for practical use, this is more than serviceable.

The next thing I want to do is shoot a video of the thing live and in operation, but I need to get a tripod and a camcorder from a friend.  In advance of that, I think I'm calling this project is 'complete' for now.  I do intend to come back to it for the 'monitor' implementation to support various enhancements, but I have other projects calling for my attention just now, alas.

Next:

In the near term, I'm goign to try to shoot a demo video.  Also, I would like to get a better power supply for the GoojPrt so I can turn up the darkness on that unit.

Longer term, I may revisit it for the 'monitor' enhancement.

Longer longer term, I may look at interfacing directly with the printer core, rather than the printer with module.  The printer core is closer to the metal of the stepper motors and the thermal head.  This part is cheaper than these panel printers.  The panel printer I am using here is useful for integrators, because it has a controller board that exposes a high-level print language and controls those lower level electronic elements.  However, why do I need that here?  This controller is already low-level, so why not interface directly.  And SOOOO much more CONTROOOOOL!  But that sort of project -- fascinating as it might be -- is really more towards producing an actual product you want to build and sell in scale, rather than just fiddling with stuff one-off.  So, that will probably never happen.  Alas...

Discussions