Building a Linux Media Network, one step at a time

Wednesday, March 08, 2006

LCD Status Display

One neat feature I'd like to incorporate into this media center is the ability to display the unit's status off-screen. By that, I mean the same sort of functionality that your DVD or CD player gives you: a panel to show the current position in the track, the play/pause/stop status, etc.

I started by ordering a 20-character, 4-line display from "rainbow_city_store" on eBay. The service was prompt and wholly satisfactory. This display is compatible with the popular HD44780 LCD controller, and can basically be plugged straight into a parallel port once you've got the wiring all sorted out. The seller provided a couple of schematic diagrams, and also some helpful links to more wiring diagrams and various HD44780 projects. I wired up the display to the parallel port as described here (I didn't use the port cups, but the schematic was great).

(ignore the extra notes for now)

Once the display was wired up I investigated a project called LCDProc. This is a useful little tool that can display things like CPU, Memory, and Disk usage on an external display. But what's more important is the component of LCDProc that can drive the HD44780 over the parallel port (LCDd). This really simplifies the interface to the display by providing simple commands that can be executed via a regular TCP/IP socket.

Here are some notes on establishing communication with the display:

  • At the hardware level, you can check that your signals are correct by using a multimeter to measure the voltage between certain pins and the ground. The SP800 sets the data pins to 3.3V (high) or 0.5V (low). The other pins will be between 1.5V and 5V high or 0.5V low, I believe.

  • If you have applied power to Pin 2 on the LCD and grounded pins 1 and 3, you should see lines 2 and 4 on the display illuminate (barely). If you apply power to pin 15 and ground pin 16 (make sure you get that right) you will activate the backlight, and the lines should be much more visible. This is the HD44780 self-test. You may be stuck here a while :)

  • Pin 1 on the parallel port (pin 6 on the display) is the Strobe. If you are interfacing directly with the hardware (ie. not using LCDd), be sure to set this to high, and then to low to tell the LCD controller that the signal on the data pins are valid.

  • Access to the data pins of the parallel port on the SP800 is at IO 0x378. You can access the status pins at 0x38A. More info here. Some sample code is here. Compile like so: gcc -o lptout lptout.c. Just tweak the outb call to direct the byte to the data or status pins.

  • If you are using LCDproc/LCDd and have wired your display like mine, you want the HD44780 driver and the "8bit" wiring configuration.

  • Build and install LCDd like so:
    • # Download and extract the tarball to /usr/local/src
      cd lcdproc-0.4.5
      ./configure --enable-drivers=hd44780
      make && make install

    • Edit LCDd.conf. Uncomment the line "Driver=HD44780" and comment out any other drivers. In the [HD44780] section, ensure the Port parameter is set to 0x378 and the ConnectionType parameter is set to 8bit. The size should also be set to 20x4. Finally, copy this file to /etc.

    • Start LCDd by running LCDd /etc/LCDd.conf. It runs in the foreground by default. This is configurable within the conf file. If LCDd was able to connect and interface with your display, the screen should change from the two active lines (self-test screen) to something like this:
      LCDProc Server
      Clients: 0
      Screens: 0

      (The display pinout on my LCD screen is actually at the top of the display, so this screen currently appears upside-down. If you know of a way to rotate the display via the controller I would love to know.)

    • Test the connection by opening a new terminal window and running lcdproc C. This will try to connect to LCDd on the default address and port and display your CPU usage statistics on the LCD screen. If it works, congratulations!

Extra Credit

That backlight ain't gonna last forever, you know. It would be convenient if we could turn it on and off at will. A simple potentiometer or switch between pin 16 and ground would do the trick. Or... we could wire it up to one of the unused status pins on the parallel port and control it by a transistor... oooh! Good idea!

Turns out, I wasn't the first one to think of it. But I did it slightly differently than described in the (excellent) LCDproc documentation. Here's the schematic:

The transistor is a 2N3904, which we happened to have lying around the office. The collector goes to pin 16 on the LCD, the emitter goes to ground, and the base to pin 17 of the parallel port via a 1K resistor. If you're interested, here's the math, as I understand it:

  • By hooking up an ammeter in series with the LCD display pin 15 we can see that the backlight draws ~51mA of current.

  • The two figures we need from the 2N3904 data sheet are the gain (hfe) and the base/emitter saturation VBE(sat), which is 0.65 ~= 0.7 for a current draw of 0.051A.

  • The high voltage on parallel port pin 17 (SEL) will be 1.5V. We subtract the saturation voltage from this to get 0.8V.

  • We calculate the required resistance for the transistor like so: 0.8V / ( 0.051A / 60 ). This gives us a resistance of 941 Ohms, ~= 1K.

LCDd has some backlight functionality built-in, but I had to tweak it a little bit to get it to work with this setup. There appears to be some conflict with pin 17 and the "multiple display" feature of LCDproc - when I started LCDd, the backlight would blink on and off repeatedly. The easiest way to stop this, if you're just using one display like me, is to force the displayID to 0 in the function lcdwinamp_HD44780_senddata (server/drivers/hd44780-winamp.c). I also had to swap the values for BacklightBrightness and BacklightOffBrightness in LCDd.conf. Then I just set the Backlight parameter in the HD44780 section of the conf file to "yes".

After the code change, run make && make install to deploy the changes. Restart LCDd. You can test the backlight by telnetting to localhost 13666 and entering the following commands:
screen_add 0
backlight on
backlight off

Note that the backlight command has no effect until at least one screen has been created.
Here's a shot of the LCD display in action. If you look closely, you can see that it's displaying the timing data that we just took out of Xine. More on that in the next post.


Post a Comment

<< Home