Saturday, February 19, 2011

LED Visor, MSP430 (Final Build into Visor)

This post is the fourth in a multi-post set: 

After working out the bugs in my software and PCB, I build the PCB into a visor.

I mounted the switched on the back of my PCB. You can see them sticking out of the left side of the visor below. The top switch changes the speed that the pattern is run with, and the bottom switch changes to a new pattern.
The PCB was mounted in the headband, along with a 9V battery.  The regulator can run from about 3.5V up to 18V, so switching from a 6V system (4 x 1.5V AA) to a 9V was not a problem.

 As you can see here, my sewing leaves a lot to be desired. I also ended up using hot glue to attached a 100uF Cap when I ran out of the correct package size ones I'd designed with.
 This was before I'd discovered conductive thread, so I wired up the LEDs individually with a stiff thin wire.  I then sewed the wire back to the visor to keep it from moving around.


Thanks for looking!

Saturday, February 12, 2011

LED Visor, MSP430 (Software)

This post is the third in a multi-post set: 

For this project I decided to use the Free version of Code Composer Studio, provided by TI. I have been working with version 4.1.

CCS provides a nice Eclipse based editor with a integrated complier and debugger. It installed without issues on my windows 7 64 bit machine.

I broke my software up into several pieces:
  • Main: The section which pulls everything together.
  • Standard.h: A section for constants, macros, typdefs, etc. which are shared across the entire project.
  • Button driver : This code de-bounces button presses, and sends back button press and button released events.
  • Led Driver: This is really a serial driver. It sends out data to the CAT4008 LED driver device.
  • Led Patterns: Code which generates different patterns for the LED. Some patterns are hard coded, and others are functions.
In order to save power, I designed the software to only drive 1 LED at a time. In order to make it look like more then 1 LED is on at a time, we use persistence of vision.

The software can be downloaded from a google code repository found here. The Source file are:
  • Main.c
  • Standard.h
  • buttons.h
  • buttons.c
  • LedDriver.h
  • LedDriver.c
  • LedPattern.h
  • LedPattern.c
The other files are the Code Composer Studio project files.

When running, the code :
  • scans for button presses
    • If SW2 is pressed, the code will change the pattern being run.
    • If SW1 is pressed, the speed at which the code is run is changed.
  • One the LED pattern is determined, it is clocked out to the LED driver.
  • The MSP430 goes into a sleep mode until the next clock interrupt starts the cycle again.

Wednesday, February 9, 2011

LED Visor, MSP430 (Schematic Capture, Layout)

This post is the second in a multi-post set: 

Having decided on a schematic, I then went ahead and installed KiCad. While it's outside the scope of this write up, I needed to create a few custom parts in order to get this to work. If you want to do this, I'd suggest following the write up on the CuriousInventor.com found  here.

I had now gone from this:

To This:

Parts List is as follows (with links to digitkey):
With Schematic capture complete, I moved onto layout. I wanted to try and keep my PCB small, so it would fit in a hat, tie or visor. I decided on about 2 inches by 1.5 inches.

The layout took me about two days, though a good part of that time was getting used to the tool. I had used professional layout software before, so the process was familiar. 
One of the cool features of KiCad is the ability to render a PCB in 3D. In order to do this, I had to install Wings3D.

The last step was packaging up the data for BatchPCB. I found some info in the sparkFun form, which I used to setup my own file.

My settings were as follows:
  • Drill Units: Inches
  • Decimal Format: Suppress Leading Zeros
  • Precision: 2:4      
  • Drill Origin: Absolute
  • Drill Sheet: None
  • Drill Report: None
  • HPGL Plotter Options: 20cm/s - Pen Number 1
  • Mirror Y Access: Unchecked
  • Minimal Header: Checked
I then created the collection of files need (copper layer top, copper layer bottom, silkscreen top, mask top, mask bottom, components) as documented by batchPCB and uploaded them.

In a few hours, I got an e-mail back that I'd passes the automated test, and I ordered 3 PCBs. 16 days later I received my PCBs!

