- Linux
Matrix Orbital LK202-24-USB
I'd been given a Matrix Orbital a while ago, and a friend of mine (Rich Goodwin) had come up with some basic software to control it. It's downloadable from here. He didn't want to use LCDproc to control it - he wanted more manual control.
I did a bit of work on the software and sent it back to him - however, between us we never really did anything with it.
Since I didn't have a particular need for it, it languished on the top of my freezer for a while, until Friday 14th March 2009, I set up a new firewall/web server/email server, and I thought this would be ideal as a simple display panel.
I found the old code, and emailed Rich to let him know what I was doing. By coincidence, he'd just set up a new machine too, and wanted the code anyway.
Since it could be useful, I've decided to publish it. It's based on Rich's code (even has the comments in), with the following changes:
- Performs the initialisation for you
- Reads keys properly
- Doesn't use too much CPU
#!/usr/bin/perl # We use this to set the baud rate for the LCD unit use POSIX qw(:termios_h); # We use this to reduce CPU loading while having responsive keys use Time::HiRes; # open a file handle so we can write to the LCD screen open LCD, "+< /dev/ttyUSB0" or die("Couldn't open connection to USB device"); # Get the file descriptor for the LCD connection local $lcdfd = fileno(LCD); # Set up the termios control my $termios = POSIX::Termios->new; # Set baud rate and so forth (taken from LCDd) $termios->getattr($lcdfd); $termios->setiflag($termios->getiflag & ~ (&POSIX::IGNBRK | &POSIX::BRKINT | &POSIX::PARMRK | &POSIX::ISTRIP | &POSIX::INLCR | &POSIX::IGNCR | &POSIX::ICRNL | &POSIX::IXON)); $termios->setoflag($termios->getoflag & ~ (&POSIX::OPOST)); $termios->setlflag($termios->getlflag & ~ (&POSIX::ECHO | &POSIX::ECHONL | &POSIX::ICANON | &POSIX::ISIG | &POSIX::IEXTEN)); $termios->setcflag($termios->getcflag & ~ (&POSIX::CSIZE | &POSIX::PARENB)); $termios->setcflag($termios->getcflag | (&POSIX::CS8 | &POSIX::CREAD | &POSIX::CLOCAL)); $termios->setcc(&POSIX::VMIN, 1); $termios->setcc(&POSIX::VTIME, 3); $termios->setospeed(&POSIX::B19200); $termios->setispeed(&POSIX::B0); # And actually set the values $termios->setattr($lcdfd, &POSIX::TCSANOW); # Make buffers flush immediately (only for printing keys) $|=1; # clear the screen - we'll do this 3 times, so use a subroutine clear_screen(); # use the LCD file handle as the default print handle # - instead of each print statement starting LCD, # this is quicker. select LCD; # Pick out the relevant bits - uptime, users and current load average if (`uptime` =~ m~up\s+(.*?),\s+(\d+)\s+users?,\s+load average: ([0-9\.]+),~i) { my $uptime = $1; my $users = $2; my $load = $3; # clear the print our info, # wait for 5 seconds before moving on, # clear screen before printing more info. print "Uptime:\n"; print "$uptime\n"; wait_keys(5); clear_screen(); print "Users:\n"; print "$users\n"; wait_keys(5); clear_screen(); print "Current Load:\n"; print "$load\n"; wait_keys(5); } # Display the list of users (using 'who') my $user = 1; while(`who`=~m:([^ ]+).*?([^ ]+)[^\n]+\n:g) { clear_screen(); print "User $user:\n"; print "$1 on $2\n"; wait_keys(5); $user++; } clear_screen(); print "Demonstration over!\n"; print "Please call again.\n"; # Now we're done printing to LCD, # let's go back to STandarD OUTput select STDOUT; # We're finished writing to the LCD, so let's be neat # and close the file handle we opened at the start close LCD; sub clear_screen { print LCD chr(254) . chr(88); } sub wait_keys { my $wait = shift; # We use this for finding out if we've been alarmed local $finished = 0; # Set the alarm to clear the flag $SIG{ALRM} = sub { $finished = 1; }; # And set the time for the alarm to occur alarm($wait); # Repeat the following until the end... while($finished == 0) { # This bit is taken from the Perl FAQ # Works on Mandrake 10, Perl FAQ says it works on BSD local $rin; vec($rin, $lcdfd, 1) = 1; # Check to see if there's anything present if(select($rin, undef, undef, 0) > 0) { # Read whatever's in there my $l = ""; read LCD, $l, 1; print STDOUT $l; } else { Time::HiRes::usleep(10000); } } }
OpenBSD
OpenBSD 4.4 can use this device natively (in fact, I think it was in 3.7 that it could be). Just change the /dev/ttyUSB0
to /dev/cuaU0
- although if you run it as a user, you need to make sure you have read/write access to the port.