Introduction: LilyPad Wrist Band POV

Persistence of Vision (POV) is the illusion  that an image continues to persist even though the image has changed.   In essence, we are taking advantage of the limitations of the brain-eye processing time.  With a camera we can tune our eye for a longer exposure.  The Lilypad POV (row of LEDs) is a fun toy to build with minimal programming and electronic needs.

Step 1: Supplies

 You will need:
  1. 8 LEDs (though you can use more or less, probably not less than 6 for a clear image)
  2. Lilypad Arduino 
  3. Lilypad Power Supply 
  4. Conductive thread
  5. Velcro/fastener
  6. Elastic Band

Step 2: Layout of LEDs

Choose 8 LEDs.  I am using the Lilypad Bright White LED (www.sparkfun.com/commerce/product_info.php).  You can use other LEDs but keep in mind the LEDs required forward voltage and current consumption ratings; you may have to include a resistor and/or need additional power.   

I have chosen to use output pins 6-13 and 5 as ground.  (I will explain more in the next step)

Because I am inexperienced with sewing, I first stitched everything down on a piece of fabric to be transfered later to an elastic band 

Step 3: Sewing LEDs

Before sewing make sure the plus side (+) of the LEDs is facing the Lilypad.   Make sure that each LED plus side is not connected or touching anything other than the corresponding pin of the LilyPad. 

We are going to use a fairly common trick.  We know that later we will have to attach a power supply to the LilyPad and it can be difficult to combine thread lines.  Therefore, we can use a little trick by declaring pin 5 as output and setting the pin to low (a fake ground).  In your code, you will write this:

int ground = 5;

void setup() {
   pinMode(ground,OUTPUT);
   digitalWrite(ground,LOW);



Note: while we can set any pin to ground, usually, it is not recommend to set a pin HIGH as another PLUS pin.  LilyPads can only output 40mA from each digital I/O pin.

We can stitch all of the minus sides of the LEDs together and then to pin 5.

After you complete your sewing, plug-in your LilyPad to your computer and use the following code to flash all the lights. 

int ledPin13 = 13; // LED connected to digital pin 13
int ledPin12 = 12; // LED connected to digital pin 12
int ledPin11 = 11; // LED connected to digital pin 11
int ledPin10 = 10; // LED connected to digital pin 10
int ledPin9 = 9; // LED connected to digital pin 9
int ledPin8 = 8; // LED connected to digital pin 8
int ledPin7 = 7; // LED connected to digital pin 7
int ledPin6 = 6; // LED connected to digital pin 6
int ground = 5; // LED connected to digital 5 "ground"

int ledPinArray[8] = {6,7,8,9,10,11,12,13};

void setup() {
// initialize the digital pin as an output:
for(int i = 0; i < 8; i++){
pinMode(ledPinArray[i],OUTPUT);
}
pinMode(ground, OUTPUT);
digitalWrite(ground, LOW);
}

{
for(int i = 0; i < 8; i++){
digitalWrite(ledPinArray[i],HIGH);
}

delay(1000); // wait for a second
for(int i = 0; i < 8; i++){
digitalWrite(ledPinArray[i],LOW);
}
delay(1000); // wait for a second
}

Step 4: Wrist Band Setup

I transfered my fabric with LilyPad and LEDs stitched on to an elastic band.  The band will allow people of different arm width to use the toy.

 I am using the lilypad power supply (www.sparkfun.com/commerce/product_info.php).  This device uses a AAA battery and has 3 minus holes and 1 plus hole.  Stitch Minus on the Power Supply to Minus on the LilyPad and Plus on the Power Supply to Plus on the Lilypad.  

Choose a fastener.  I chose velcro because it's easy to sew down and you can adjust for arm width

Step 5:

 Turn on your Power Supply and make sure all the lights are flashing.

Step 6: Source Code Part 1

POV works by blinking a specified set of LEDs, waiting a second, and then blinking another set of specified LEDs.  See Image Below.  Between each column we want to delay 2.5 milliseconds (ms).  To form the letter P, for the first 2.5ms nothing is on.  The next 2.5ms all the LEDs are on. The next 2.5 ms only LEDs 6 and 9 are on....).  In our code we save this letter in the following manner:

int P[] = {
1,1,1,1,1,1,1,1,
0,0,0,0,1,0,0,1,
0,0,0,0,1,0,0,1,
0,0,0,0,1,0,0,1,
0,0,0,0,1,1,1,0,
0,0,0,0,0,0,0,0};

I used this nifty website to help me figure out which pins I needed to turn on (www.repulsor.net/minipov/)

