Friday, December 16, 2011

Arduino Lilypad CyberHat

Arduino Lilypad CyberHat

last updated: dec, 18, 2011


Arduino LilyPad is a special version of Arduino, designed by Leah Buechley at MIT Media Lab. It is specifically designed for integration in clothes and garments. With a special conductive thread, you can sew it on your jacket, and it is easy to program it with the same Arduino IDE we use for the standard Arduino boards.
Check Leah's great LilyPad tutorial which is a great introduction to this wonderful device.





I bought an Arduino LilyPad Simple board kit (LilyPad Beginner's kit), online from british shop SkPang: http://www.skpang.co.uk/catalog/lilypad-beginners-kit-p-967.html I bought again (using paypal account) from this shop and I got good service and fast delivery.

This kit includes a simple version of the Lilypad(*), a lithium LiPO 1 cell 3.7V battery, 5 leds, a multicolored led, a loudspeaker, a vibration button, a light sensor, a temperature sensor, and two spools of conductive thread, along with needles. There is also the small "FTDI basic" board that allows to connect to pc USB via a cable (not included): I use a Nokia DKE-2 phone cable, the same to talk with other arduinos equipped with "USB2Serial light".

(*) This simple Lilypad version differs from the standard one, because has less "petals" (9 available I/Os). But it has a plug for the included 1 cell 3.7V LiPO battery, and the recharging circuit to recharge it from the USB connector. I think these features are not available in the standard LilyPad, which requires an external power supply and is powered via conductive threads.
Arduino LilyPad should not be powered with more than 5Vdc.

-

In the winter, I am using a cap that I bought in Riga, Latvia. It is made of wool felt. It is a perfect fit for a first project for electronic integration with cloth.

Here are some pictures of the hat:


Here is how it looks on the inside. The battery is kept in place with a little bit of Patafix.


And this is a particular image of a led. It is quite small. Connecting threads are invisible from the outside.



And here is a detail view of the inside. I had to use some thermal glue to have the components stick well on the cloth material. The small circle on top is the speaker, while the one on the bottom right is the multicolored led.




The board, being inside just sits on top of my head when I am wearing the cap. It is completely invisible from the outside, and also the leds are very small and fit nicely in the felt. You would not say this hat has anything unusual until I turn it on. :-)



Code is very simple. I just prepared a set of routines for some light effects on the 5 blue leds, a small tune (shamelessly copied from arduino sample code library), and some random flickering of the multicolored led.

Enjoy!!!!!

------------
/* 
ledcap lilypad
Marco Guardigli
I dressed a winter cap with an arduino lilipad
mgua@tomware.it
this code is GPL. see www.gnu.org


*/

#include 

#define LEDFC  10      // front center
#define LEDFR  11      // front right
#define LEDFL  9       // front left
#define LEDBR  19      // back right
#define LEDBL  6       // back left
#define MCLR   16       // multicolor led: Blue (when low)
#define MCLB   17       // multicolor led: red (when low)
#define MCLG   18       // multicolor led: green (when low)
#define SPK    5        // speaker  


int melody[] = { NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4 };
int noteDurations[] = { 4,8,8,4,4,4,4,4 }; // note durations: 4 = quarter note, 8 = eighth note, etc.:



void sing() {
  Serial.println("sing");  
  for (int thisNote = 0; thisNote < 8; thisNote++) {
    // to calculate the note duration, take one second divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000/noteDurations[thisNote];
    tone(SPK, melody[thisNote],noteDuration);
    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    // stop the tone playing:
    noTone(SPK);
  }
}


void setup() {
  Serial.begin(9600);
  Serial.println("Init");
  pinMode(LEDFC, OUTPUT);
  pinMode(LEDFR, OUTPUT); 
  pinMode(LEDFL, OUTPUT); 
  pinMode(LEDBR, OUTPUT); 
  pinMode(LEDBL, OUTPUT); 
  pinMode(MCLR, OUTPUT); 
  pinMode(MCLG, OUTPUT); 
  pinMode(MCLB, OUTPUT); 
  pinMode(SPK,  OUTPUT);
  digitalWrite(LEDFC,LOW);
  digitalWrite(LEDFR,LOW);
  digitalWrite(LEDFL,LOW);  
  digitalWrite(LEDBR,LOW);
  digitalWrite(LEDBL,LOW);
  digitalWrite(MCLR,HIGH);  // multicolor led is off when the inputs are all high
  digitalWrite(MCLG,HIGH);  
  digitalWrite(MCLB,HIGH);
  digitalWrite(SPK,LOW);
  delay(1000);
  sing();
}

// RGB
// LLL purple
// HLL orange
// LHL deeppurple
// LLH light blue
// LHH blue
// HHL red
// HLH green
// HHH off


