From joev@mikasa.WPI.EDU Sun Jan 1 18:34:40 EST 1995 Article: 144 of comp.os.linux.development.system Path: bigblue.oit.unc.edu!concert!gatech!bloom-beacon.mit.edu!news2.near.net!news.mathworks.com!bigboote.WPI.EDU!mikasa.WPI.EDU!joev From: joev@mikasa.WPI.EDU (Joseph W. Vigneau) Newsgroups: comp.os.linux.development.system Subject: My LED performance meter thing... Date: 1 Jan 1995 23:18:28 GMT Organization: Worcester Polytechnic Institute Lines: 147 Message-ID: <3e7d84$or5@bigboote.WPI.EDU> NNTP-Posting-Host: mikasa.wpi.edu Last week, someone wrote here asking about robotic contol via Linux... I responded explaining how I used the parallel port to control a sort-of "performance meter". I've recieved a lot of requests on how I did this. Here's the story: Last year, at school (WPI), Silicon Graphics brought this huge 18-wheel truck that is basically a demonstrationmobile. Inside it had Indys, Crimsons, and some of their big machines like a couple of Onyxes and an *monsterous* Power Challenge.. I'm relatively young (17 at the time), and I'd never seen a computer this big before: It looked like an oversized refrigerator, with cooling ducts running in and out of it! On the front of this beast, was a little LCD backlit readout about the size of my HP-48G's display. It was labeled "CPU Activity", and had a little bar chart showing how hard each processor was working. I thought it would be cool to have one of these mounted on my Linux box :) I finally got a computer of my own this past November, and finally got to run Linux on my own, instead of administering it for a number of people on my floor. I had a Shack attack, and went to Radio Shack, and picked up the following items: a breadboard, a 10-bar LED, breadboard wires, and a package of assorted resistors. [Side note: While at the Shack with a few of my suitemates, we were way in back in the component section (the only good part of the store any more), and were approached by a lady who thought we were employees there :). Back to the project.] It was wired up like this, via the parallel port: pin 20 (ground) | 150ohm LED | pin 2 (D0) ----/\/\/------|>|-----+ | pin 3 (D1) ----/\/\/------|>|-----+ | pin 4 (D2) ----/\/\/------|>|-----+ [...] | pin 9 (D7) ----/\/\/------|>|-----+ Note: 2 of the LEDs weren't connected. Now, the software part: Two files were used: the first is a routine written by a roomate (damianf@wpi.edu) used to blast raw bytes at a port, and read them. Please contact him for more info, or if you want to use it in a progrm of your own. static inline int port_in( int port ) { unsigned char value; __asm__ volatile ("inb %1,%0" : "=a" (value) : "d" ((unsigned short)port)); return value; } static inline void port_out( unsigned short int port, unsigned char val ) { __asm__ volatile ( "outb %0,%1\n" : : "a" (val), "d" (port) ); } I originally wanted to use the load average to determine how many of the LEDs lit up, but realized that it was only updated every minute.. I wanted a display similar to xload or xosview, but I really coun't figure out how they were determined.. What I ended up doing was reading the output of 'ps aux', and summing up the %CPU column. I then converted that into a number representing how many LEDs should light, and blast it at the printer port. NOTE: I wrote and built this thing in a bout 90 minutes, so it's quick and dirty, and not at all as elegant as I hoped it to be. Here's the program: /* meter.c by Joseph W. Vigneau (joev@wpi.edu) (c)1994. This program is covered under the GNU copyleft agreement. */ #include #include #include #include #include "port.h" float loadavg(void) { FILE *f; char line[80]; float cpu = 0.0, totalcpu = 0.0; if((f = popen("/bin/ps -aux","r"))==NULL) { fprintf(stderr,"Couldn't fork /bin/ps.\n"); exit(1); } fgets(line, 80, f); while(!feof(f)) { sscanf(line,"%*s %*d %f",&cpu); totalcpu += cpu; fgets(line, 80, f); } /* printf("TOTAL: %f\n",totalcpu); */ pclose(f); return totalcpu/100.0; } main() { unsigned char lights; float ave; char dir = 0; char foo[10]; register unsigned char numlights, i; if(ioperm(0x378,1,1)) { fprintf(stderr,"ioperm error.\n"); exit(1); } while(1) { ave = loadavg(); numlights = (int)(ave*8.0); /* printf("ave = %f, numlights = %d\n",ave, numlights); */ lights = 0; for(i=0;i Click Here!