Sunday, February 6, 2011

LED Visor, MSP430 (Concept)

This post is the first in a multi-post set: 

This project actually came before the LED jacket. It also was an experiment to try and see what the process would be like to work with the MSP430 development system at home. I've developed several professional products for the MSP430, but all of them used big expensive compilers with the pcb layout done by our layout team.

Design

 First off, I decided I wanted to put some LEDs on a hat or visor. This made for a nice, trivial project.

I had a ez430-F2013 which I'd picked up from work . It wasn't quite what we needed at work, however it was just fine for a small home project. If your interested, you can pick one up from digikey for about $20.
ez430-F2013 Programmer & dev board.
I also was interested in trying out two new tools.
  • One was a PCB EDA tool, KiCad. While I know that a lot of folks like Eagle,  I wanted something that was open source. After looking at gEDA, I decided I would rater use something a little more integrated.
  • I wanted to try out BatchPCB, a service which fabricates custom circuit boards. While the wait times can be long, the price was right. I wanted to see if I could take a circuit idea from schematic capture, to layout, to reality. 
For my PCB I need to :
  • Provide a power source (e.g. power regulation)
  • Provide a circuit for driving the LEDs.
  • Provide a way to connect up the ez430 development board.
  • Provide a way to control the LEDs.
After some browsing around on digikey, I found the CAT4008 LED driver. It was a nice, low cost, simple to use LED driver so I picked it.

The TI MSP430F2013 can run from 1.8V to 3.6V. For this project, I decided I wanted a 3.5V regulator. After some looking, I picked a small 3.5V 600mA regulator.

I drew up a circuit by hand in my lab notebook, using the reference information in the datasheets for parts I'd selected.
Notebook pre-plan for circuit.

Next: PCB Schematic Capture and Layout.

Saturday, January 22, 2011

Arduino Lilypad - 5x8 LED Jacket (Conclusion and thoughs)

This is the third post in a 3 post set:
Arduino Lilypad - 5x8 LED Jacket (Design and Construction)
Arduino Lilypad - 5x8 LED Jacket (Software)
Arduino Lilypad - 5x8 LED Jacket (Conclusion and thoughts)

As you can probably see from the pictures, the final jacket isn't quiet what I had drawn out. In the process working on this project I learned several things:
  1. Don't mix LED colors if you want readable text. While it isn't too bad in the video, the text would have been MUCH easier to read if it wasn't swapping between blue and white a lot.
  2. 5 Bits high isn't quite enough for a nice readable font. I would try at least 6 next time, maybe 7.
  3. Conductive thread is hard to work with, or, at least the 4-ply stuff that I have is. I didn't leave enough spacing between some of the wires, and I didn't think about whether I wanted the thread on the top or the bottom of the fabric when I started. By keeping my rows on the bottom, and my columns on the top I could have gotten a better layout.
  4. Don't over commit on the first project. I decided to drop the tri-color LED and switches after I saw how difficult it is to read the text. I'd rather have the parts for the next project then attach them to this project.
  5. Finding the right needle size is hard. The larger needled, which were easy to thread kept breaking when put though the holes on the Arduino board (the eye of the needle would snap off). 
  6. The display driver code should be moved off to a interrupt handler linked to a timer, rather then being run from a super-loop in the main code.
Summary:
  • Build Time: about 3 weeks (2 weekends, and several 1 to 2 hour stints on week nights).
  • Cost: about $90 total.
    • $10.00 jacket
    • $21.95 for Controller
    • $14.95 for power supply
    • $15.00 20 White LED ($0.75 * 20 = $15.00)
    • $19.80 20 Blue LED ($19.80)
    • $4 Conductive Thread ( about 30 ft from a 225 ft spool. Spool cost $30)
    • $2 Misc (needles, puff paint, etc).

Thursday, January 20, 2011

Arduino Lilypad - 5x8 LED Jacket (Software)

