Archive for December 6th, 2012

Arduino Snippets: LED Bargraph Display

An LED bargraph display comes in handy for displaying a tuning center point, monitoring a sensor above-and-below a setpoint, and suchlike.

Given the number of output bits, this requires a pair of ‘595 shift registers. There’s no particular need for speed, so the shiftOut() function will suffice. That means the register control bits don’t need the dedicated SPI pins and won’t soak up the precious PWM outputs required by, say, the RGB LED strip drivers.

LED Bargraph Display

LED Bargraph Display

It’s Yet Another Solderless Breadboard Hairball:

LED Bargraph Display - breadboard

LED Bargraph Display – breadboard

The upper LED bargraph is an HPSP-4836 RRYYGGYYRR block, the lower one is an all-green GBG1000. The bottom four LEDs aren’t connected; you could add another ‘595 shift register, but then you’d have four bits left over and you’d be forced to add more LEDs. Four bricks and five ‘595 chips would come out even, if you’re into that.

The LEDs run at about 4 mA, which would be enough for decoration in a dim room and seems about the maximum the poor little 74HC595 chips can supply. If you need more juice, you need actual LED drivers with dimming and all that sort of stuff.

You need not use LED bargraphs, of course, and discrete LEDs for the lower six bits make more sense. They’ll be good for mode indicators & suchlike.

The demo code loads & shifts out alternating bits, then repeatedly scans a single bar upward through the entire array. Note that the bar is just a bit position in the two bytes that get shifted out every time the array updates (which is every 100 ms); the array is not just shifting a single position to move the bar. Verily, the bar moves opposite to the register shift direction to demonstrate that.

The Arduino source code:

// LED Bar Light
// Ed Nisley - KE4ANU - November 2012

// Pin assignments
// These are *software* pins for shiftOut(), not the *hardware* SPI functions

const byte PIN_MOSI = 8;			// data to shift reg
const byte PIN_SCK  = 6;			// shift clock to shift reg
const byte PIN_RCK  = 7;			// latch clock

const byte PIN_SYNC = 13;			// scope sync

// Constants

const int UPDATEMS = 100;				// update LEDs only this many ms apart

#define TCCRxB 0x02						// Timer prescaler

// Globals

word LEDBits;

unsigned long MillisNow;
unsigned long MillisThen;

//-- Helper routine for printf()

int s_putc(char c, FILE *t) {

//-- Send bits to LED bar driver register

void SetBarBits(word Pattern) {

	shiftOut(PIN_MOSI,PIN_SCK,MSBFIRST,Pattern >> 8);
	shiftOut(PIN_MOSI,PIN_SCK,MSBFIRST,Pattern & 0x00ff);



// Set things up

void setup() {
	digitalWrite(PIN_SYNC,LOW);	// show we arrived

//	TCCR1B = TCCRxB;					// set frequency for PWM 9 & 10
//	TCCR2B = TCCRxB;					// set frequency for PWM 3 & 11




	fdevopen(&s_putc,0);				// set up serial output for printf()

	printf("LED Bar Light\r\nEd Nisley - KE4ZNU - November 2012\r\n");

	LEDBits = 0x5555;

	MillisThen = millis();


// Run the test loop

void loop() {

	MillisNow = millis();

	if ((MillisNow - MillisThen) > UPDATEMS) {


		LEDBits = LEDBits >> 1;
		if (!LEDBits) {
			LEDBits = 0x8000;
			printf("LEDBits reset\n");

		MillisThen = MillisNow;