Alternatively, we can write out the entire word (to see the letters turn your screen on its side):
int lilypad[] = {
1,1,1,1,1,1,1,1, //L
1,0,0,0,0,0,0,0,
1,0,0,0,0,0,0,0,
1,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,

1,1,1,1,0,1,0,0, //i
0,0,0,0,0,0,0,0,

1,1,1,1,1,1,1,1, //l
0,0,0,0,0,0,0,0,

1,0,0,0,0,1,1,0, //y
0,1,0,0,1,0,0,0,
0,0,1,1,0,0,0,0,
0,0,0,1,1,1,1,0,
0,0,0,0,0,0,0,0,

1,1,1,1,1,1,1,1, //p
0,0,0,0,1,0,0,1,
0,0,0,0,1,0,0,1,
0,0,0,0,0,1,1,1,
0,0,0,0,0,0,0,0,

1,1,1,1,0,0,0,0, //a
1,0,0,1,0,0,0,0,
1,0,0,1,1,0,0,0,
1,1,1,1,1,0,0,0,
0,0,0,0,0,0,0,0,

1,1,1,1,0,0,0,0, //d
1,0,0,1,0,0,0,0,
0,0,0,1,0,0,0,0,
1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0};



Step 7: Source Code Part 2

The Entire Code


#define NUM_ELEM(x) (sizeof (x) / sizeof (*(x)))

int lilypad[] = {
1,1,1,1,1,1,1,1, //L
1,0,0,0,0,0,0,0,
1,0,0,0,0,0,0,0,
1,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,

1,1,1,1,0,1,0,0, //i
0,0,0,0,0,0,0,0,

1,1,1,1,1,1,1,1, //l
0,0,0,0,0,0,0,0,

1,0,0,0,0,1,1,0, //y
0,1,0,0,1,0,0,0,
0,0,1,1,0,0,0,0,
0,0,0,1,1,1,1,0,
0,0,0,0,0,0,0,0,

1,1,1,1,1,1,1,1, //p
0,0,0,0,1,0,0,1,
0,0,0,0,1,0,0,1,
0,0,0,0,0,1,1,1,
0,0,0,0,0,0,0,0,

1,1,1,1,0,0,0,0, //a
1,0,0,1,0,0,0,0,
1,0,0,1,1,0,0,0,
1,1,1,1,1,0,0,0,
0,0,0,0,0,0,0,0,

1,1,1,1,0,0,0,0, //d
1,0,0,1,0,0,0,0,
0,0,0,1,0,0,0,0,
1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0};


int ledPin13 = 13; // LED connected to digital pin 13
int ledPin12 = 12; // LED connected to digital pin 13
int ledPin11 = 11; // LED connected to digital pin 13
int ledPin10 = 10; // LED connected to digital pin 13
int ledPin9 = 9; // LED connected to digital pin 13
int ledPin8 = 8; // LED connected to digital pin 13
int ledPin7 = 7; // LED connected to digital pin 13
int ledPin6 = 6; // LED connected to digital pin 13
int ground = 5; // LED connected to digital 5 "ground"

int ledPinArray[8] = {6,7,8,9,10,11,12,13};
// The setup() method runs once, when the sketch starts

int columnDelay;
int sizeWord = 0;
void setup() {
// initialize the digital pin as an output:
for(int i = 0; i < 8; i++){
pinMode(ledPinArray[i],OUTPUT);
}
pinMode(ground, OUTPUT);
digitalWrite(ground, LOW);

columnDelay = 2.5; //wait 2.5ms between each column flash
Serial.begin(9600);
Serial.print("Number of lilypad: ");
Serial.println(NUM_ELEM(lilypad));
delay(2000);
sizeWord = NUM_ELEM(lilypad);
}

// the loop() method runs over and over again,
// as long as the Arduino has power

/*void loop()
{
for(int i = 0; i < 8; i++){
digitalWrite(ledPinArray[i],HIGH);
}

delay(1000); // wait for a second
for(int i = 0; i < 8; i++){
digitalWrite(ledPinArray[i],LOW);
}
delay(1000); // wait for a second
}*/

void loop()
{
//Serial.print("Number of lilypad: ");
//Serial.println(NUM_ELEM(lilypad));
//delay(1000);
printWord(lilypad);
delay(8); //wait a little bit between each display of the word LilyPad
}

void printWord(int wordVar[]) {

int numRows = sizeWord/8;
for(int j = 0; j < numRows; j++) {
for(int i = 0; i<8; i++) {
digitalWrite(i+6, wordVar[i+j*8]);
}
delay(columnDelay);
}

Step 8: Take Pictures!

 Now all you have to do is wave your arms about and take a picture!

This material is based upon work supported by the National Science Foundation under Grant No. 0855886 to Kylie Peppler. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.