home   artikelen   forum   colofon  
Gepubliceerd op 12.10.2001
Auteur: Ronny Ziegler
Vertaald door: Guus Snijders
Languages: en de
Help Ons!
 

LCD display

LCD Als je een Linux PC zonder monitor hebt werken als server, maar wel op de hoogte wilt zijn van de huidige status van de computer, kun je een Liquid Crystal Display gebruiken.

LCD & Linux

Het aansluiten van een Liquid Crystal Display op een Linux computer is al vaak beschreven en we willen niet de oude informatie herhalen.
Ons artikel beschrijft niet alleen de basis toegang tot een LCD, maar laat ook zien hoe je een LCD en jslaunch kunt laten samenwerken, zodat je niet alleen een simpel status rapport krijgt, maar de PC ook interactief kunt besturen.

We zullen beschrijven hoe je een LCD via de parallelle poort kunt aansturen met het programma lcd van Nils Fdrber. Met vier knoppen onder de controle van jslaunch kun je door je eigen menu navigeren en verschillende commando's uitvoeren. Dit alles zonder enorme programmeer-inspanningen.

Het scherm

Het programma lcd kun je gebruiken om te communiceren met LCDs met een Hitachi HD44780 chip.
Deze zijn ondermeer verkrijgbaar bij Conrad-Elektronik (Duitsland) en kosten ongeveer DM 70,- ($40,-) voor vier regels en 20 kolommen zonder, (Best.-Nr 187267) en ongeveer DM 80,- met een backlight (Best.Nr. 187275). Als je computer in een slecht verlichte ruimte staat, kun je het beste een display met een backlight gebruiken.

Display met backlight

De display is aangesloten op de parallelle pooort en gebruikt de voglende pinnen:

25 pin
Par.Poort-kabel
LCD
Panel
LCD-Pin
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
ground

Parport-labeling

Verder moet pin 2 van het LCD paneel moet verbonden worden met de +5V lijn en de pinnen 1 en 5 van de display en de pinnen 18 en 25 met aarde.
Een handige 5 volt bron in de PC is de 2-aderige floppy power kabel (rode ader is +5V, zwart is aarde -- test dit eerst!).

Het contrast van de display kun je veranderen met een 100 Ohm potentiometer. Het zou echter ook OK moeten zijn als je pin 3 van de display met aarde verbindt.

   +5V ---+
           /
           \ <--+
           /    |
           \    |
    GND ---+    +--- VL (Pin 3 - driver input)
  

De uiteindelijke verbinding ziet er zo uit:

         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        --+    
                                           
  

De verbinding van de pinnen 18-25 is erg belangrijk, zonder deze zie je knipperende symbolen en blokken op de display.

Als je alles juist hebt opgezet, zie je twee rijen met zwarte blokken:

Display zonder weergegeven
  informatie

De driver

De nieuwste driver die beschikbaar was voor de communicatie met de LCD, was 0.152, maar deze konden we niet compileren. De vorige versie, 0.151 werkte wel goed voor ons.
Deze is te vinden op de FTP server ftp://ftp.unix-ag.uni-siegen.de/pub/os/linux/drivers/
(Op deze server staat ook een versie 0.6.0, dat is een ander programma met dezelfde naam).
Eerst controleer je of je de drivers kunt compileren, voordat je een LCD koopt. Pas als je zeker weet dat je kunt communiceren met de LCD, is het het waar geld uit te geven!
Wij slaagden er alleen in de driver te compileren op een systeem met een 2.2.13 en een oude 2.0.36 kernel. Het werkte niet op een 2.2.16 kernel. LCD-0.151 stopte met een foutmelding. Misschien heb jij meer geluk dan wij.
Alvorens te compileren, kies je eerst je kernel in het bestand driver/Makefile (2.0.x or 2.2.x). Stel het adres van de parallelle poort in in driver/hardware.h:

