The principle of ‘one step at a time’ is very sound. The more changes you make at once, the more places there are for bugs to hide. And that’s why this project has been progressing slowly – or not at all – just lately.
Finally, though, I feel like it might be back on track.
A quick recap: SmartParallel is going to be an Atmel ATMEGA328PB-powered board that acts as a smart serial to parallel interface that will allow me to use my Epson MX-80 F/T III dot matrix printer with devices such as a Raspberry Pi. In fact, I intend to set up a Pi as a networked printer server.
An initial breadboard-based prototype suggested it would work fine. As an interim step before the final PCB, I created a PCB that holds the serial-to-parallel shift register, controlling the data lines to the printer, and breaks out all the other lines to and from the DB25 printer socket. This is what I’m using at the moment. A couple of the other chips are on a piece of stripboard.
I have the first iteration of the ‘final’ PCB in hand, but haven’t soldered any components yet. Why?
The reason is that I didn’t want to make too many changes at once. I originally used a homemade ATMEGA328PB prototyping rig/breakout board to house the microcontroller, but I recently replaced this with a new version on a properly fabbed PCB rather than a slung-together stripboard monstrosity. I was worried that it might be difficult to decide if any problems I encountered were faults in the new and as-yet untested prototyping board or elsewhere.
Then life got busy. I had no time to test the new rig. I did noodle about with a Go program that will print a text file on a Raspberry Pi, via the SmartParallel, to the Epson. It didn’t work. I got depressed about that.
I also, now and then, tinkered with the code for the SmartParallel – but as the test hardware was in an unknown state and not hooked up because … reasons … I didn’t test any of the changes.
This is bad.
Changes should be incremental, testing as you go. One change, one test. That way, you know straight away if you’ve introduced a bug and where, roughly, it is.
Yesterday, I hooked up everything again, tried the Go code and … well, still no go. (See what I did there?)
But where is the problem? The prototyping board? The Go code? The much <ahem> ‘improved’ ATMEGA code? Maybe even the serial connection between Pi and SmartParallel.
Time to revert to a more successful state. Instead of trying to print programmatically from the Pi, I connected the serial input of the SmartParallel to an FTDI serial cable from my Mac. I’ve happily printed single-line messages this way before.
Except that now it wasn’t working. Not only were the messages not printing, the serial responses from the SmartParallel were not appearing on my terminal screen. Gah!
Also, other strange things were happening. The printer initialisation routine, which should normally take a second, was taking a long time. And that routine does use a couple of _delay_ms() calls. Hmm, could this be a clock issue?
Reset the fuses
I was getting something back from the SmartParallel, but it was garbled. I double-checked baud rates at both ends – no problem there.
The code in Atmel Studio had F-CPU set to 8000000 – ie, 8MHz. And I knew the clock division fuse, LOW.CKDIV8, was selected, to give an effective clock speed of 1MHz. Finally, the LOW.SUT_CKSEL fuse was set to use the internal RC oscillator. This had all worked fine on my previous prototyping rig, but maybe not so well here for some reason?
I popped a 16MHz crystal into the prototyping board (I’m planning on using such a crystal on the final board anyway), and changed the fuse settings appropriately.
Bingo! Now the serial connection was working again. And no weird delays during initialisation. And messages are getting sent to the printer. Yay!
Well, mostly yay. It seems I clearly introduced some logic errors into the code when I improved it. But at least with a working serial connection these were easy to track down. Within a couple of hours I’d hunted down and exterminated the bugs, leaving my improvements to the code in place and working. So I am slightly ahead of where I was before.
It feels like this project is on track again. Plus, it appears my ATMEGA328PB prototyping board actually works, which is nice.
The next step – given that the hardware is in a known working state – will be to try my Go code again, just to see if I can print programmatically, sending more than one line at a time. Once that’s working, I can progress to making up the proper PCBs, because I know I have working code.
See, that’s how it should be done – with only one part of the whole system being altered and in an experimental state. Life is a lot easier that way.