I still want to find a small LCD module for the LED calculator, so I can fit the whole thing into a box with a footprint about the size of a deck of cards. But for prototyping, I have a stack of 2×16 LCD modules about 3 1/2″ wide (viewable about 2 1/2″) from Slim, and Wednesday night I got one hooked up and working.
They’re Optrex DMC-16207 modules, and they seem to be using the Hitachi chipset that everyone uses, or at least an equivalent, although I didn’t know that at the time. Searching online, I had a hard time finding data on this exact module, but came across a mechanical drawing, a module user’s manual, and finally a full datasheet.
Interfacing the Arduino and LCD
I dived in and wrote my own LCD interfacing code. I found out in retrospect that there are several other Arduino LCD interfacing projects out there:
But all of them are using hard-coded delays to pause while the LCD processes commands, rather than checking the busy flag. To be sure, I’m doing the same thing right now in my first draft of the code; but I’m going to go back and clean it up to do it right.
Also, I haven’t checked all of them, but at least one is using digitalWrite()
to manipulate each bit of the port register individually. Since I’m dedicating eight Arduino lines to the LCD’s I/O port, I can write the port register as a byte rather than twiddling individual bits, saving time and effort.
My goal will be to write a nice library module/class that encompasses these different approaches (8-wire vs 4-wire, busy flag vs hard-coded delays, read/write interaction vs hardwired write-only) and presents a clean interface to the programmer to select the options. Of course, for now, I just wanted to get it up and running.
I found this ATmega to Arduino pin mapping, which confirmed that Arduino digital lines 0-7 are PORTD lines 0-7. And the Arduino port register reference shows that DDRX
and PORTX
are defined as Arduino variables; so writing to a port is as easy as PORTD = $ff
. It’s very nice that they left those low-level features exposed, even though in most cases it’s better to use the higher-level interface for portability.
Calculator Prototype
So here’s the work in progress.
The Arduino is getting power from USB and supplying 5V power to the LCD. The LCD contrast is hard-wired to ground. Although it actually looks pretty good right now, I’ll want to put in a potentiometer to adjust contrast. And I’m still using my bench power supply to run the LED circuit at 9V.
I don’t have a method built to select the voltage of the target circuit — the software is assuming 5V for now. The easy thing to do would be pushbuttons to bump the desired voltage up and down. It’d be kind of fun to do it with a spinny-wheel, although I’m not sure how much that would increase the cost, and I’m concerned about overengineering this thing if I really want to offer it as a kit. Maybe another potentiometer is a good compromise.
However the target voltage is selected, I need to determine the selectable range (which could of course be overridden by an owner with an AVR programmer). I’m thinking 3 – 15V in .1V increments. Is that enough?