void rainbow() {
  Serial.println("rainbow");
  for (int i=1; i < random(100); i++) {
    if (random(100)>50) { digitalWrite(MCLR,LOW); } else { digitalWrite(MCLR,HIGH); }
    if (random(100)>50) { digitalWrite(MCLG,LOW); } else { digitalWrite(MCLG,HIGH); }    
    if (random(100)>50) { digitalWrite(MCLB,LOW); } else { digitalWrite(MCLB,HIGH); }
    delay(50);
    digitalWrite(MCLR,HIGH);
    digitalWrite(MCLG,HIGH);
    digitalWrite(MCLB,HIGH);
    delay(50);
  }
}

void allblink() {
  Serial.println("allblink");
  for (int i=1; i < random(100); i++) {
    digitalWrite(LEDFC,HIGH);
    digitalWrite(LEDFR,HIGH);
    digitalWrite(LEDFL,HIGH);  
    digitalWrite(LEDBR,HIGH);
    digitalWrite(LEDBL,HIGH);
    delay(random(100));
    digitalWrite(LEDFC,LOW);
    digitalWrite(LEDFR,LOW);
    digitalWrite(LEDFL,LOW);  
    digitalWrite(LEDBR,LOW);
    digitalWrite(LEDBL,LOW);
    delay(random(100));
  }   
}


void randomblink() {
  Serial.println("randomblink");  
  int lev = random(100);
  for (int i=1; i < random(100); i++) {
    if (random(100) > lev) { digitalWrite(LEDFC,HIGH); }
    if (random(100) > lev) { digitalWrite(LEDFR,HIGH); }
    if (random(100) > lev) { digitalWrite(LEDFL,HIGH); } 
    if (random(100) > lev) { digitalWrite(LEDBR,HIGH); }
    if (random(100) > lev) { digitalWrite(LEDBL,HIGH); }
    delay(random(100));
    digitalWrite(LEDFC,LOW);
    digitalWrite(LEDFR,LOW);
    digitalWrite(LEDFL,LOW);  
    digitalWrite(LEDBR,LOW);
    digitalWrite(LEDBL,LOW);
  }   
}


void spinleft() {
  Serial.println("spinleft");  
  int d = random(500);
  int d1 = random(100);
  digitalWrite(LEDFC,HIGH);
  delay(d);
  digitalWrite(LEDFL,HIGH);
  delay(d1);
  digitalWrite(LEDFC,LOW);
  delay(d);
  digitalWrite(LEDBL,HIGH);
  delay(d1);
  digitalWrite(LEDFL,LOW);
  delay(d);
  digitalWrite(LEDBR,HIGH);
  delay(d1);
  digitalWrite(LEDBL,LOW);
  delay(d);
  digitalWrite(LEDFR,HIGH);
  delay(d1);
  digitalWrite(LEDBR,LOW);
  delay(d);
  digitalWrite(LEDFC,HIGH);
  delay(d1);
  digitalWrite(LEDFR,LOW);
  delay(d);
  digitalWrite(LEDFC,LOW);
}

void spinright() {
  Serial.println("spinright");  
  int d = random(100);
  int d1 = random(50);
  digitalWrite(LEDFC,HIGH);
  delay(d);
  digitalWrite(LEDFR,HIGH);
  delay(d1);
  digitalWrite(LEDFC,LOW);
  delay(d);
  digitalWrite(LEDBR,HIGH);
  delay(d1);
  digitalWrite(LEDFR,LOW);
  delay(d);
  digitalWrite(LEDBL,HIGH);
  delay(d1);
  digitalWrite(LEDBR,LOW);
  delay(d);
  digitalWrite(LEDFL,HIGH);
  delay(d1);
  digitalWrite(LEDBL,LOW);
  delay(d);
  digitalWrite(LEDFC,HIGH);
  delay(d1);
  digitalWrite(LEDFL,LOW);
  delay(d);
  digitalWrite(LEDFC,LOW);
}


void front3() {
  Serial.println("front3");  
  int ton=random(50);
  int toff=random(500);
  for (int i = 1; i < 10; i++) {
    digitalWrite(LEDFC,HIGH);
    digitalWrite(LEDFR,HIGH);
    digitalWrite(LEDFL,HIGH);
    delay(ton);
    digitalWrite(LEDFC,LOW);
    digitalWrite(LEDFR,LOW);
    digitalWrite(LEDFL,LOW); 
    delay(toff);
  }
}




void loop() {
  // cycles random effects
  switch (random(10)) {
    case 0:
      rainbow();
      break;
    case 1:  
      if (random(100) > 90) { sing(); }
      break;
    case 2:
      allblink();
      break;
    case 3:    
      spinleft();
      break;
    case 4:
      spinright();
      break;
    case 5:
      front3();
      break;
    case 6:
      randomblink();
      break;
    default:  
      delay(1000);
  }
  delay(1000);
}

---------------