Skin Electronics#

Thoughts on Skin Electronics#


The evolution of the electronic age has become an intrinsic part of modern human society. Each newly fabricated device is a more compact and capable version of the last and this allows for this evolution to increase in momentum. The speed at which we are creating electronic devices and automating our existence has both fascinating and detrimental implications.


When thinking of accessibility and medicine, compact, flexible devices which can be attached directly to the skin (skin electronics) or directly inserted into the body (nanotech devices) are of great value. Being able to place electronics on the skin of someone with mobility issues for instance to automate controlled or programmed outputs (i.e. blinking to turn lights on and off through a circuit attached to the eyelid) is worthwhile use of skin electronics.


The contradictions of this technology lie in our lack of understanding as a society and even within the scientific community, of the long-term effects of manmade electromagnetic waves on our resonant body (cellular physicality). We have propelled so quickly in innovation of electronic technologies without fully considering the implications of this technology on our states of wellbeing. Yet, we cannot perceive a world in which technology is not an intrinsic part of our lives, and it will only continue to evolve and merge further with human functions.


Through this reflection of the contradicting nature of skin electronics, I will create headpiece rather than an electronic device to attach onto the skin.


The headpiece will be a garment for dance / movement performance or practice.


Music is a powerful tool for changing our perception of reality. Sound can influence our emotions and states of mind. Paired with ecstatic dance, a liberated form of expressive dance which focuses on creative flow of abstract movements which release organically from the body, music and dance are a primal and important part of human nurture and healing.


Music and dance have long been used to promote trance states for the purpose of shamanic journeys, meditation, release of negative emotions, and altered states of perception.


The Cleopatra Headpiece will use a neopixel ring controlled by a sound sensor (microphone) to create various patterns according to the sound input. The louder the music and thus the vibrations the better the output of the neopixels, so take this headdress somewhere with good music and space to shake your head and dance.

Neopixels and Neopixel Library#


Neopixels (product from Adafruit) are individually addressable LEDs. Unlike RGB LED’s which require 3 pins to control each colour value, neopixels are programmed through a single pin on a microcontroller such as the Gemma board from Adafruit. Programming neopixels requires an understanding of coding through Arduino IDE.


Adafruit provides a library for neopixel outputs. You can download the library here and install.


To install the neopixel library once downloaded:


- Open Arduino IDE
- Open sketch: include library: manage library
- Search for and install Adafruit Neopixel
- Test the library (see below for test codes and examples)

Microphone Sensor#


A microphone is a transducer, meaning a component that converts energy, such as sound waves to an electrical energy in the form of audio. A thin material grid vibrates when sound waves hit the surface. When this vibration occurs it reverberates to the rest of the components in the device, which then convert the vibrations into an electrical current.


This electrical current can be used as the sensor (input) which controls the output produced by the neopixels. By taking the variables in sound wave ranges, we can program the neopixels to create patterns according to the number values printed on Arduino IDE.

Adafruit Sewable Gemma Board#


Download the Gemma Board driver for Arduino IDE


Cleopatra Headpiece with Neopixels and Sound Sensor#


Cleopatra Headdress + Sound Activated Neopixels from Catherine Euale on Vimeo.


Sound Vibration Activated Neopixels from Catherine Euale on Vimeo.

Microphone Sound Sensor#


<br>![]()
/****************************************
Example Sound Level Sketch for the 
Adafruit Microphone Amplifier
****************************************/

const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz)
int sample = A0;

void setup() 
{
   Serial.begin(9600);
}


void loop() 
{
   unsigned long startMillis= millis();  // Start of sample window
   unsigned int peakToPeak = 0;   // peak-to-peak level

   unsigned int signalMax = 0;
   unsigned int signalMin = 1024;

   // collect data for 50 mS
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(0);
      if (sample < 1024)  // toss out spurious readings
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save just the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save just the min levels
         }
      }
   }
   peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
   double volts = (peakToPeak * 5.0) / 1024;  // convert to volts

   Serial.println(volts);
   delay (100);
}

Circuit#


