Sunday, July 17, 2011

Microcontroller driven LCD panel with voltage measurement, time, EEPROM for computers

I just finished making a circuit to drive a four line LCD panel from an Arduino. The project started out as a way to drive the LCD to display arbitrary information, but then evolved into a way to tell the time, read and write the EEPROM from the Atmel 328p, and measure voltage. I'm using many existing libraries: the Time library, and the two Controller LCD library.

The final functionality is:
  1. Commands are sent over USB using vi-line syntax. All commands start with ':' character.
  2. Segments the 40x4 display into 8 segments of 20 chars each. Segment 0 is column 0, line 0. Segment 1 is column 20 line 0. This allows an easy way to display up to eight different status updates. To write "hello world" in segment 3, you write ":s3helloworld\n" to the serial port.
  3. Read and write from EEPROM. The 1028 bytes of EEPROM is chunked into 8 segments of 128 bytes each. Segment 0 cannot be written to, which allows for 128 bytes of ROM. To write a segment 3, you index (:i3), then write (:wMySecretMessage\n). To read from EEPROM, you index first (:i3), then read the full segment (:r).
  4. Time can be read from the device (:t) and the time can be set using Unix time (:T1310349445).
  5. Voltage monitoring at analog pins can be toggled (:a). Voltages are displayed on the LCD (display shows all six pins in decivolts: 5.0v is written 50) and written in raw form on serial (relative to 1023. 1023 = 5V, 0=0V)

The entire Arduino source code is available as FourLinePanel.pde. It still has some debugging information left in, it prints the value of every new command it receives. This debugging could be removed. It supports a few commands:
:t Displays the time
:T<unix time> sets the time
:l<message>\n Writes message to current position
:sN<message>\n Writes message starting at segment N
:a Turns on analog voltage monitoring on LCD and serial
:r Reads 128 bytes from EEPROM at current location
:iN Index into segment N of the EEPROM
:w<data>\n Write data into EEPROM starting at current location

This requires one Atmega microcontroller, an LCD panel, two 22pF ceramic capacitors, and one 16Mhz crystal. To interface it with USB, a USB to serial cable might be required. In my design, I'm driving the entire project using power from the USB port. This minimises the need for voltage regulation and additional components: power over USB is usually clean. You can download the schematic for the FourLinePanel here.

To interface with a computer, you read and write to the serial port with 38400 bits per second, no flow control, and no parity bits. An example program to interface this with Python is given below.
import serial, time
# Set the time on the FourLinePanel for GMT+5hrs
# offset from GMT: Add 5hrs
offset = 5*3600
port = "/dev/ttyUSB0"
fourLine = serial.Serial(port, 38400);
fourLine.write(":T" + 
               str((int)(time.time() + offset))) 

There are five spare digital pins that could be used to drive a Real Time Clock or LEDs. These are marked as "Spare Digital (unused)" in the circuit diagram [png], and circuit diagram [ps]. The analog voltage testers can be used as handy ways to measure voltage at the desk when a multimeter isn't handy, or to constantly monitor the voltage drop across a device (like a photovoltaic cell).