This is the second post in a 3 post set:
Arduino Lilypad - 5x8 LED Jacket (Design and Construction)
Arduino Lilypad - 5x8 LED Jacket (Software)
Arduino Lilypad - 5x8 LED Jacket (Conclusion and thoughts)

The software for this project uses the Arduino development environment, Arduino Alpha. For my project, I was using version 0021.

The software has very few responsibilities at this point. All it has to do is drive the LEDs to match a pattern. It also has to shift which LEDs are driven, as it can only drive a single row at a time (due to the matrix layout), and on a row, only 3 LEDs can be on at one time. This is because each LED takes about 17 mA of current. The maximum current rating of my power supply is 100 mA. 3 LED * 17 mA = 51 mA. This left about 50 mA for the processor at design time.

To do this, the code has a small state machine ( the function called updateDisplayState() ). Each time this state machine is called the code move onto a new block of LEDs. So the first time the function is called LEDS in position 1 in the block below are illuminated. When the function is called again, the LEDs in block 2 are called, and so on until block F. After block F, the code cycles back to block 1.

DDDEEEFF
AAABBBCC
77788899
44455566
11122233

The function updateDisplayState() used a buffer of bytes to represent the display. Each byte is one column, where BIT0 is the bottom LED, and BIT4 is the top LED. So a 8 byte buffer can be used to show 8 columns of LEDs. In order to get the text to shift, I just move the pointer in the buffer over occasionally. This creates the illusion of the text characters moving across the screen.

The code for the Arduion, as well as the Python 3.1 scrip used to generate the text byte sequence is below.

I'll do a final post on lessons learned, and thoughs for next time later.

Arduino Code:
/*

LedJacket

This code Drives a 5x8 LED display sewen onto a jacket.

*/
// ----------------------------------------------------------------------------------
// HW Settings for LED Display
// ----------------------------------------------------------------------------------
const char ROW_SIZE = 5;
const char COLUMN_SIZE = 8;

// Pull to 5V to illuminate LED
const char RowPins[ROW_SIZE] = {4,3,2,19,18};
// Pull to GND to illumiate LED
const char ColumnPins[COLUMN_SIZE] = {17,16,15,14,13,12,11,10};

// ----------------------------------------------------------------------------------
// Display Buffer
// ----------------------------------------------------------------------------------
// Converted Text Block of " TEAM 3662, SNOW BYTE "
const unsigned char TXT_SNOW_BYTE_SIZE = 95;
static unsigned char TxtSnowByte[TXT_SNOW_BYTE_SIZE] = {0,0,0,0,0,0,0,0,16,31,16,0,31,21,21,0,15,20,15,0,15,16,15,16,15,0,0,0,21,21,31,0,31,21,23,0,31,21,23,0,23,21,29,0,1,3,2,0,0,0,9,21,18,0,31,8,4,31,0,14,17,14,0,30,1,30,1,30,0,0,0,31,21,10,0,24,7,24,0,16,31,16,0,31,21,21,0,0,0,0,0,0,0,0,0};

// Show all Blue LED.
const unsigned char TxtBlue[8] = {0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55};

// Show all White LED.
const unsigned char TxtWhite[8] = {0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA};

// ----------------------------------------------------------------------------------
// Display Timing Constants
// ----------------------------------------------------------------------------------
// USEC_WAIT_BETWEEN_MULTIPLEXING multiplied by DISPLAY_UPDATE_COUNT give
// the time between when the text scroll to the next number...
// Right now it is about 1500 * 600 = 900000 uSec, or 0.9 Seconds.
static const unsigned int DISPLAY_UPDATE_COUNT = 500;
static const unsigned int USEC_WAIT_BETWEEN_MULTIPLEXING = 850;

// ----------------------------------------------------------------------------------
// Run once setup hook.
// ----------------------------------------------------------------------------------
void setup() {
LedArray_initHw();
}

