--- /dev/null
+>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 <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#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<numlights;i++)
+ lights |= (1<<i);
+
+ port_out(0x378, lights);
+ usleep(750000L);
+ }
+}
+
+This program has to be suid root, due to the ioperm call.
+
+Good luck, and have fun! Your mileage may vary.. If this makes your computer
+explode or something, I'm not responsible, etc.. If you improve upon this,
+post it here, so everyone else can see!
+
+--
+joev@wpi.edu WPI Computer Science '97 Linux!
+ <a href="http://www.wpi.edu/~joev"> Click Here! </a>
+
+
+
+
+
+
+