#!/usr/bin/perl # # removed -w # # Original Code # -------------- # http://www.Linux-1U.net/LCD/scripts/lcd.keypad.pl # # #--------------------------------------- # # test_lcd.keypad.pl display stuff to the LCD # # 07-Jul-00 amo Date-of-Birth ( stolen from record_sensors.pl ) # 20-Apr-01 amo Use ifconfig instead ( os independent ) # 17-Sep-02 srs Reinvtented as a LCD controller # 30-Oct-02 amo Cleanup wierd characters, reformat script for BPI-216L # 10-Nov-02 amo Added Codes for MatrixOrbital LK202-25, Cleaned up with srs in Sep # # # # =========================================== # use strict ; # # For check the keyboard for keyhits with lcd_key() # # To Install the perl module # -------------------------- # perl -MCPAN -e shell # cpan> install Term::ReadKey # require Term::ReadKey; use Term::ReadKey; # # # Name of the program # my ( $NM ) = "lcd.keypad.pl"; # keep a short name for LCD my ( $VER ) = "2.2.0"; # my ( $LCDTYPE ) = "BPI-216L"; $LCDTYPE = "LK202-25"; # MatrixOrbital # # my ( $DEBUG ) = 0; # debug my ( $SLEEP ) = 2; # time between scroll/updates # my ( $status ) = 0; # # # which serial port is the display attached to # #y ( $SERIALPORT ) = "/dev/ttyS0"; # RS232 connector on back my ( $SERIALPORT ) = "/dev/ttyS1"; # 9-pin header inside on motherboard # my ( $SERIALRATE ) = "9600"; # Default to 9600 baud my ( $WIDTH ) = 16; # Default to 16 x 2 LCD # # # Cursor Code For BPI-216L # ------------------------ # my ( $CMD ) = "\xFE"; # general command prefix my ( $CLS ) = "\x01"; # clear display my ( $HOME ) = "\x02"; # Home my ( $Line1 ) = "\xEF"; # Line1 my ( $Line2 ) = "\xC0"; # Line2 # # # For MatrixOrbital LK202-25 # -------------------------- # my ( $KeyF1, $KeyF2, $KeyF3, $KeyUP, $KeyDN, $KeyLE, $KeyRI, $KeyOK, $KeyEsc ) = ""; # if ( $LCDTYPE eq "LK202-25" ) { # $SERIALRATE = "19200"; $WIDTH = 20; # 20x2 serial lcd baudrate # $CMD = ""; # no command code $CLS = "\x0C"; $Line1 = "\xFE\x48"; # why does it need 2 hex numbers ?? $Line2 = "\x0A"; # # $KeyF1 = "C"; # Function Key $KeyF2 = "H"; # Function Key $KeyF3 = "M"; # Function Key # $KeyUP = "D"; # Up key $KeyDN = "J"; # Down key $KeyLE = "I"; # Left key $KeyRI = "N"; # Right key # $KeyEsc = "E"; # Esc key $KeyOK = "O"; # OK key # # system ( "stty $SERIALRATE < $SERIALPORT" ); # $status = open ( LCDIN, "< $SERIALPORT"); if ( $status == 0 ) { printf "ERROR: Can not read from LCDport=$SERIALPORT\n"; exit 1; } # } # MatrixOrbital # # # End User Changes # # =========================================== # # Open for writing to the LCD port # system ( "stty $SERIALRATE <$SERIALPORT" ); # $status = open ( LCDOUT, "> $SERIALPORT"); if ( $status == 0 ) { printf "ERROR: Can not write to LCDport=$SERIALPORT\n"; exit 1; } # # # Check command line arguments # ---------------------------- &cmd_args; # # # Get some info about the hosts # ----------------------------- # &lcd_init; # initialize the LCD # # load up the data block for LCD display # my ( $LCD_First ) = 1; # first data my ( $LCD_Last ) = 0; # Last data # my ( @DATA ) = &lcd_data; # # # display the data # &lcd_display ; # close LCDOUT; # exit 0; # # # =========================================================== # # Initialize the Serial Port ( LCD ) # ----------------------------------- # sub lcd_init { # system ( "stty $SERIALRATE <$SERIALPORT" ); # # open ( LCDOUT, "> $SERIALPORT"); # } # lcd_init # # # Clear LCD screen # ---------------- sub lcd_cls { # printf LCDOUT "${CMD}$CLS"; # } # lcd_cls # # # Home # ---------------- sub lcd_home { # printf LCDOUT "$CMD" . "$HOME"; # } # lcd_home # # # Get the Hostname # ----------------- sub lcd_get_hostname { # my ( $opt ) = $_[0]; # my ( $host ) = `hostname $opt`; chomp ( $host ); # return ( $host ); # } # lcd_get_hostname # # # Get the IP # ----------- sub lcd_get_ip { # my ( $ip_gw ) = $_[0]; # my ( @ipaddr, @f ) = (); my ( $ip, $str ) = ""; # if ( $ip_gw eq "gw" ) { # # default w.x.y.z 0.0.0.0 UG 0 0 0 eth0 @ipaddr = split ( /\s+/, ` route -v | grep default ` ); # } else { # # inet addr:166.90.172.11 Bcast:166.90.172.255 Mask:255.255.255.0 @ipaddr = split ( /:/, `ifconfig -v | grep -i "inet addr" | grep -v 127.0.0 ` ); # } # $str = $ipaddr[1]; ( $ip, @f) = split ( /\s+/, $str ); # return ( $ip ); # } # lcd_get_ip # # # Get the ProcessID # ------------------ # sub lcd_get_pid { # my ( $str ) = ` ps auxw | grep $NM `; my ( $x_y, $pid, @foo ) = split ( /\s+/, $str ); # return ( $pid ); # } # lcd_get_pid # # # Get CPU Info # ------------ # model name : AMD Athlon(tm) # cpu MHz : 1152.633 # sub lcd_get_cpuinfo { my ( $key ) = $_[0]; # my ( $cpuinfo ) = `cat /proc/cpuinfo | grep -i "$key"`; # $cpuinfo =~ s/\(tm\)//; # my ( $str, $info ) = split ( /:/, $cpuinfo ); # $info =~ s/^\s+//; # get rid of leading spaces $info =~ s/\s+$//; # trailing spaces # return ( "$info" ); } # lcd_get_cpuinfo # # # Get CPU load # ------------- # sub lcd_get_cpuload { my ( $str ) = `cat /proc/loadavg`; my ( $min, $typ, $max, @foo ) = split ( /\s+/, $str ); # return ( "$min..$typ..$max" ); } # lcd_get_cpuload # # # Get Mem load # ------------- # sub lcd_get_memswapload { # my ( $ms ) = $_[0]; # Mem: or Swap: # my ( $str ) = `cat /proc/meminfo | grep $ms:`; my ( $key, $tot, $used, $free, @foo ) = split ( /\s+/, $str ); # my ( $t, $u, $f ) = ""; # $t = &lcd_MK ( $tot ); $u = &lcd_MK ( $used ); $f = &lcd_MK ( $free ); # # printf "$t..$tot....$u..$used....$f..$free..\n"; # return ( "$t..$u..$f" ); } # lcd_get_memswapload # # # netstat -iv # ----------- # Kernel Interface table # Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg # eth0 1500 0 7984 0 0 0 2244 0 0 0 BMRU # lo 16436 0 218 0 0 0 218 0 0 0 LRU # # Get Network load # ----------------- # sub lcd_get_netload { my ( $str ) = `netstat -iv | grep eth0`; my ( $eth, $mtu, $met, $RCV, $e, $d, $o, $TX, @foo ) = split ( /\s+/, $str ); # return ( "R=$RCV X=$TX" ); } # lcd_get_netload # # # Get Disk load # ------------- # df - hangs on NFS issues # /dev/hda1 256667 123084 120331 51% / # /dev/hda2 256665 8263 235149 4% /tmp # /dev/hda3 521780 175404 319872 36% /var # # cat /proc/mounts # /dev/root / ext3 rw 0 0 # /dev/hda2 /tmp ext3 rw 0 0 # /dev/hda3 /var ext3 rw 0 0 # # sub lcd_get_diskload { my ( $part ) = $_[0]; # which partition # my ( @df ) = `df | grep "$part" `; my ( $p, $m, $u, $l, $per, $name ) = split ( /\s+/, "$df[0]" ) ; my ( $mk ) = "xx"; # $mk = &lcd_MK ( "$m" ) if ( $#df >= 0 ); # return ( "$name $mk $per" ); # } # lcd_get_diskload # # # Get CPU Temperature, fan speed # ------------------------------ # fan2: 6750 RPM (min = 3000 RPM, div = 2) # temp2: +53.5°C (limit = +60°C, hysteresis = +50°C) sensor = thermistor # sub lcd_get_cpu_tf { my ( $tf ) = $_[0]; # cpu temp or cpu fan my ( @data3 ) = `sensors | grep $tf`; my ( @res, @f, @t ) = (); # my ( $id, $key, $r, $t ) = 0; # for ( $id=0; $id <= $#data3; $id++ ) { ( $key, $res[$id], @f ) = split ( /\s+/, $data3[$id] ); # # Get rid of the whacky degree symbol before C ( centigrade ) # $r = $res[$id]; # if ( $tf eq "temp" ) { chop ( $r ); chop ( $r ); $r =~ s/^\+//; $r .= "C"; # append centigrade letter } # temp # $t[$id] = "$r"; # } # fan and temp sensors # $r = join ( " ", @t ); # return ( "$r" ); } # lcd_get_cpu_tf # # # # Convert the number 1234567 to 1234K # ------------------------------------ # sub lcd_MK { my ( $n ) = $_[0]; # my ( $kk ) = $n / 1000; my ( $mm ) = $n / 1000000; # my ( $m, $k, @f ) = 0; # if ( $mm > 1 ) { ( $m, @f ) = split ( /\./, $mm ); return ( "${m}M" ); } elsif ( $kk > 1 ) { ( $k, @f) = split ( /\./, $kk ); return ( "${k}K" ); } else { return ( $n ); } # } # lcd_MK # # # Time and Date stamp # ------------------- sub lcd_get_ts { my ( $id ) = $_[0]; # # Thu Oct 31 19:58:50 PST 2002 my ( $dow, $mon, $day, $time, $zone, $year ) = split ( /\s+/, ` date `); # if ( $id == 1 ) { return ( "$dow $mon $day $year" ); } else { return ( "$time $zone" ); } # } # lcd_get_ts # # # Load a bunch of Data to the Array for display selection # -------------------------------------------------------- # sub lcd_data { # # printf "..Loading data ..\n" if ( $DEBUG >= 2 ); # # NOT all data need to be re-read # $DATA[0] = 0; # initialize $DATA[1] = "$NM-$VER"; $DATA[2] = &lcd_get_pid; $DATA[3] = &lcd_get_hostname ( "-s" ); # hostname -s $DATA[4] = &lcd_get_hostname ( "-d" ); # hostname -d $DATA[5] = &lcd_get_ip ( "ip" ); # ip# $DATA[6] = &lcd_get_ip ( "gw" ); # gateway $DATA[7] = &lcd_get_cpuinfo ( "model name" ); # model name : AMD Athlon(tm) $DATA[8] = &lcd_get_cpuinfo ( "cpu Mhz" ) ; # cpu MHz : 1152.633 # # dynamic data # $DATA[9] = "CPU Load"; $DATA[10] = &lcd_get_cpuload; $DATA[11] = "Memory Load"; $DATA[12] = &lcd_get_memswapload ( "Mem" ); $DATA[13] = "Swap Load"; $DATA[14] = &lcd_get_memswapload ( "Swap" ); $DATA[15] = "eth0: Rcv/Xmit"; $DATA[16] = &lcd_get_netload; $DATA[17] = "Disk Load"; $DATA[18] = &lcd_get_diskload ( "/" ); $DATA[19] = &lcd_get_diskload ( "/tmp" ); $DATA[20] = &lcd_get_diskload ( "/var" ); $DATA[21] = &lcd_get_diskload ( "/usr" ); $DATA[22] = &lcd_get_diskload ( "/opt" ); # $DATA[23] = "Temp1 Temp2 Temp3"; $DATA[24] = &lcd_get_cpu_tf ( "temp" ); $DATA[25] = "Fan1 Fan2 Fan3"; $DATA[26] = &lcd_get_cpu_tf ( "fan" ); $DATA[27] = &lcd_get_ts ( 1 ); # date $DATA[28] = &lcd_get_ts ( 2 ); # time $DATA[29] = 0; # initialize # $LCD_Last = 27; # return ( @DATA ); # } # lcd_data # # # Check the Keyboard for new keystrokes on PS/2 kb # ------------------------------------------------- # sub lcd_keyboard { my ( $id ) = $_[0]; my ( $w ) = $_[1]; # update after 5 passes # # # MUST correspond to lcd_data() above my ( %KeyID ) = (); # # id is 2 less than what it should be for NEXT item to display # $KeyID{ "h" } = 3; # hostname $KeyID{ "i" } = 5; # IP# $KeyID{ "c" } = 7; # CPU Type # $KeyID{ "l" } = 9; # CPU load $KeyID{ "m" } = 11; # Memory load $KeyID{ "s" } = 13; # Swap load $KeyID{ "n" } = 15; # Network load $KeyID{ "d" } = 17; # Disk load # 19 # /tmp /var # 21 # /usr /opt $KeyID{ "t" } = 23; # Temp $KeyID{ "f" } = 25; # Fan # $KeyID{ "\n" } = $id +1; # next entry # # # Check the ps/2 keyboard # ------------------------ ReadMode 3; # my ( $key ) = ReadKey ( -1 ); # check the ps/2 keyboard # my ( $nid ) = 0; # my ( $update ) = 0; $update = 1 if ( $w >= $SLEEP ); # my ( $kb ) = 0; # keyboard found # # # Process the key found on the PS/2 keyboard or the LCD keypad # ------------------------------------------------------------ # if ( defined $key ) { # # force an update of the screen # $update = $kb = 1 ; # keyboard found, dont wait # if ( $key eq "q" ) { printf "QUIT\n" ; exit 1; } else { # printf "PS2_key=$key..\n" if ( $DEBUG ); # # which item to display next # ========================== $nid = $KeyID{ $key }; # $id = $nid if ( $nid >= 1 ); } # which key } # key found # # $id = $#DATA -2 if ( $id < 1 ); # go to last data entry $id = 1 if ( $id >= $#DATA ); # rolling backwards # # Display the data to the LCD ( after 5 passes or found keyhit ) # --------------------------- &lcd_out ( $id, "-1", "-1" ) if ( $update ); # # return ( $id, $kb ); # } # lcd_keyboard # # # Read the LCD Keypad of MatrixOrbital LK202-25 # ------------------------------------ # sub lcd_keypad { # my ( $id ) = $_[0]; # my ( $kb ) = 0; # no keypad hit # # # Check the LCD keypad # -------------------- ReadMode ( 3, \*LCDIN ); # Read the LCD keypad # my ( $key ) = ReadKey ( -1, \*LCDIN ); # check the lcd keypad # # # Process the LCD keypad found # ----------------------------- # if ( defined $key ) { # $kb = 1 ; # keyboard found, dont wait # printf "LCD_keypad=$key..\n" if ( $DEBUG ); # if ( $key eq "Huh" ) { printf "Dummy\n"; } elsif ( $key eq $KeyF1 ) { $id = 1; # home &lcd_out ( $id, "F1", "Define F1" ); } elsif ( $key eq $KeyF2 ) { &lcd_out ( $id, "Func 2", "Define Func 2" ); } elsif ( $key eq $KeyF3 ) { $id = 25; # End &lcd_out ( $id, "Function 3", "Define Function 3" ); } elsif ( $key eq $KeyUP ) { $id -= 1; # go to prev menu $id = $#DATA -2 if ( $id < 1 ); # go to last data entry $id = 1 if ( $id >= $#DATA ); # rolling backwards &lcd_out ( $id, "-1", "-1" ); } elsif ( $key eq $KeyDN ) { $id += 1; # skip over a menu item $id = $#DATA -2 if ( $id < 1 ); # go to last data entry $id = 1 if ( $id >= $#DATA ); # last data will show "zero" &lcd_out ( $id, "-1", "-1" ); } elsif ( $key eq $KeyLE ) { &lcd_out ( $id, "left", "New Left Menu" ); } elsif ( $key eq $KeyRI ) { &lcd_out ( $id, "right", "New Right Menu" ); } elsif ( $key eq $KeyEsc ) { &lcd_out ( $id, "escape", "Erase stuff later" ); } elsif ( $key eq $KeyOK ) { &lcd_out ( $id, "Okay", "okay for now" ); } # } # have LCD keypad pressed # return ( $id, $kb ); # } # lcd_keypad # # # # Show Something on the LCD # -------------------------- # sub lcd_display { # my ( $id, $jd, $d, $e, $key ) = 0; # my ( $w ) = 0; # wait before next menu item my ( $kb ) = 0; # # Initial setup info dumped to the screen # printf "\n"; printf "$NM: $LCDTYPE LCD on serial port=$SERIALPORT..$SERIALRATE..pid=%s..\n", &lcd_get_pid; printf "\n"; # # # # Indefinitely loop around and show data # -------------------------------------- # while ( 1 ) { # # Get new block of data for lcd updates # -------------------------------------- &lcd_data; # # # Print the data to the LCD # ------------------------- # for ( $id = 1; $id <= $#DATA; $id +=2 ) { # $kb = 0; # kbhit found # for ( $w = 0; $w <= $SLEEP ; $w += 1 ) { # # printf "..id=$id..w=$w..db=$kb..\n"; # # Check for new PS/2 Keyboard # --------------------------- ( $id, $kb ) = &lcd_keyboard ( $id, $w ); # # # Skip if we're out of bounds # if (( 0 < $id ) && ( $id <= $#DATA )) { # # Check the LCD Keypad for MatrixOrbital # -------------------------------------- ( $id, $kb ) = &lcd_keypad ( $id ) if ( $LCDTYPE eq "LK202-25" ) ; # } # out of bounds # # # wait 1 second before checking for a key again # except if we are done .. # $w = 0 if ( $kb ); # new key/display, wait again # sleep 1 if ( $w <= $SLEEP ); # } # wait between display # } # for each data entry # } # while loop - indefinitely # } # lcd_display # # # Display the Text to the LCD Screen # ---------------------------------- # sub lcd_out { my ( $id ) = $_[0]; my ( $str1 ) = $_[1]; # -1 or string my ( $str2 ) = $_[2]; # # Normal Data to display # my ( $d ) = $DATA[$id]; my ( $jd ) = $id+1; my ( $e ) = $DATA[$jd]; # # # Display these values instead # $d = "$str1" if ( $str1 ne "-1" ); $e = "$str2" if ( $str2 ne "-1" ); # if ( $DEBUG >= 2 ) { printf "data[$id]=$d\n"; printf "data[$jd]=$e\n"; } # # # Clear the LCD display # ------------------------------ # printf LCDOUT "${CMD}$CLS"; # CLS # # # Output ( left justified ) string to the LCD # printf LCDOUT "${CMD}$Line1"; # Line1 printf LCDOUT "%*s", -$WIDTH, $d; # printf LCDOUT "${CMD}$Line2"; # Line2 printf LCDOUT "%*s", -$WIDTH, $e; # printf LCDOUT "\n"; # flush the lcd # } # lcd_out # # # Check the Command line arguments # -------------------------------- # sub cmd_args { my ( $i ) = 0; my ( $arg ) = ""; # while ( $i <= $#ARGV ) { $arg = $ARGV[$i]; $DEBUG = 1 if ( $arg eq "-d" ); $i += 1; } # } # cmd_args # # # end of file