// ----------------------------------------------------------------------------------
// Main Function loop.
// ----------------------------------------------------------------------------------
void loop() {

// Loop though a buffer which is bigger then our little 5x8 display, scroll across it.
for(unsigned char index =0; index < (TXT_SNOW_BYTE_SIZE - COLUMN_SIZE); index++)
{
// Show this buffered output for about 350 miliseconds. 
for(unsigned int i =0 ; i < DISPLAY_UPDATE_COUNT ; i++)
{
updateDisplayState(&TxtSnowByte[index]);
delayMicroseconds(USEC_WAIT_BETWEEN_MULTIPLEXING);
}
}

// Cycle between Blue and White LED
for(unsigned char index = 0; index < 10; index++)
{
// Point to either the Blue or White LED buffer
const unsigned char* showData = 0;
(index & 0x01) ? showData = TxtBlue : showData = TxtWhite;

// Show the buffer
for(unsigned int i =0 ; i < DISPLAY_UPDATE_COUNT ; i++)
{
updateDisplayState(showData);
delayMicroseconds(USEC_WAIT_BETWEEN_MULTIPLEXING);
}
}
}

//------------------------------------------------------------------------
// Clears all the items on the LED Display.
// This function ensure that the hardware is properly configured to
// be used with the LED array. It also revers biases the Diodes to
// ensure they are off.
//
// NOTE: origionally I had made the unused lines high-impedence inputs
// however, I had issues with leakeages on the jacket, possibly
// due to the conductive thread. I found that driving the lines
// provided a much better result - Thomas (Jan 15th, 2011)
void LedArray_initHw(void) {


// Ensure each Column Line is set to HW, and driven High
for( char i = 0; i < COLUMN_SIZE; i++)
{
// Set to input, and write to LOW to disable pull up Resistor.
pinMode(ColumnPins[i], OUTPUT);
digitalWrite(ColumnPins[i],HIGH);
}

// Ensure each Row line is set to HW and driven Low
for( char i = 0; i < ROW_SIZE; i++)
{
// Set to input, and write to LOW to disable pull up Resistor.
pinMode(RowPins[i],OUTPUT);
digitalWrite(RowPins[i],LOW);
}
}

//------------------------------------------------------------------------
// Sets the next set of display bits.
//
// This function impliment a simple state machine which ensure that only
// 3 LEDs can be turned on at one time. This is to limit the current used
// by the system. Each LED which is turn on takes about 16 - 18 mA of 
// current. The AAA based power supply maxes out at about 100 mA. with 3 LED on
// we pull about 55 - 60 mA. This leaves a safty margine, as well as space for the
// power consumed by the Arduino.
//
// The state machine drives on Row at a time, turning on up to 3 LEDs.
void updateDisplayState(const unsigned char* bufferHead)
{
static unsigned char lastActiveRow = 0;
static unsigned char lastBitMask = 0;
static unsigned char stateIndex = 0;

switch (stateIndex)
{
case 0:
// Reset HW.
digitalWrite(ColumnPins[6],HIGH);
digitalWrite(ColumnPins[7],HIGH);
digitalWrite(RowPins[lastActiveRow],LOW);
lastActiveRow++;
if (lastActiveRow > ROW_SIZE) lastActiveRow =0;
lastBitMask = 1 << lastActiveRow;

// Write out new bits.
digitalWrite(RowPins[lastActiveRow],HIGH);
digitalWrite(ColumnPins[0], (bufferHead[0] & lastBitMask ) ? LOW : HIGH);
digitalWrite(ColumnPins[1], (bufferHead[1] & lastBitMask ) ? LOW : HIGH);
digitalWrite(ColumnPins[2], (bufferHead[2] & lastBitMask ) ? LOW : HIGH);
break;
case 1:
// Reset HW.
digitalWrite(ColumnPins[0],HIGH);
digitalWrite(ColumnPins[1],HIGH);
digitalWrite(ColumnPins[2],HIGH);

// Write out new bits.
digitalWrite(ColumnPins[3], (bufferHead[3] & lastBitMask ) ? LOW : HIGH);
digitalWrite(ColumnPins[4], (bufferHead[4] & lastBitMask ) ? LOW : HIGH);
digitalWrite(ColumnPins[5], (bufferHead[5] & lastBitMask ) ? LOW : HIGH);
break;
case 2:
// Reset HW.
digitalWrite(ColumnPins[3],HIGH);
digitalWrite(ColumnPins[4],HIGH);
digitalWrite(ColumnPins[5],HIGH);

// Write out new bits.
digitalWrite(ColumnPins[6], (bufferHead[6] & lastBitMask ) ? LOW : HIGH);
digitalWrite(ColumnPins[7], (bufferHead[7] & lastBitMask ) ? LOW : HIGH);
break;
}

// Step to the next state.
stateIndex++;
if ( stateIndex > 2) stateIndex = 0;
}

