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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...