Hmm… maybe I spoke too soon.
No sooner had I congratulated myself on a completed project than a problem raised its ugly head. And it was one that required some tracking down. And so, as this blog is my lab notebook, I thought I’d share what happened, as I always find other people’s tales of troubleshooting to be illuminating.
One morning, I decided to add an extra capability to the spprintfile program I’ve written in Go. This is a command line program intended to run on a Raspberry Pi host which reads plain text files and send them for printing to the SmartParallel.
I added a mode switch to allow printing in condensed (132-column) and wide (40-column) modes in addition to the normal 80-column. And it worked fine – at first. (Well, okay, the wide mode doesn’t work and I’ve abandoned it, but anyway…)
Something weird happened. The next time I printed, some of the text went missing. Lines got jumbled together, with missing characters. Some lines weren’t printed at all.
I wondered if the sending of control characters to the printer was causing the problem and made several changes to the Go code to try to account for this. But nothing made sense.
And the problem was getting worse. More and more characters and lines disappeared each time I printed.
Checking the connection
Could it be a serial problem? Were characters getting swallowed along the way?
I could tell that the Go code was interacting with the SmartParallel. The code has a debug mode (using the -d switch on the command line) that provides additional information. This told me that the CTS line was going high and low – under the control of the SmartParallel board – in expected ways, and the Go code wasn’t timing out at all.
So I was sure that text was being sent and at least some of it was being received.At the very least, the null terminator byte at the end of each line of code must have been received, otherwise the SmartParallel wouldn’t have switched the CTS line high after each receive.
Next, I connected the logic analyser to the SmartParallel’s serial port. And, sure enough, I could confirm that the messages from the Raspberry Pi were coming through cleanly, and the SmartParallel was responding properly both by controlling the CTS line and sending back appropriate messages.
I eliminated the serial port as a suspect in my enquiries.
During my tests, though, things were getting worse. More and more of the messages were failing to get printed. Eventually, nothing was getting printed at all.
The code on the SmartParallel hadn’t been changed since the device was working fine, so although I did peruse the code in case there was some weird corner case I’d overlooked, I was confident the software on the board wasn’t the problem.
Also, although nothing was getting printed, the SmartParallel continued to interact normally with the Raspberry Pi. The Go code would send a line of text, the CTS line would go high, the Busy LED on the SmartParallel – which is under the control of the printer – would briefly come on, then off, followed by the CTS line going low. And then it would all happen again with the next line.
As far as the Raspberry Pi was concerned, everything was working, if a little faster than normal.
The Busy light was intriguing. The printer activates the Busy signal when it receives a pulse on the /Strobe line from the SmartParallel. This happens each time a byte is sent. A quick probe with the oscilloscope confirmed that, indeed, the /Strobe signal was being sent as expected. This signal is controlled by the ATMEGA328PB microcontroller via a 74LV541 buffer. I satisfied myself that both of these are working as expected.
Also, the SmartParallel recognises when the printer is offline or online. So the signals running to and from the printer via the buffer seem to be operating okay.
Suspicion started to fall on the 74LV595 shift register. This is what’s used to set the eight data lines to the printer.
I’d hand-soldered this copy of the SmartParallel board. The 74LV595 I used is a SOIC-16 package – small, but not ridiculously so. That said, a close look suggested that some of my solder joints on the IC’s legs were, shall we say, a bit too creative. I’d had a slight issue with some of them because I’d made the mistake of soldering on a nearby decoupling cap first, which made getting to a couple of the legs awkward.
I touched up a few of the joints and tried again. Not much difference, except that, every now and then, a few characters would appear on the printer. These were not characters that should have appeared, but neither were they random. I always got the same string:
But then something else odd happened. I decided to probe one of the data output lines with the oscilloscope, to see if it was getting set at all. I did this by pressing the probe down on one of the pins of the 74LV595. Sure enough, it was flipping between high and low. I couldn’t relate this to any specific bit of text, but here’s the thing – while I was probing, the Epson starting printing the text again. It wasn’t complete – it was back to having missing bits – but it was printing.
This strongly suggests the shift register chip is dodgy. I did end up doing quite a lot of soldering and resoldering on it. Maybe I damaged it during that process. Maybe the solder joints, while looking okay now, are still a bit iffy.
I decided to do one last bit of clean-up and retouching of the joints. If I’d already damaged the chip with soldering, what did I have to lose? I can’t remember if I subsequently tested the board again that night – it was getting pretty late.
And I started to plan what to try next:
- I have a little grabber-like tool that latches on to chips and allows you to probe all the lines. If I could get this to stay in place, I could sic the logic analyser on the shift register and see what’s happening on the data lines.
- I have male and female DB-25 breakout boards. I could wire these back-to-back as a kind of pass-through cable that would allow me to probe the printer connections, including the data lines, that way.
- I could probe each data line on the chip one-by-one and stitch together the results.
None of these methods was particularly attractive, but I was getting desperate.
Oh no, it works!
This morning, just to double-check the nature of the problem, I tried again. It worked.
I mean, flawlessly.
I’ve now printed several files. I even printed out all 389 lines of the Go program source code (that took a while). Yes folks, I’m printing program listings on a dot matrix printer like it’s 1982. Without a hitch.
Either that last bit of cleaning up of my soldering fixed the issue or I’m facing that most heinous of all problems – the intermittent fault.
But hey, let’s be glass half full about this. In any case, I plan to make up a couple more of the boards using reflow soldering.
Although I now have a nice printout of my program, the Epson, bless its heart, decided it doesn’t like tabs, so there’s no indenting of the code. (And I don’t want any tabs-vs-spaces comments. I prefer tabs, alright? Get over it.)
It seems that the Epson will ignore tab characters (ASCII 9) unless you have set up tab positions. You do this by sending ESC D (ASCII 27, ASCII 68) followed by numbers specifying tab positions (up to 12) followed by a null byte (ASCII 0). I tried several ways of doing this. They didn’t work and it was getting messy. Plus, you’d need to do this after each reset of the printer. Bah!
In the end, I added a bit to the routine that checks incoming bytes so any tab characters (ASCII 9 or ASCII 137) get replaced with spaces – four spaces if there’s room in the buffer or a single space if not. It works well enough and I’ll probably add functions to set the tab sizes programmatically.
Oh, and that mysterious ->TAbtc[ string? Who knows? ¯\_(ツ)_/¯
So that’s it – back to a working device. Let’s see if it’s still working tomorrow…
[UPDATE 04/11/2019] Gah! After working without issue for a few days, I left the SmartParallel and Epson switched off for a while and now… back to the state where text is being sent to the SmartParallel, the Busy light is flashing briefly, but nothing’s getting printed. So there’s still work to do…