Jump to content
RobG

Wearable WS2812 Strip Controllers

Recommended Posts

If you have one of those 5050/WS2811 aka WS2812 strips and you want to "wear" it, I have a board for you.

Here are the specs:

  • 20pin MSP430G2xx3
  • 5V power supply
  • 0.05" programming header
  • UART input (allows pixel or sequence control)
  • 11mm wide (0.45")
  • 25mm long (1")
  • 32mm long (1.25") - version with memory
  • optional SOIC SRAM or EEPROM
  • 1mm thick

There are 4 boards on the panel, 2 with memory option.

 

Assembled boards

post-73-0-47244300-1370913676_thumb.jpg

 

Board in the sleeve

post-73-0-90847300-1370913684_thumb.jpg

 

Board attached to 30 LED strip (0.5m)

post-73-0-24147200-1370913681_thumb.jpgpost-73-0-22169000-1370913678_thumb.jpg

Share this post


Link to post
Share on other sites

Updated firmware.

bit0-2 - color (RGB)

bit3-4 - number of animations (1-4)

bit5 - type (dot or bar)

 

For example, send ASCII a to trigger red dot one time, A for red bar one time, or J for green bar twice.

 

If you ever wanted to make candy cane, icicle, or arch for your xmas show, this will make it a lot easier :smile:

 

Share this post


Link to post
Share on other sites

The bounce time at the end of the strip seems way too quick. It looks like a couple of the leds at the end arn't even being used at all. Don't know if that's a video artifact or not.

Share this post


Link to post
Share on other sites

@@Rubi, here it is (I cannot test it now, but I think this is the one from the video.)

#include <msp430g2553.h>

typedef unsigned char u_char;
typedef unsigned int u_int;
typedef struct {
	u_char r;
	u_char g;
	u_char b;
} RGBLED;

#define DATA_OUT_PIN BIT7
#define UART_RX_PIN BIT1

void sendRGB(u_char numberOfLEDs);

// update with the number of LEDs in your strip
#define NUMBER_OF_LEDS 60

RGBLED leds[NUMBER_OF_LEDS] = { 0, };
u_char rxByte = 0;

void main(void) {

	WDTCTL = WDTPW + WDTHOLD;

	BCSCTL1 = CALBC1_16MHZ;
	DCOCTL = CALDCO_16MHZ;

	// setup USIB, needed for the driver
	P1SEL |= DATA_OUT_PIN;
	P1SEL2 |= DATA_OUT_PIN;
	UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master
	UCB0CTL1 |= UCSSEL_2; // SMCLK
	UCB0BR0 |= 0x03;
	UCB0BR1 = 0;
	UCB0CTL1 &= ~UCSWRST;

	// setup USCIA
	P1SEL |= UART_RX_PIN;
	P1SEL2 |= UART_RX_PIN;
	UCA0CTL1 |= UCSSEL_2;
	UCA0BR0 = 0x82;						// 16MHz 9600
	UCA0BR1 = 0x06;						// 16MHz 9600
	UCA0MCTL = UCBRS_6;
	UCA0CTL1 &= ~UCSWRST;
	IE2 |= UCA0RXIE;

	// animation section

	RGBLED onLED = { 0xFF, 0xFF, 0 }; // default color
	const RGBLED offLED = { 0, 0, 0 };

	u_char repeat = 0;
	//TODO add 3rd type where off moves in the same direction and 4th where dot just goes up but does not return
	//we can either sacrifice number of repetitions, 1-2, or add command: 0x01ttrrzz - set params, 0x00rrggbb - set color and start
	u_char type = 0;
	u_char seq = 0;

	_bis_SR_register(GIE);

	// animation loop
	while (1) {

		// wait for uart change
		if (rxByte == 0) {
			continue;
		} else {
			(rxByte & BIT0) ? (onLED.r = 0xFF) : (onLED.r = 0);
			(rxByte & BIT1) ? (onLED.g = 0xFF) : (onLED.g = 0);
			(rxByte & BIT2) ? (onLED.b = 0xFF) : (onLED.b = 0);
			(rxByte & BIT5) ? (type = 1) : (type = 0);
			repeat = rxByte >> 3;
			repeat &= 0x03;
			repeat++; // 1-4
			rxByte = 0;
		}

		u_char repeatCounter = 0;

		while (repeat != repeatCounter) {
			// animate 1 or x times
			u_char counter = 0;
			u_char direction = 0;

			leds[0] = onLED;
			repeatCounter++;

			while (1) {
				if (direction) {
					counter--;
					leds[counter] = onLED;
					leds[counter + 1] = offLED;
					if (counter == 0) {
						direction = 0;
						break; // leave the loop
					}

				} else {
					counter++;
					leds[counter] = onLED;
					if (type) {
						leds[counter - 1] = offLED;
					}
					if (counter == (NUMBER_OF_LEDS - 1)) {
						direction = 1;
					}
				}

				sendRGB(NUMBER_OF_LEDS); // update LED strip

				_delay_cycles(100000); // delay
			}

			leds[0] = offLED; // cleanup after animation
			sendRGB(NUMBER_OF_LEDS); // update LED strip
		}
		// end of animate
	}

}

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void) {
	rxByte = UCA0RXBUF;
}

// this is driver section, depends on LED strip
void sendRGB(u_char numberOfLEDs) {
	u_int c = 0;
	u_char led = 0;
	u_char all[3];
	u_char d;
	_bic_SR_register(GIE);
	while (c < numberOfLEDs) {
		all[0] = leds[c].g;
		all[1] = leds[c].r;
		all[2] = leds[c].b;
		while (led < 3) {
			u_char b = 0;
			d = all[led];
			while (b < 8) {
				while (!(IFG2 & UCB0TXIFG))
					;
				(d & 0x80) ? (UCB0TXBUF = 0xF0) : (UCB0TXBUF = 0xC0);
				d <<= 1;
				b++;
			}
			led++;
		}
		led = 0;
		c++;
	}
	_bis_SR_register(GIE);
	_delay_cycles(800); // delay 50us to latch data, may not be necessary
}


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×