In order to generate the text string above (see the constant TxtSnowByte[] and TXT_SNOW_BYTE_SIZE) I used a small python scrip to generate the byte string.

##
## Translator for a 5 bit tall font.
##
## By: Thomas Anderson
## Last Updated: Jan 15th, 2011

## Font Dictionary data
# This dictionary assumes the following:
# * All Letters will be capital
# * Each letter will be represented by a series of bytes.
# * The bytes will be decodes, so that: 
#   - Bit0 represents the lowest pixel on a 5 bit Row.
#   - Bit4 represent the top pixel on a 5 bit Row.
# * An end user will want both a string of raw data (bytes), and the number of bytes in the string.
# * Values in the 'bytes' section are in base 10, not in hex.
# * Values in the 'bytes' section are assumed to be used as unsigned 8-bit integers.
#
# New letters/characters can be added to this dictionary simply by defining a new entry.
fontDict = {
    'A' :
    {
        'bytes' : "15,20,15,0",
        'size'  : 4,
    },
    'B' :
    {
        'bytes' : "31,21,10,0",
        'size'  : 4,
    },
    'C' :
    {
        'bytes' : "14,17,17,0",
        'size'  : 4,
    },
    'D' :
    {
        'bytes' : "31,17,14,0",
        'size'  : 4,
    },
    'E' :
    {
        'bytes' : "31,21,21,0",
        'size'  : 4,
    },
    'F' :
    {
        'bytes' : "31,20,20,0",
        'size'  : 4,
    },
    'G' :
    {
        'bytes' : "31,17,21,6,0",
        'size'  : 5,
    },
    'H' :
    {
        'bytes' : "31,4,31,0",
        'size'  : 4,
    },
    'I' :
    {
        'bytes' : "17,31,17,0",
        'size'  : 4,
    },
    'J' :
    {
        'bytes' : "2,17,31,16,0",
        'size'  : 5,
    },
    'K' :
    {
        'bytes' : "31,4,27,0",
        'size'  : 4,
    },
    'L' :
    {
        'bytes' : "31,1,1,0",
        'size'  : 4,
    },
    'M' :
    {
        'bytes' : "15,16,15,16,15,0",
        'size'  : 6,
    },
    'N' :
    {
        'bytes' : "31,8,4,31,0",
        'size'  : 5,
    },
    'O' :
    {
        'bytes' : "14,17,14,0",
        'size'  : 4,
    },
    'P' :
    {
        'bytes' : "31,20,28,0",
        'size'  : 4,
    },
    'Q' :
    {
        'bytes' : "14,17,18,13,0",
        'size'  : 5,
    },
    'R' :
    {
        'bytes' : "31,20,11,0",
        'size'  : 4,
    },
    'S' :
    {
        'bytes' : "9,21,18,0",
        'size'  : 4,
    },
    'T' :
    {
        'bytes' : "16,31,16,0",
        'size'  : 4,
    },
    'U' :
    {
        'bytes' : "31,1,31,0",
        'size'  : 4,
    },
    'V' :
    {
        'bytes' : "30,1,30,0",
        'size'  : 4,
    },
    'W' :
    {
        'bytes' : "30,1,30,1,30,0",
        'size'  : 6,
    },
    'X' :
    {
        'bytes' : "27,4,27,0",
        'size'  : 4,
    },
    'Y' :
    {
        'bytes' : "24,7,24,0",
        'size'  : 4,
    },
    'Z' :
    {
        'bytes' : "19,21,25,0",
        'size'  : 4,
    },
    '0' :
    {
        'bytes' : "31,17,31,0",
        'size'  : 4,
    },
    '1' :
    {
        'bytes' : "9,31,1,0",
        'size'  : 4,
    },
    '2' :
    {
        'bytes' : "23,21,29,0",
        'size'  : 4,
    },
    '3' :
    {
        'bytes' : "21,21,31,0",
        'size'  : 4,
    },
    '4' :
    {
        'bytes' : "28,4,31,0",
        'size'  : 4,
    },
    '5' :
    {
        'bytes' : "29,21,23,0",
        'size'  : 4,
    },
    '6' :
    {
        'bytes' : "31,21,23,0",
        'size'  : 4,
    },
    '7' :
    {
        'bytes' : "16,16,31,0",
        'size'  : 4,
    },
    '8' :
    {
        'bytes' : "31,21,31,0",
        'size'  : 4,
    },
    '9' :
    {
        'bytes' : "29,21,31,0",
        'size'  : 4,
    },
    ' ' :
    {
        'bytes' : "0,0",
        'size'  : 2,
    },
    ',' :
    {
        'bytes' : "1,3,2,0",
        'size'  : 4,
    },
}

