Thorn
Posts: 21
Joined: Wed Aug 10, 2011 7:09 pm
Location: Scotland
Contact: Website

LED CPU Meter (GPIO)

Mon Oct 01, 2012 7:26 pm

Hey there, not sure if this has been done before or whether this is the right forum (there's so many here now!)

To get to grips with GPIO, I created a small LED meter for total CPU usage on the pi. Sharing's caring, so I chose to throw it up here so other people can perhaps benefit from it.

It depends on GordonDrogon's awesome WiringPi library.

Photo of it in action:
Image

Link to source file: http://thoronir.net/raspi-dev/gpio/cpumeter.c

timbro321
Posts: 39
Joined: Fri May 25, 2012 6:49 pm

Re: LED CPU Meter (GPIO)

Mon Oct 01, 2012 8:03 pm

Do You know how to do this in Python?

Thanks

Thorn
Posts: 21
Joined: Wed Aug 10, 2011 7:09 pm
Location: Scotland
Contact: Website

Re: LED CPU Meter (GPIO)

Mon Oct 01, 2012 8:09 pm

timbro321 wrote:Do You know how to do this in Python?

Thanks
No idea, I don't have a decent understanding of python I'm afraid. The wiringPi library is provided for python aswell so I'm not sure if it'd be much different as there's nothing C-specific here. The workflow is pretty simple ->

Initialise wiringPi and GPIO pins
while running
calculate cpu usage by reading /proc/stat
decide how many LED's to light from this
done

If you want, I'll have enough spare time later this week to create a python version hopefully.

Matt1234
Posts: 33
Joined: Mon Aug 06, 2012 12:34 pm

Re: LED CPU Meter (GPIO)

Mon Oct 01, 2012 8:30 pm

That would be really useful for me also!

So I see that you can find out info from ,what , text files? Correct me if I am wrong!

I am struggling to connect things, internally and then externally... Like make an LED flash when I have a new email etc etc etc.

Thanks and your project looks good!
;)

Thorn
Posts: 21
Joined: Wed Aug 10, 2011 7:09 pm
Location: Scotland
Contact: Website

Re: LED CPU Meter (GPIO)

Mon Oct 01, 2012 9:28 pm

Matt1234 wrote:That would be really useful for me also!

So I see that you can find out info from ,what , text files? Correct me if I am wrong!

I am struggling to connect things, internally and then externally... Like make an LED flash when I have a new email etc etc etc.

Thanks and your project looks good!
;)
Hey,

Yeah, it reads /proc/stat which is in text format.

Flashing an LED with new mail is somewhat more involved. I believe with imap you can login to the mail server and check how many unread messages are currently sitting there, then flash your LED accordingly. However I'm not totally sure on that, and I have no idea how it would apply to incoming mail from pop3.

I'm considering turning this into a youtube channel which teaches GPIO from beginner applications into move involved projects such as that, however I'm not sure if there would be much interest.

anat
Posts: 19
Joined: Mon Aug 27, 2012 12:45 am

Re: LED CPU Meter (GPIO)

Fri Oct 05, 2012 1:12 am

Nice project. I found an LED8BUS chip
http://www.ebay.com/itm/Rapid-Prototypi ... 2c66f0530b

and soldered it on a K000 Slice of Pi board. Everything can fit in a case.
Image

It will try your program tonight.

User avatar
Bigcat123
Posts: 230
Joined: Thu Aug 23, 2012 2:41 pm

Re: LED CPU Meter (GPIO)

Fri Oct 05, 2012 6:12 am

If you did you would have quite a few rivals! You have Raspberry Pi Tutorials, Raspberry Pi Beginners AND The Raspberry Pi Guy to keep up with! I am not sure it would go in your favour....
Just a beginner sharing his experiences on his way to geek nirvana...

zippy54
Posts: 3
Joined: Tue Dec 25, 2012 10:34 pm

Re: LED CPU Meter (GPIO)

Tue Dec 25, 2012 10:39 pm

Hello,

I was looking through your source code and came across a small bug; it's very easy to do, I've go to admit I've done this with unsigned ints.

Code: Select all

// Initalise all LED's and default them off
    for(int i=0; i < number_leds; i++)
On the 5th iteration we'll ping the LEDs then execute the statement in the loop which will evaluate the variable i and add one to the total. We're now at 6 which does not fit the criteria of the loop, so we skip onto the next statement, we'll not initalise the sixth LED.

Instead:

Code: Select all

// Initalise all LED's and default them off
    for(int i=0; i <= number_leds; i++)
it's now six inclusive.

Vassius
Posts: 25
Joined: Sun Jun 03, 2012 7:56 pm

Re: LED CPU Meter (GPIO)

Wed Dec 26, 2012 9:54 pm

zippy54 wrote:Hello,

I was looking through your source code and came across a small bug; it's very easy to do, I've go to admit I've done this with unsigned ints.

Code: Select all

// Initalise all LED's and default them off
    for(int i=0; i < number_leds; i++)
On the 5th iteration we'll ping the LEDs then execute the statement in the loop which will evaluate the variable i and add one to the total. We're now at 6 which does not fit the criteria of the loop, so we skip onto the next statement, we'll not initalise the sixth LED.

Instead:

Code: Select all

// Initalise all LED's and default them off
    for(int i=0; i <= number_leds; i++)
it's now six inclusive.
The pins are 0-indexed, and the for loop starts at 0 as well. The loop makes six iterations with i at values 0, 1, 2, 3, 4 and 5. Your modification would loop seven times with i == 0 included.

