Working with eTextiles

Today at Threeways School we met with some Bath Spa University art students to discuss a project that looks to explore eTextiles. We will be working towards an installation that will be explored by the children and young people at Threeways in the Sensory Studio in March. I wanted to rig up a demo that made use of conductive thread and a micro controller designed for wearable projects so I ordered an Adafruit Gemma (essentially a wearable Arduino) and some sewable Neopixels and went on the fantastic Adafruit website to look at the wearable projects for inspiration. 

I found this tutorial for a pixie dust bag which would require minimal sewing and would be easy to put together for a demo. I only had 4 flora LED pixels, but I figured this would be fine. I also didn't want to use a capacitive sensor, but instead wanted users to have to squeeze the bag to change colour. The bag can be held in the hand and it is good dextrous exercise for some of our students to squeeze objects like this so was a nice example. I could have used a force sensor, or made one from velostat, but I opted for using a piezo as it is cheap and ready to use. One of the Arduino examples in the 'Sensors' section is for a knock sensor using a piezo, this would be the basis of my input and I simply needed to swap out the capacitive sensor input and put this in. As the example code says, the circuit is simple too: 
    * + connection of the piezo attached to analog in 0
    * - connection of the piezo attached to ground
    * 1-megohm resistor attached from analog in 0 to ground

Parts:

Adafruit Gemma - £7.26

Flora RGB Neopixels - £7.19

Conductive Thread - £3.88 (you can use wires instead to be honest and it would be easier and cheaper if like me you prefer soldering to sewing! As long as you use flexible wire and avoid brittle single core stuff it should last for a while, though may end up snapping eventually.)

Small Piezo - £1.36

A small Lithium Ion Battery - £7.22 (you will need a special LiPo charger too, beware that chargers are often aimed at either above or below 500mAh batteries, though may be adaptable. Check your battery and match it to something suitable.)

1 megaohm resistor

Some cushion foam and a cotton drawstring bag

Total cost is around £20 

Circuit:

The parts were assembled between rectangles of the cushion foam with the LEDs stitched into the middle layer. The piezo element was covered in electrical tape to stop the metal touching the conductive thread (remember it is pretty much like bare wire so don't let it touch things it shouldn't!), and layered underneath the battery and Gemma board. The final assembly was then put into a little cotton bag. 

I made sure to use crocodile clip test leads to check the hardware before I wired it up for real and tested each component as it was sewn in. The thread I used really needed clear nail varnish painting on the knots as soon as you have tied it off to stop them coming undone, but the one I have linked above says it is rough so ties up better. You could also stuff the bag with something smelly and maybe a vibration motor for a true multi sensory experience!

Final code:

//Luke Woodbury 4/11/15 dotLib.org
//Use Piezo as pressure sensor inside squashy foam filled bag
//to trigger colour change in LED animation
//Code based on:
// - NeoPixie Dust Bag by John Edgar Park jpixl.net
// - Adafruit GEMMA earring code and Adafruit NeoPixel buttoncycler code
// - Arduino knock sensor example



#include <Adafruit_NeoPixel.h>  //Include the NeoPixel library

#define NEO_PIN 1        // DIGITAL IO pin for NeoPixel OUTPUT from GEMMA
#define PIXEL_COUNT 4   // Number of NeoPixels connected to GEMMA
#define DELAY_MILLIS 10  // delay between blinks, smaller numbers are faster 
#define DELAY_MULT 8     // Randomization multiplier on the delay speed of the effect
#define BRIGHT 100        // Brightness of the pixels, max is 255

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number on Arduino (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick (most NeoPixel products)
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(PIXEL_COUNT, NEO_PIN, NEO_GRB + NEO_KHZ800);

//Piezo bits
#define knockSensor 1 // the piezo is connected to analog pin 1
const int threshold = 50;  // threshold value to decide when the detected sound is a knock or not
int sensorReading = 0;      // variable to store the value read from the sensor pin

int showColor = 0;    //color mode for cycling

void setup() {
  pixels.begin();
  pixels.setBrightness(BRIGHT);
  pixels.show();                //Set all pixels to "off"

  //pinMode(knockSensor, INPUT);
}


void loop() {
   
  int RColor = 100; //color (0-255) values to be set by cylcing touch switch, initially GOLD
  int GColor = 0 ;
  int BColor = 0 ;
  
       if (showColor==0) {//Garden PINK
         RColor = 242;
         GColor = 90;
         BColor = 255; 
       }
       if (showColor==1) {//Pixie GOLD
         RColor = 255;
         GColor = 222;
         BColor = 30; 
       }
       if (showColor==2) {//Alchemy BLUE
         RColor = 50;
         GColor = 255;
         BColor = 255; 
       }
       if (showColor==3) {//Animal ORANGE
         RColor = 255;
         GColor = 100;
         BColor = 0; 
       }
       if (showColor==4) {//Tinker GREEN
         RColor = 0;
         GColor = 255;
         BColor = 40; 
       }
  
  //sparkling
  int p = random(PIXEL_COUNT); //select a random pixel
  pixels.setPixelColor(p,RColor,GColor,BColor); //color value comes from cycling state of momentary switch
  pixels.show();
  delay(DELAY_MILLIS * random(DELAY_MULT) ); //delay value randomized to up to DELAY_MULT times longer
  pixels.setPixelColor(p, RColor/10, GColor/10, BColor/10); //set to a dimmed version of the state color
  pixels.show();
  pixels.setPixelColor(p+1, RColor/15, GColor/15, BColor/15); //set a neighbor pixel to an even dimmer value
  pixels.show();

  //piezo check
   // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(knockSensor);

  // if the sensor reading is greater than the threshold:
  if (sensorReading >= threshold) {
      showColor++;
      if (showColor > 4)
        showColor=0;
       }   
  }