# This function uses the above dictionary to create an Array of bytes
#  which represent the text message for a 5 Row LED display.
def convertTextToArray(stringToConvert):
    
    sizeInBytes = 0
    outString = ""
    
    for letter in stringToConvert:
        if letter in fontDict:
            sizeInBytes += fontDict[letter]['size']
            outString += fontDict[letter]['bytes'] + "," 
        else :
            print("Item ",letter, " not in Dictionary")    
    
    # Display the results
    print("Text          = ",stringToConvert)
    print("Size In bytes = ",sizeInBytes)
    print("Byte String   = ",outString)

# Use the function above to print out the following messages
convertTextToArray("    TEAM 3662, SNOW BYTE    ")
convertTextToArray("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1234567890  ")

When run, this generates:
Text          =      TEAM 3662, SNOW BYTE    
Size In bytes =  95
Byte String   =  0,0,0,0,0,0,0,0,16,31,16,0,31,21,21,0,15,20,15,0,15,16,15,16,15,0,0,0,21,21,31,0,31,21,23,0,31,21,23,0,23,21,29,0,1,3,2,0,0,0,9,21,18,0,31,8,4,31,0,14,17,14,0,30,1,30,1,30,0,0,0,31,21,10,0,24,7,24,0,16,31,16,0,31,21,21,0,0,0,0,0,0,0,0,0,
Text          =  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1234567890  
Size In bytes =  208
Byte String   =  15,20,15,0,0,0,31,21,10,0,0,0,14,17,17,0,0,0,31,17,14,0,0,0,31,21,21,0,0,0,31,20,20,0,0,0,31,17,21,6,0,0,0,31,4,31,0,0,0,17,31,17,0,0,0,2,17,31,16,0,0,0,31,4,27,0,0,0,31,1,1,0,0,0,15,16,15,16,15,0,0,0,31,8,4,31,0,0,0,14,17,14,0,0,0,31,20,28,0,0,0,14,17,18,13,0,0,0,31,20,11,0,0,0,9,21,18,0,0,0,16,31,16,0,0,0,31,1,31,0,0,0,30,1,30,0,0,0,30,1,30,1,30,0,0,0,27,4,27,0,0,0,24,7,24,0,0,0,19,21,25,0,0,0,9,31,1,0,23,21,29,0,21,21,31,0,28,4,31,0,29,21,23,0,31,21,23,0,16,16,31,0,31,21,31,0,29,21,31,0,31,17,31,0,0,0,0,0,