Assembly#


  1. Use conductive thread to carefully connect sewable Adafruit components and attach to headpiece by making small hidden / invisible stitches through the woven yarn of the headpiece.
  2. Connnect components making sure to keep stitches clean and not crossing to avoid short circuits from happening.
  3. NEOPIXEL RING TO GEMMA: Data in > D0~ | GND > GND | Vcc > Vout
  4. MICROPHONE SENSOR TO NEOPIXEL RING: GND > GND
  5. MICROPHONE SENSOR TO GEMMA: Vcc> 3Vo | OUT > D2
  6. 3v LITHIUM BATTERY TO GEMMA: On board JST Connector

Code#


#include <Adafruit_NeoPixel.h>

#define N_PIXELS  12  // Number of pixels you are using
#define MIC_PIN   A1  // Microphone is attached to Trinket GPIO #2/Gemma D2 (A1)
#define LED_PIN    0  // NeoPixel LED strand is connected to GPIO #0 / D0
#define DC_OFFSET  0  // DC offset in mic signal - if unusure, leave 0
#define NOISE     100  // Noise/hum/interference in mic signal
#define SAMPLES   60  // Length of buffer for dynamic level adjustment
#define TOP       (N_PIXELS +1) // Allow dot to go slightly off scale

byte
  peak      = 0,      // Used for falling dot
  dotCount  = 0,      // Frame counter for delaying dot-falling speed
  volCount  = 0;      // Frame counter for storing past volume data

int
  vol[SAMPLES],       // Collection of prior volume samples
  lvl       = 10,     // Current "dampened" audio level
  minLvlAvg = 0,      // For dynamic adjustment of graph low & high
  maxLvlAvg = 512;

Adafruit_NeoPixel  strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  memset(vol, 0, sizeof(vol));
  strip.begin();
}
void loop() {
  uint8_t  i;
  uint16_t minLvl, maxLvl;
  int      n, height;
  n   = analogRead(MIC_PIN);                 // Raw reading from mic 
  n   = abs(n - 512 - DC_OFFSET);            // Center on zero
  n   = (n <= NOISE) ? 0 : (n - NOISE);      // Remove noise/hum
  lvl = ((lvl * 7) + n) >> 3;    // "Dampened" reading (else looks twitchy)

  // Calculate bar height based on dynamic min/max levels (fixed point):
  height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);

  if(height < 0L)       height = 0;      // Clip output
  else if(height > TOP) height = TOP;
  if(height > peak)     peak   = height; // Keep 'peak' dot at top

  // Color pixels based on rainbow gradient
  for(i=0; i<N_PIXELS; i++) {  
    if(i >= height)               
       strip.setPixelColor(i,   0,   0, 0);
    else 
       strip.setPixelColor(i,Wheel(map(i,0,strip.numPixels()-1,30,150)));
    } 

   strip.show(); // Update strip

  vol[volCount] = n;                      // Save sample for dynamic leveling
  if(++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter

  // Get volume range of prior frames
  minLvl = maxLvl = vol[0];
  for(i=1; i<SAMPLES; i++) {
    if(vol[i] < minLvl)      minLvl = vol[i];
    else if(vol[i] > maxLvl) maxLvl = vol[i];
  }
  // minLvl and maxLvl indicate the volume range over prior frames, used
  // for vertically scaling the output graph (so it looks interesting
  // regardless of volume level).  If they're too close together though
  // (e.g. at very low volume levels) the graph becomes super coarse
  // and 'jumpy'...so keep some minimum distance between them (this
  // also lets the graph go to zero when no sound is playing):
  if((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP;
  minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels
  maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average)
}

// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}


Tests#

Microphone Sound Sensor Test + Analog Read with Arduino from Catherine Euale on Vimeo.

Neopixel Basic Test from Catherine Euale on Vimeo.

Adafruit Neopixel Ring + Sound Input Test from Catherine Euale on Vimeo.

3D Model for Crown#


Model for 3D printing a cleopatra crown to mount a neopixel ring. The holes here are for sewing onto a cap. The structure is flat to be printed on FilaFlex.

Files#