LCD DisplayIf you have a Linux PC without a monitor working as a server, but want to be informed about the current status of the computer, you could use a Liquid Crystal Display.
LCD & Linux
The connection of a Liquid Crystal Display to a Linux computer has been described
many times and we don't want to repeat old information.
We will describe how you are able to access a LCD via the parallel port with
the program lcd by Nils Fdrber. With four buttons that are
checked by jslaunch you can navigate through your own menu and
execute different commands. Everything without a huge effort in
The program lcd can be used to communicate with LCDs with
a Hitachi HD44780 chip.
Our article not only discusses the basic access to a LCD but also shows how an LCD and jslaunch can work together, so you do not get only a simple status report but also the PC can be steered interactively.
You can get this at Conrad-Elektronik (Germany) and it costs about 70,- DM ($40) for 4 lines and 20 columns without (Best.-Nr. 187267) and about 80,- DM with a back light (Best.-Nr. 187275). If your computer is placed in a room that is not illuminated very well you should get a display with a back light.
We will describe how you are able to access a LCD via the parallel port with the program lcd by Nils Fdrber. With four buttons that are checked by jslaunch you can navigate through your own menu and execute different commands. Everything without a huge effort in programming.
The program lcd can be used to communicate with LCDs with
a Hitachi HD44780 chip.
The display is connected to the parallel port and needs the following connections:
In addition, pin 2 of the LCD panel has to be connected to the
+5V power line and the pins 1 and 5 of the display and the pins 18 and 25
of the parallel port to ground.
A nice 5 Volt source inside the PC is the 2-wire floppy power cable (red cable +5V, black is ground -- test it first!).
The contrast of the display can be changed by a 100 ohm potentiometer. But it should be OK if you connect pin 3 of the display to the ground.
+5V ---+ / \ <--+ / | \ | GND ---+ +--- VL (Pin 3 - driver input)
The final connection looks like:
25 pin LCD SUB D Panel Pin --------------------------- GND 1 --+--- \ Connect to +5V 2 --|--- / Gameport R/W 5 --+ 1 EN 6 | 2 DB1 7 | 3 DB2 8 | 4 DB3 9 | 5 DB4 10 | 6 DB5 11 | 7 DB6 12 | 8 DB7 13 | 9 DB8 14 | 14 RS 4 | 18-25 GND --+
The connection of pins 18-25 is very important, otherwise you would see flashing signs and boxes on the display.
If you correctly linked everything, you would see two rows with black boxes:
The latest driver that is used to communicate with the LCD has the
release number 0.152, but we were not able to compile this version. The previous
release 0.151 worked fine for us.
You get this one at the FTP server ftp://ftp.unix-ag.uni-siegen.de/pub/os/linux/drivers/
(On the server you find a version 0.6.0. That one has the same name but is a different program.)
First check if you managed to compile the drivers before you go and buy an LCD. Only after being sure that you can communicate with the LCD is it worth spending the money!
We only succeeded in compiling the driver on a system with a 2.2.13 and an old 2.0.36 kernel. It failed on the 2.2.16 kernel. LCD-0.151 stopped with an error message. Maybe you will have more luck than us.
Before compiling, you choose your kernel in the file driver/Makefile (2.0.x or 2.2.x). You have to set the address of the parallel port in the file driver/hardware.h:
[...] #define LCD_ADDRESS 0x0378 /* corresponds to lpt1: */ /* #define LCD_ADDRESS 0x0278 */ /* corresponds to lpt2: */ /* #define LCD_ADDRESS 0x3bc */ /* also a possible address for the parallel port */ [...]
Delete the comments /* and */ for your address.
If you do not know the address of the parallel port, plug in a printer, load the printer module:
>> insmod lpand have a look at:
>> cat /proc/ioportsThere you find the address.
If you have a display with a different size than 20x4 you can set this in driver/hardware.h.
[...] #define LCD_COLS 20 #define LCD_LINES 4 [...]
lcd needs the files
/usr/src/linux-2.2.13/include/linux/modsetver.h for compiling
the drivers. But both are missing in our copy of the 2.0.x kernel.
It would work if you copied these files from a 2.2.x kernel into the proper directory modsetver.h and modversions.h).
If everything was completed you could:
>> makethe program lcd.
Then you'll find the compiled module lcd.o in the subdirectory driver/, which is needed to talk to the LCD.
Finally, you have to create the pseudo file /dev/lcd that will be the device talking to the LCD. This creation is done using the script mkdevice in the subdirectory driver/ (as root).
Next you have to connect the hardware in the right way.
We wrote about Jslaunch in an earlier issue
(Jslaunch -- PC steering via Joystick
In combination with an LCD, the usefulnes of the program is extended.
The program jslaunch checks in well-defined time intervals if the buttons of a joystick connected to the gameport of the sound card were pressed and would execute commands depending on the button combination that was pressed.
Jslaunch can be used very comfortably because it does not need any kernel module to read the joystick port, but gets the information directly and can be installed easily.
Due to the high stability of the program, it can be used as an emergency reset. If a few important components of the system crashed (e.g. keyboard, network and/or Xserver) you would be able to halt or reboot the system and would not have to use the hard-reset button.
The easiest way would be if you got a joystick (maybe broken but with the buttons are still working) and separate the cables and buttons from the stick.
If the display had to have a professional look, you could substitute the buttons with better looking buttons you would get in any well-stocked electronics shop.
The program jslaunch does not take much work; you just have to compile it (>> make).
After everything is connected correctly, you should test the
To do this, you have to load the module of the LCD driver (as root in the subdirectory driver/):
>> /sbin/insmod lcd.oThen you should see a flashing cursor in the upper left corner. If everything worked well you could copy the module into the directory /lib/modules/2.2.*/misc/ and you do not have to change into the driver/ directory any longer.
To produce an output on the LCD you change into the subdirectory tools/proclcd and compile the program with a
>> makeThe program is started and the output is piped to the /dev/lcd device:
>> ./proclcd > /dev/lcdThen you should see an output on the display like:
By the way, the driver can be removed using:
>> /sbin/rmmod lcdThis would only work if no running process accessed the LCD.
Next you test the joystick.
Start jslaunch with the command:
>> jslaunch -r 1 "echo 1" -r 2 "echo 2" -r 3 "echo 3" -r 4 "echo 4"If you pressed a button, jslaunch would show which button was pressed.
You should write down which number belongs to which button because you will need it later for the LCD steering.
If both (LCD and joystick buttons) worked well, you could place both
into the housing of the PC.
A free slot would be ideal to fix the display and the four buttons. If the parallel port and/or joystick port was not fixed on a slot card but was fixed with a cable on the backside of the PC you could remove it and place it inside of the PC.
This part describes how you can construct your own menu which can be used via the joystick buttons. This is not a complicate program, just a few simple bash scripts. Even an inexperienced programmer is able to modify these to his desired LCD output.
First, you create a new directory where you collect the scripts for the LCD:
>> mkdir /usr/local/etc/display/There, you create the file own that has to be an executable:
>> touch /usr/local/etc/display/own >> chmod a+x /usr/local/etc/display/ownThe script should look like:
#!/bin/sh # Just a dumb script copying some nice system information values # to our LCD device # export SLEEP=10 #Button 1,2,4: Menu -- button 3: reboot echo -n -e "\33c" > /dev/lcd echo -n -e "\33h" > /dev/lcd echo -e " " > /dev/lcd echo -e " Please wait ..." > /dev/lcd echo -e " ==============" > /dev/lcd killall jslaunch sleep 4 /usr/local/jslaunch-2.0/jslaunch -r 1 "killall own && /usr/local/etc/display/menu1"\ -r 3 "killall own && /usr/local/etc/display/reboot"\ -r 4 "killall own && /usr/local/etc/display/menu1"\ -r 2 "killall own && /usr/local/etc/display/menu1"& #The buttons 1,2 and 4 start the menu #button 3 reboots the computer echo -n -e "\33c" > /dev/lcd while true; do echo -n -e "\33c" echo -n -e "\33h" #The following lines collect information about the PC and show these #on the LCD step by step #-- Number of the apache users export WEB=$(apachectl status | grep reques | cut -d " " -f 4) . #-- Number of the ftp users export FTP=$(ftpcount | grep local | cut -d " " -f 22) #-- Size of the free memory export MEM=$(cat /proc/meminfo |fgrep "MemFree"|cut -b 13-24) #-- Uptime of the PC export UPT=$(uptime | cut -d "," -f 1) #-- Number of the users logged in export USER=$(uptime | cut -d "," -f 2) #-- CPU usage export LOAD=$(cat /proc/loadavg | cut -d " " -f 1) #-- The following lines display the information about a # few mounted devices # (Zip-drive, cdrom, local-partition...) export ZIP=$(df | grep "zip" | cut -d "%" -f 2,2) export LOCAL=$(df | grep "local" | cut -d "%" -f 2,2) export CDROM=$(df | grep "cdrom" | cut -d "%" -f 2,2) export ZIP_P=$(df | grep "zip" | cut -b 50-53) export LOCAL_P=$(df | grep "local" | cut -b 50-53) export CDROM_P=$(df | grep "cdrom" | cut -b 50-53) # ***** SCREEN 1 ******* # Here the collected information is shown # Uptime, Memory, HTTP/FTP-User and Load echo -e $UPT echo -e "MEM "$MEM echo -e "HTTP "$WEB" -- FTP" $FTP" " echo -e $USER " load:" $LOAD sleep $SLEEP # The sleeping time sets how log the info is shown # ***** SCREEN 2 ******* # List of the mounted devices echo -n -e "\33c" echo -n -e "\33h" echo -e $ZIP_P $ZIP echo -e $LOCAL_P $LOCAL echo -e $CDROM_P $CDROM sleep $SLEEP # ***** SCREEN 3 ******* # List of all entries in the printer spool echo -n -e "\33c" echo -n -e "\33h" export DRUCK=$(lpq | grep bytes | cut -b 8-18 | tail -n 6) echo -e "printer queue:" echo -e $DRUCK sleep $SLEEP # ***** SCREEN 4 ******* # Some information about the network device echo -n -e "\33c" echo -n -e "\33h" export ETH_R=$(cat /proc/net/dev | grep eth0 | cut -b 8-14) export ETH_S=$(cat /proc/net/dev | grep eth0 | cut -b 36-43) export IPP_R=$(cat /proc/net/dev | grep ippp0 | cut -b 8-14) export IPP_S=$(cat /proc/net/dev | grep ippp0 | cut -b 36-43) export IPP_E=$(cat /proc/net/dev | grep ippp0 | cut -b 44-48) export ETH_E=$(cat /proc/net/dev | grep eth0 | cut -b 44-48) echo -e " eth0 ippp0" echo -e "rec " $ETH_R" "$IPP_R echo -e "sen " $ETH_S" "$IPP_S echo -e "err " $ETH_E" "$IPP_E sleep $SLEEP done > /dev/lcd
The scripts are very simple. The required information is shown with
a small command and can be obtained with the tools "grep" and "cut". On
different distributions, this can cause a few problems because the
format of the output of the programs can be different and so the
specified columns in the cut command can be incorrect.
If the specific information did not appear on the display, you should check the commands by hand and determine the appropriate values.
The information is written in to a variable (e.g. $ETH_E for
the number of all received corrupt packages of the network device) and
then printed via echo.
Instead of this, you could use another program, too: e.g. procload.
As you can see in line 18, the menu (own) would be killed if you pressed
the buttons 1,2 and 4 and the corresponding menu (here it is menu 1 for all)
would be started.
The following script has to be placed in the directory /usr/local/etc/display, too, and needs to be an executable.
The file could look like:
#!/bin/sh # First you have to stop the old jslaunch because it still owns the # old configuration killall jslaunch # If the previous menu stayed in the sleep modus it has to be # stopped, too. killall sleep # This sleeping time is necessary because the user needs enough # time to release the button. Otherwise jslaunch does not # start again. echo -n -e "\33c" > /dev/lcd echo -n -e "\33h" > /dev/lcd echo -e " " > /dev/lcd echo -e " Please wait..." >/dev/lcd echo -e " ==============" > /dev/lcd sleep 4 # Here some information which button has which option export VERZ=/usr/local/etc/display echo -n -e "\33c" > /dev/lcd echo -n -e "\33h" > /dev/lcd echo " --== Menu ==--" > /dev/lcd echo " 1 mount zip module" > /dev/lcd echo " 2 unmount zip module" > /dev/lcd echo " 3 next" > /dev/lcd # Now it starts jslaunch with the new options # 1 == mount Zip # 2 == unmount Zip # 3 == e.g. menu, to mount a CD Rom -- the line is # not active # 4 == Reboot /usr/local/jslaunch-2.0/jslaunch\ -r 1 "killall menu1 && /usr/local/etc/display/zip_on"\ -r 3 "killall menu1 && /usr/local/etc/display/reboot"\ # -r 4 "killall menu1 && /usr/local/etc/display/cdrom"\ -r 2 "killall menu1 && /usr/local/etc/display/zip_off" & # After 15 seconds the menu would go back to the main menu if # no button was pressed. sleep 15 /usr/local/etc/display/own
The script to reboot looks like the following (also here you could add a security question like "Really reboot?").
#!/bin/sh killall jslaunch killall sleep echo -n -e "\33c" > /dev/lcd echo -n -e "\33h" > /dev/lcd echo -e " " > /dev/lcd echo -e " Reboot now ..." >/dev/lcd echo -e " ==============" > /dev/lcd echo -e " See you soon ;-) "> /dev/lcd sleep 4 reboot
In menu1 we commented out button 3 because it should now be clear how
you could create your scripts. With button 3, you could got to
an additional menu where you would be able to mount or unmount the CD-ROM
drive, for example.
But any other display could be made, like special status reports.
Every menu has to be placed in a new script file in the directory /usr/local/etc/display/, that has to be constructed like:
#!/bin/sh killall jslaunch killall sleep echo -n -e "\33c" > /dev/lcd echo -n -e "\33h" > /dev/lcd echo -e " " > /dev/lcd echo -e " Please wait ..." >/dev/lcd echo -e " ==============" > /dev/lcd sleep 4 # Here a few information about the commands that are executed after # pressing a button export VERZ=/usr/local/etc/display echo -n -e "\33c" > /dev/lcd echo -n -e "\33h" > /dev/lcd echo " --== Menu ==--" > /dev/lcd echo " 1 Button 1 does..." > /dev/lcd echo " 2 Button 2 does..." > /dev/lcd echo " 3 next" > /dev/lcd # Every button gets a command or menu /usr/local/jslaunch-2.0/jslaunch\ -r 1 "killall this_menu && /usr/local/etc/display/Script1"\ -r 3 "killall this_menu && /usr/local/etc/display/Script2"\ # -r 4 "killall this_menu && /usr/local/etc/display/Script3"\ -r 2 "killall this_menu && /usr/local/etc/display/Script4" & sleep 15 /usr/local/etc/display/own
Using this method you can build your own menu structure without any big effort or great knowledge in any programming language.
start it automatically
The LCD display is ideal for a PC without any monitor or keyboard, but without those the menu has to be started automatically while booting.
Two options exist to accomplish this. Either you add the command that starts the service into the boot.local (placed at /sbin/init.d), or you write a short init script and place this at /sbin/init.d (SuSE) or /etc/rc.d/init.d (RedHat).
The commands that have to be executed start the LCD module and then start the menu script:
/sbin/insmod lcd sleep 2 /usr/local/etc/display/own &If you did not copy the LCD module into a subdirectory of /lib/modules (see above) you would have to specify the full path instead.
So, there it is. The LCD should work and if you wanted to see how it looks in the final state, look at this picture:
|http://www.home.unix-ag.org/nils/lcd.html||Homepage of the program lcd|
|http://www.linux-magazin.de/ausgabe/1999/08/LCD/lcd.html||lcd programmer`s article in the German Linux Magazine|
|ftp://sunsite.org.uk/Mirrors/contrib.redhat.com/libc6/i386/||Sorry but jslaunch does not have a homepage of its own|
|http://lcdproc.omnipotent.net/||Drivers for several displays connected to the serial port|
|http://www.mv.com/ipusers/cdwalker/lpt_driver.html||Drivers for several displays connected to the parallel port|
Enter Own Comment