driver/hardware.h
   [...]
      #define LCD_ADDRESS 0x0378     /* komt overeen met lpt1: */
   /* #define LCD_ADDRESS 0x0278  */ /* komt overeen met lpt2: */
   /* #define LCD_ADDRESS 0x3bc   */ /* ook een mogelijk adres voor de
      parallelle poort*/
   [...]
  

Verwijder de commentaren /* en */ rond jouw adres.
Als je het adres van de parallelle poort niet weet, plug je een printer in en laadt je de printer module:

  >> insmod lp
  
en controleer:
  >> cat /proc/ioports 
  
daarin kun je het adres vinden.
Als jouw display een andere grootte heeft dan 20x4, kun je dit instellen in driver/hardware.h

driver/hardware.h
   [...]
   #define LCD_COLS 20
   #define LCD_LINES 4
   [...]
  


lcd heeft de bestanden /usr/src/linux/include/linux/modversions.h en /usr/src/linux-2.2.13/include/linux/modsetver.h nodig voor het compileren van de drivers. Beide ontbraken in onze kopie van de 2.0.x kernel.
Als je deze bestanden van een 2.2.x kernel kopieert naar de juiste directory modsetver.h en modversions.h), werkt het wel.

Als alles compleet is, gebruik je:

  >> make 
om het programma lcd te compileren.
De gecompileerde module lcd.o kun je vinden in de subdirectory driver/, deze heb je nodig om te praten met de LCD.
Ten slotte maak je het pseudo bestand /dev/lcd, dat is het device dat "praat" met de LCD. Dit bestand kun je maken met het script mkdevice in de subdirectory driver (als root).
Vervolgens sluit je de hardware aan.

jslaunch

We hebben Jslaunch in een eerdere uitgave besproken: (Jslaunch -- Een PC besturen met een Joystick).
In combinatie met een LCD wordt de bruikbaarheid van dit programma verder uitgebreid.
Het programma jslaunch controleerd in goed-gedefinieerde tijds- intervallen of de knoppen van een joystick, verbonden met de gameport van de geluidskaart, werden ingedrukt en voert commando's uit, afhankelijk van de ingedrukte knoppen combinatie.
Jslaunch kan erg comfortabel gebruikt worden omdat het geen kernel module nodig heeft voor de joystick poort, maar de informatie direct krijgt en makkelijk geïnstalleerd kan worden.
Door de enorme stabiliteit van het programma kun je het gebruiken als een nood reset. Zelfs als belangrijke componenten van het systeem zijn gecrashed (bijvoorbeeld toetsenbord, netwerk en/of X-server), kun je het systeem stoppen of herstarten en hoef je de reset-knop niet te gebruiken.
De makkelijkste manier is om van een joystick (eventueel een defecte waarvan de knoppen nog werken), de kabels en knoppen van de stick te scheiden.
Als de display er professioneel uit moet zien, kun je de knoppen vervangen door beter uitziende knoppen die je in iedere zichzelf respecterende electronica winkel kunt kopen.
Het programma jslaunch vraagt niet veel werk; je moet het alleen compileren (>> make).

Eerste test

Als alles goed is aangesloten, kun je de display testen.
Hiervoor moet je de module van de LCD driver laden (als root, module staat in de subdirectory driver/):

  >> /sbin/insmod lcd.o 
  
Dan zou je een knipperende cursor in de linker bovenhoek moeten zien. Als dit goed werkt, kun je de module kopiëren naar de directory /lib/modules/2.2.*/misc/, dan hoef je niet langer naar de driver directory te gaan.

Om uitvoer op de LCD te produceren, ga je naar de subdirectory tools/proclcd en compileer je het programma met een

  >> make
  
Het programma wordt gestart en de uitvoer gepiped naar het device /dev/lcd:
  >> ./proclcd > /dev/lcd
  
Dan zou je de uitvoer op de display moeten zien, zoals:

Proclcd test

De module kun je overigens weer verwijderen met:

  >> /sbin/rmmod lcd
  
Dit werkt alleen als de LCD niet wordt gebruikt door de LCD.

