A major reason for doing breadboard prototypes is to learn what mistakes you’ve made in your circuit design. Of course, it’s also a way to introduce brand new errors.
Before committing to fabricating PCBs, I wanted to check out whether my design for the SmartParallel dot matrix printer interface would even work. My confidence was reasonably high because, months ago, I’d got a prototype working. But that one didn’t exactly represent the design I finally came up with in KiCad. Maybe I’d introduced some stupid ideas. (Spoiler alert: I had.)
I’d already made myself a prototyping kit. This consists of a breakout board with zero insertion force (ZIF) socket for the TQFP32 version of the Atmel ATMEGA328PB microcontroller mounted on an acrylic base alongside a breadboard.
I’d also hacked together a DB25 socket with DuPont-headed cables. So it should really be quite easy. It was just a case of plonking the ICs, LEDs and resistors on the breadboard and wiring it all together.
I’ll spare you the detailed agonies other than to say that, with so many cables flying about, it’s easy to get your wires crossed. Literally.
To give an example, the circuit includes a 74HC595 shift register that creates the signals on the eight data lines and whose inputs are the store/latch clock (STCP), the shift clock (SHCP) and the serial data line. And it almost worked.
The data lines are connected to LEDs, and so, in the initialisation section of the code, I have the microcontroller switch these on one-by-one and then turn them all of again, just to show everything’s working. Well, they came on, one-by-one – except for the last one.
I was convinced the error was in the code. It took me hours to realise I’d swapped the STCP and SHCP wires where they connected with the microcontroller. With that fixed, all was well.
Thinking about pullups
There were other issues that aren’t worth relating here. Along the way, however, they got me thinking about pullup resistors. I’ve put 10kΩ pullups on several of the signal lines that are active low. And I wondered, do I really need them?
So I decided to have a poke about. I disconnected the printer cable from the SmartParallel prototype and measured the voltages on the cable pins with the Epson switched on – ie, the voltages being set by default by the printer.
Then I did a similar thing with my old Dell Dimension 4600, to see what voltages are set by a commercial parallel printer interface. Finally, I connected the Epson to the SmartParallel with both powered up and measured the signals on the wires going between them. This is what I found.
|pin||function||Epson||Dell||Epson & SmartParallel|
|12||PAPER END (PE)||0V||5V||0V|
Perhaps the first thing to notice is that both printer and Dell interface clearly use pullups for most of the signals – including the data lines. The data lines are 0V with SmartParallel connected because that’s the default level that the software sets them too, so all’s well there.
The BUSY and PE signals are active high but the printer is pulling them low (the printer was in the ‘ready’ state so that’s to be expected). /STROBE, /ERROR and /INIT are all properly high. These have pullups on the SmartParallel prototype, so that’s good.
But the results did cause me to wonder if I properly understood the SELECT, /SELECT-IN and /AUTOFEED signals (all of which you’ll find by other names – I’m using Epson’s nomenclature). It turns out the answer was no.
Understanding the signals
Let’s start with SELECT. You’ll sometimes see this described as active low, but I think this is wrong.
SELECT is an output from the printer. It’s high when the printer is ‘selected’ – that is, the printer is active and online. The printer takes it low when it goes offline – for example, when you press the ‘Online’ toggle button. It’s because this low state signals that the printer is offline that some people regard it as active low – when it’s low, there’s a condition you need to pay attention to. But the signal is not called ‘offline’, it’s called ‘select’. It’s high when it’s doing its assigned job.
My confusion about the nature of this signal caused me to add a pulldown resistor to this line. So I removed that. If anything, it should have a pullup. You’ll notice the Dell pulls this line high. Being selected is the printer’s natural state. You can see that, with Epson and SmartParallel connected, and the pulldown resistor removed, the signal is at 3.7V for some reason. This is high enough, probably, but is another good reason to change the resistor to a pullup.
/SELECT-IN is an input to the printer. In effect, when this signal is low, it tells the printer it should be online and is the selected printer. The printer is able to receive data only when this signal is low. You can see it defaults to this condition.
If the host machine takes this line high, it takes the printer offline. On the Epson there’s a DIP switch (1-8) that allows you to configure the printer’s behaviour. The default, factory-set position of this switch means that the printer will, in fact, completely ignore the state of this signal. In other words, the printer always considers itself ‘selected’. I have no pullups or pulldowns on this line, and that’s how I’m going to leave it.
Then there’s /AUTOFEED, which you’ll see described elsewhere as LINEFEED (which is what I did on my schematic). The Epson name more accurately describes its purpose.
When active (ie, low), whenever the printer receives a carriage return (ASCII 13) it automatically performs a linefeed as well.
This, too, can be configured either via the signal line or via a DIP switch. The two settings are ORed together, so you can prevent this behaviour either by keeping the /AUTOFEED line high or by flipping the DIP switch to ON.
This can be useful in some circumstances, such as when a piece of software sends only a carriage return at the ends of paragraphs and not an accompanying linefeed. I remember using this feature back in the day: it’s actually the reason the screws joining the top and bottom halves of the Epson’s case have long since disappeared – I was always delving inside to flip the DIP switch.
The factory default position for the DIP switch is OFF, meaning that the /AUTOFEED function can be controlled by the host. Even so, you can see that the line is pulled high by both the Epson and the Dell. I should perhaps think about adding a pullup to this line.
There’s one other change I want to make to my design and, to be honest, I’d realised my mistake before I built the breadboard prototype. I’d added an LED to show the state of the /STROBE signal. This is active low, so I fed this signal via the 74HC14 inverter, thinking I was clever.
But the thing is, the /STROBE signal exists for only 1µs. It’s never going to light up that LED. So that’s one component saved (actually, two counting the obligatory power-limiting resistor).
It works! Mostly…
So, with all those issues addressed, it works. I can send text via the serial port on the microcontroller (I have it hooked to my Mac via an FTDI cable) and it prints on the printer. Toggling the ‘online’ switch on the printer has the expected results. Running out of paper is detected. All seems fine. Except…
I keep getting random resets of the printer. Sometimes there’ll be a gap between resets of a minute or two. But then the gaps seem to get shorter. Occasionally, they’ve been virtually continuous.
I suspect a breadboard issue – maybe a lousy connection on the /INIT line. There are good breadboards and bad ones and I think this one falls into the latter category. And even good breadboards are far from perfect, introducing stray capacitances and other nasties. I need to get the oscilloscope on the /INIT line to see if this is, indeed, flipping low sometimes.
I could change to a classier breadboard, but I think a better solution is to step up a notch and build a version on proto board, where connections will be properly soldered. That’ll be the next post for this project.
And finally, I noticed that, with the SmartParallel not powered, but the printer switched on, large parts of the SmartParallel board were coming to life. I think this has something to do with its pullup resistors on some lines. The printer is holding these lines high, so there is a route from those lines, through the resistors to VCC on the SmartParallel. Maybe I should power the pullups via a diode, rather than direct to VCC. What do you think?