Wednesday, January 19, 2011

Arduino Lilypad - 5x8 LED Jacket (Design and Construction).

LED Jacket with 5x8 array
This post is the first in a 3-post set:  
Arduino Lilypad - 5x8 LED Jacket (Design and Construction)
Arduino Lilypad - 5x8 LED Jacket (Software) 
Arduino Lilypad - 5x8 LED Jacket (Conclusion and thoughts)

This was a concept project.

I work with a First Robotics Team (Team 3662, SnowByte!) as a mentor. Unfortunately, there are usually more kids interested in programming then can really get their hands dirty on the robot.

This project was an experiment in getting some more programming work drummed up that could be done at a high school level (with some mentoring). The idea is that the kids can build stuff they can wear to the FIRST competition, AND practice their programming.

I decided to try my hand at sewable circuit. The idea is to put an LED array on a jacket, and drive it with mininal parts and complexity.





Research:
While looking for ideas, I pulled heavily from:
There are also quite a few other wearable DIY projects on youTube and Make that had good ideas.

Design:

  I knew I wanted the following:
  • Low cost
  • Low part count
  • Quick to make.
  • Interesting to program.
In order to achieve this, I decided that I would directly drive a LED array from the Arduino pins. According to the documentation, a pin could sink up to 40 mA, but could source more. Because of that, I planned to drive a line of LEDs, and then pull down the ones I wanted to light up.

Looking at the Arduino Lilypad I found that there are 12 usable Digital I/O lines, and 6 Analog lines, which could also be used in a digital mode. This allowed for 18 pins in my project. I wanted to have two push buttons, and one tri-color LED. Each push button took 1 pin, and a tri-color LED took 3 pins. So, I now had (18 - 1 -1 -3 = 13 ) pins remaining.  figuring that 5 bits was enough vertically for an array, I was then left with 8 lines for columns on my array.

Since I had a 5 x 8 pin grid, I needed 40 LEDs. I now had a basic parts list.

Construction:
I ordered most of my parts from SparkFun.
All-in-all, this order can to about $140 (with shipping, handling, tax, etc ). I bought extra LEDs in case I had any issues with them.

I Still needed a few things though.
 I also used a few around the house items:
  • Scissors
  • Xacto knife (for cutting out the sewing that I messed up)
  • Chalk
  • Ruler
Then I drew out my design in order to make sure that:
  • My Lines crossed as little as possible
  • I could wire up my Tri-color LED to 3 PWM lines.
 I ended up mounting my Arduino lilypad on the back side of the jacket in order to get things to line up correctly. I setup my system so that
  • pins A4, A5, 2, 3, 4 were the Row pins connected to the + side of the LEDs. 
  • Pins A3,A2,A1,A0,13,12,11,10 were my column pins, and connected to the - side of the LEDS. 
  •  Pins 5,6 and 9 are PWM pins, and are connected to the tri-color LED.
  • Pins 7 and 8 are connected to the switches.
The LEDs from Spark fun came with a 100 Ohm resistor already in series, so I didn't need any extra line resistance.

I then drew out an outline of the Arduino on the jacket with chalk, and using the ruler drew the lines where I wanted to sew. ( Forgot to take pictures, sorry :) ).

Over the next two weeks I sewed the LEDs on. In the process, I learned that I suck at sewing. I also wrote a very simple program that turned one LED on at a time, and switch which LEDs was being driven every 1 1/2 seconds. This allowed me to test out the sewing job as soon as I had my first column of LEDs attached.
Arduino Lilypad inside jacket pocket.

Once I had a column of LEDs sewn on and working, I covered the conductive thread with puff paint and let if dry over night. Before I started doing that I had a lot of trouble with lines shorting each other out. 
LED Array (with my poor sewing and puff paint covering the stitching)


I'll cover the software in the next post, however, here's a video of the text scrolling in action.