zippy54
Posts: 3
Joined: Tue Dec 25, 2012 10:34 pm

Re: LED CPU Meter (GPIO)

Thu Dec 27, 2012 1:22 pm

I understand where you're coming from here. Have you tested to make sure you setup all the LEDs?

It seems I was confused with your const variable you make it seem like you have seven LEDs instead of six. Nonetheless, I retract my previous statement, I didn't see it was just six and I didn't know GPIOs were zero-indexed. I come from a language where you can define where arrays index from; you can set any value such as 100 instead of it being language defined.

n33kos
Posts: 1
Joined: Fri Oct 14, 2016 8:52 pm

Re: LED CPU Meter (GPIO)

Fri Oct 14, 2016 10:32 pm

I know this thread is currently 4 years old but I'd like to say many thanks for posting the source for your project! :D

I have a headless pi I've been using as a development server and wanted a quick and dirty way to monitor CPU usage. Your code worked but I had to make some modifications to clear up compilation errors (This may be due to issues in my own environment):

1) I had to include:

Code: Select all

#include <stdlib.h>
#include <string.h>
2) I had to compile in C99 mode with

Code: Select all

-std=c99
I also made adjustments to the code for my own purposes. The leading dark LED in my version flashes to represent what percentage of that interval is being used. This way you can glean a little more information if you only have a few LEDs to work with. My version is a more CPU intensive so you may want to turn down the delay on slower pi versions.

I figured I would share my modifications in the event that it benefits anyone else. I noticed your original link seems to be hosted on a forum, If its agreeable to you I'll post my entire version in a code block here for duplicity. I would hate for that link to go dark and lose such a great resource.

Code: Select all

// cpumeter.c - Raspberry Pi GPIO LED CPU Meter
// Michael Rodenhurst, 30/09/12 | Nicholas Suski 10/14/16
//
// LEDS are illuminated to represent cpu usage incrementally starting at GPIO 0 
// CPU values which fall inbetween LED increments are represented by leading LED flash rate
//
// Compile: $ gcc cpumeter.c -ocpumeter -lwiringPi -std=c99

#include <stdio.h>
#include <unistd.h>
#include <wiringPi.h>
#include <stdlib.h>
#include <string.h>

#define VERSION "1.1"

// We assume these start at GPIO 0
const int number_leds = 5;
int previous_tjif = 0;
int previous_ijif = 0;
int refresh_delay = 50;
int looptimer = 0;

void initialise();
void update();
int get_cpu_usage();

int main()
{
	printf("CPU LED Meter, Version %s\n", VERSION);

	initialise();

	while(1)
	{
		update();
		delay(refresh_delay);
	}

	return 0;
}

void initialise()
{
	// Verify we are root
	if(geteuid() != 0)
	{
		printf("This program must run as root\n");
		exit(0);
	}

	if(wiringPiSetup() < 0)
	{
		printf("wiringPiSetup() failed!\n");
		exit(1);
	}

	printf("Initialise GPIO pins...\n");

	// Initalise all LED's and default them off
	for(int i=0; i < number_leds; i++)
	{
		pinMode(i, OUTPUT);
		digitalWrite(i, 0);
	}

	printf("Done\n");
}

void update()
{
	// Disable all LED's
	for(int i=0; i < number_leds; i++)
		digitalWrite(i, 0);

	int cpu_usage = get_cpu_usage();
	int leds_lit = cpu_usage/(100/number_leds);

	for(int i=0; i <= leds_lit; i++){
		if (i == leds_lit){
			looptimer = looptimer+1;
			if (looptimer > 255)
				looptimer = 0;
			if (looptimer % (refresh_delay - (cpu_usage/100)*refresh_delay) == 0)
				digitalWrite(i, 1);
		}else{
			digitalWrite(i, 1);
		}
	}
	
   //printf("CPU Usage: %d -- ", cpu_usage);
   //printf("Leds Lit: %d\n", leds_lit);
}

// Return value 0-100
int get_cpu_usage()
{
	char *buf = malloc(48);

	// Read the cpu status from /proc/stat
	FILE *fp = fopen("/proc/stat", "r");
	fread(buf, sizeof(char), 48, fp);
	fclose(fp);

	// Strip the prefixed "cpu  "
	char *cpuline = malloc(48);
	for(int i=5; i<strlen(buf); i++)
		cpuline[i-5] = buf[i];

	cpuline[40] = '\0';

	// Parse the proc/stat information into seperate jiffie containers
	int user_jif, nice_jif, system_jif, idle_jif;
	int iowait_jif;

	char *tokbuf = strtok(cpuline, " ");
	user_jif = atoi(tokbuf);
	tokbuf = strtok(NULL, " ");
	nice_jif = atoi(tokbuf);
	tokbuf = strtok(NULL, " ");
	system_jif = atoi(tokbuf);
	tokbuf = strtok(NULL, " ");
	idle_jif = atoi(tokbuf);
	tokbuf = strtok(NULL, " ");
	iowait_jif = atoi(tokbuf);

	// Get the workload from that
	int tjif = user_jif + nice_jif + system_jif + idle_jif + iowait_jif;

	int delta_total = tjif - previous_tjif;
	int delta_idle = idle_jif - previous_ijif;
	int delta_usage = (1000*(delta_total-delta_idle)/(delta_total+5))/10;
	previous_tjif = tjif;
	previous_ijif = idle_jif;

	free(cpuline);
	free(buf);

	return delta_usage;
}

Image

Return to “C/C++”