Vervolgens kun je de joystick testen.
Start jslaunch met het commando:

  >> jslaunch -r 1 "echo 1" -r 2 "echo 2" -r 3 "echo 3" -r 4 "echo 4"
  
Als je een knop indrukt, laat jslaunch zien welke knop werd ingedrukt.
Noteer welk nummer bij welke knop hoord, dit heb je later nodig bij het besturen van de LCD.

Als beide (LCD en joystick knoppen) goed werken, kun je beide in de kast van de PC plaatsen.
Een vrij slot zou ideaal zijn om de display en de vier knoppen te plaatsen. Als de parallele poort en/of joystick poort niet vast op een slotplaat zitten, maar aan een kabel aan de achterkant van de PC, kun je deze verwijderen en binnenin de PC plaatsen.

Het menu

Deze sectie beschrijft hoe je je eigen menu kunt bouwen dat je kunt besturen met de joystick knoppen. Dit geen complex programma, alleen wat bash scripts. Zelfs een onervaren programmeur kan deze aanpassen voor de gewenste LCD uitvoer.

Eerst maak je een nieuwe directory voor de LCD scripts:

  >> mkdir /usr/local/etc/display/
  
Daar maak je het bestand own en maak je deze uitvoerbaar:
  >> touch /usr/local/etc/display/own
  >> chmod a+x /usr/local/etc/display/own
  
Het script ziet er als volgt uit:

/usr/local/etc/display/own
   #!/bin/sh
  
   # Een eenvoudig script dat wat aardige systeem informatie copieerd
   # de LCD
   #
   
   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"&
  
   # De knoppen 1,2 en 4 starten het menu
   # knop 4 herstart de computer
   
   echo -n -e "\33c" > /dev/lcd
   
   while true; do
    echo -n -e "\33c" 
    echo -n -e "\33h"
  
   # De volgende regels verzamelen informatie over de PC en geven deze
   # in stap voor stap weer op de LCD
  
   #-- Aantal Apache gebruikers
   export WEB=$(apachectl status | grep reques | cut -d " " -f 4) .
   #-- Aantal FTP gebruikers
   export FTP=$(ftpcount | grep local | cut -d " " -f 22)
   #-- Vrij geheugen
   export MEM=$(cat /proc/meminfo |fgrep "MemFree"|cut -b 13-24)
   #-- Uptime van de PC
   export UPT=$(uptime | cut -d "," -f 1)
   #-- Aantal ingelogde gebruikers
   export USER=$(uptime | cut -d "," -f 2)
   #-- CPU gebruik
   export LOAD=$(cat /proc/loadavg | cut -d " " -f 1)
   #-- De volgende regels geven informatie over enkele gemounte 
   #   apparaten
   #   (Zip-drive, cdrom, lokale partitie...)
   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)
  
   # ***** SCHERM 1 *******
   # Hier wordt de verzamelde informatie weergegeven
   # Uptime, geheugen, HTTP/FTP gebruikers en load
     echo -e $UPT
     echo -e "MEM "$MEM
     echo -e "HTTP "$WEB" --  FTP" $FTP" "
     echo -e  $USER " load:" $LOAD
     sleep $SLEEP
     # De sleep tijd is hoe lang de informatie wordt weergegeven
   
   # ***** SCHERM 2 *******
   # Lijst van de gemounte apparaten
     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
  
   # ***** SCHERM 3 *******
   # Lijst van alle entries in de printer spool (wachtrij)
    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
  
   # ***** SCHERM 4 *******
   # Wat informatie over de netwerkkaart(en) 
    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
  


De scripts zijn erg simpel. De benodigde informatie wordt weergegeven met een kort commando en wordt verkregen met de tools "grep" en "cut". Op verschillende distributies kan dit wat problemen geven omdat de uitvoer van de programma's kan verschillen, zodat de gebruikte kolom in het cut commando fout is.
Als de specifieke informatie neit is verschenen op de display, zou je de commando's met de hand moeten controleren en de juiste waarden bepalen.

De informatie wordt opgeslagen in een variabele (bijv. $ETH_E voor het aantal ontvangen corrupte packets van de netwerkkaart) en dan geprint via echo.
In plaats hiervan kun je ook een ander programma gebruiken, zoals procload.

Zoals je kunt zien in regel 18, wordt het menu (own) gestopt als je de knoppen 1,2 en 4 indrukt en het bijbehorende menu (hier is het menu 1 voor alle) wordt gestart.
Het volgende script plaats je in de directory /usr/local/etc/display, en maak je ook uitvoerbaar.
Het bestand ziet er uit als:

Bestand /usr/local/etc/display/menu1
   #!/bin/sh       
   #  Eerst stop je de oude jslaunch, daar deze nog steeds de oude 
   #  configuratie gebruikt
   killall jslaunch
  
   #  Als het vorige menu in "sleep" modus bleef, moet deze ook gestopt
   #  worden.
   killall sleep
   
   #  Deze "slapende" tijd is nodig omdat de gebruiker genoeg tijd moet
   #  hebben om de knop weer los te laten. Anders start jslaunch niet 
   #  weer opnieuw.
   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
  
  
   #  Hier wat informatie over welke knop welke functie heeft
   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
   
   #  Nu starten we jslaunch met de nieuwe opties
   #  1 == mount Zip 
   #  2 == unmount Zip
   #  3 == bijvoorbeeld een menu, om een CD Rom te mounten -- 
   #       de regel is niet actief 
   #  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" &
  
   # Na 15 seconden gaat het menu terug naar main menu als er geen knop
   # werd ingedrukt.
   sleep 15
   /usr/local/etc/display/own
  


Het script om te rebooten ziet er uit als volgt (je kunt hier ook een vraag invoegen als "Echt rebooten?").

Script /usr/local/etc/display/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 schakelden we knop 3 uit omdat het nu duidelijk zou moeten zijn hoe je je eigen scripts maakt. Met knop 3 kun je naar een nieuw menu gaan waarin je bijvoorbeeld de CD-ROM driver kunt (un)mounten.
Maar je kunt ook andere schermen maken, zoals speciale status rapporten.
Ieder menu komt in een nieuw script in de directory /usr/local/etc/display/, en bouw je als volgt op:

Basis structuur
   #!/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
  
   #  Hier wat informatie over de commando's die worden uitgevoerd na het
   #  indrukken van een knop
   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
  
   #  Iedere knop krijgt een commando of een 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
  


Met deze methode kun je je eigen menu bouwen zonder grote inspanningen of diepgaande kennis van programmeertalen.

automatisch starten

De LCD display is ideaal voor een PC zonder monitor of toetsenbord, maar zonder die moet het menu automatisch worden gestart tijdens het booten.

Er zijn twee opties om dit te bereiken. Of je voegt het commando om de service te starten toe aan boot.local (te vinden in /sbin/init.d), of je schrijft een kort init script en plaatst deze in /sbin/init.d (SuSE) of /etc/rc.d/init.d (RedHat).

De commando's voor het laden van de LCD module en het starten van het menu script:

  /sbin/insmod lcd
  sleep 2
  /usr/local/etc/display/own &
  
Als je de LCD module niet hebt gekopieerd naar een subdirectory van /lib/modules (zie boven), moet je het volledige pad opgeven.

Daar zijn we dan. De LCD zou moeten werken en in deze afbeelding kun je zien hoe het er uit zou moeten zien:

Zelfgemaakte LCD opzet


http://www.home.unix-ag.org/nils/lcd.html Homepage van het programma lcd
http://www.linux-magazin.de/ausgabe/1999/08/LCD/lcd.html Artikel over het programmeren van lcd in de Duitse Linux Magzine
ftp://sunsite.org.uk/Mirrors/contrib.redhat.com/libc6/i386/ Sorry, jslaunch heeft geen eigen homepage.
http://lcdproc.omnipotent.net/ Drivers voor verschillende seriële displays
http://www.mv.com/ipusers/cdwalker/lpt_driver.html Drivers voor verschillende parallelle displays