Skip to content

12. Skin Electronics

This week was full of new things and exploration for me. The process below will unfold step by step through tests and small discoveries, just like my learning week.

Research

Basic concepts

Skin electronics refers to ultra-thin, flexible and stretchable electronic systems designed to be worn directly on the skin and create body-centric interfaces.

Credit to Katia Vega

Main applications include:

  1. Physiological monitoring (health & wellness - heart, temperature, muscle activity)
  2. Human-Machine Interfaces ("Electronic tattoos", tactile patches)
  3. Soft robotics and prosthetics (tactile perception)
  4. Communication and smart textiles (Wireless patches)

Adafruit microcontroller

The Adafruit SADM21 QT Py is a tiny, versatile microcontroller ideal for e-textile and e-skin projects. Easy to program with Arduino, it was my first time experimenting with something other than the Arduino Uno, exploring a smaller, more compact platform for interactive wearables.

Alumni pages that inspired me

References & Inspiration

//to complete

  • Political Lace by Melissa Coleman is an elegant detachable lace collar embedded with a subtle LED light that pulses every 7.5 minutes: a solemn reminder of the tragic frequency at which young women die during childbirth.

  • Kinisi by Katia Vega transforms the skin into a digital interface: subtle FX cosmetics, conductive makeup and hidden sensors let facial gestures (a blink, a wink, a smile or raised eyebrow) trigger light patterns on the skin and hair.

  • The following Kenzo spot highlights Margaret Qualley’s expressive face and body movements, which inspired me with their fluidity and presence for e-skin project.

Final Result

This week's assignments required to build a circuit adapted to skin (mask, hair, tattoo, patch, glove, nails, etc.).

As outcome XXX

Process and workflow

// to complete

Tutorial with Emma Pareschi

Getting ready for Emma Pareschi's training

Material
  • Microcontroller (Arduino UNO or XIAO board)
  • Alligator clips
  • Jumper wires
  • Copper tape
  • Velostat
  • Aluminum foil
  • Tape
  • Baking paper
  • High value resistor (500K - 1M - 2M Ohm)
  • Paper
  • Pencil or pen
  • Ruler
  • Scissor

Matrix is a grid whose intersection nodes are sensors. In our application, pressure sensors.

In this screenshot, column 0 is the one set to LOW and allowing the code reading. Same option is repeated for the other two columns later in the code.

Final configuration with Arduino Pins. [Code used](#code1)

We used Processing to display visual changes while pressing the matrix.


Capacitive sensor detects changes in capacitance caused by the body approaching without needing pressure.

Theoretical concepts during the training

A quick test with aluminum foil, while approaching the material the values changed as visible in the serial plotter view. Code used

Experimenting

Material used
: - Kinesio taping
- Silver conductive tape
- Alligator clips and wires
- LilyPad LED
- Arduino Uno.

Test ran:

Open and close the arm to close the loop (each part with the conductive tape) and turn on a LED. Code used

Wiring in Arduino UNO:
- Silver tape A: pin 7
- Silver tape A: GND
- LilyPad LED: digital pin 9 for anode (+) and GND for cathode (-)

I repeated the same test but connecting 3 different lilypad LED to 3 different sensors. With Chatgpt support, code has been adjusted to include the elements Arduino code.

I was looking for a smaller and "wearable" solution and in the lab I found Adafruit SADMI (QT PY). While activating this small microcontroller I found a neopixel already embedded, tested it and decided to use it instead of sewable LEDs in order to reduce the number of components.

The final code here allows to:
- Sensor 1: turn off BLUE light
- Sensor 2: turno off RED light
- Sensor 3: turn off GREEN light

Each sensor is activated then the circuit is comple, so when the two conductive parts touch each other.

https://cdn-shop.adafruit.com/product-videos/1024x768/4600-07.mp4

//add small video


Images: Martina Muroni unless otherwise stated.


Code Example

/*
The analog sensor is connected between pin A0 and pin 4
*/

int row0 = A0;  //first row pin
int row1 = A1;  //first row pin
int row2 = A2;  //first row pin

int col0 = 4;    //first column pin
int col1 = 5;    //first column pin
int col2 = 6;    //first column pin


int incomingValue0 = 0; //variable to save the sensor reading
int incomingValue1 = 0; //variable to save the sensor reading
int incomingValue2 = 0; //variable to save the sensor reading

int incomingValue3 = 0; //variable to save the sensor reading
int incomingValue4 = 0; //variable to save the sensor reading
int incomingValue5 = 0; //variable to save the sensor reading

int incomingValue6 = 0; //variable to save the sensor reading
int incomingValue7 = 0; //variable to save the sensor reading
int incomingValue8 = 0; //variable to save the sensor reading

void setup() {

  // set all rows to INPUT (high impedance):
    pinMode(row0, INPUT_PULLUP);
    pinMode(row1, INPUT_PULLUP);
    pinMode(row2, INPUT_PULLUP);

 //set the firt column as output
  pinMode(col0, OUTPUT);
  pinMode(col1, OUTPUT);
  pinMode(col2, OUTPUT);


  //open serial communication
  Serial.begin(9600);

}

void loop() {

  //set the col0 to low (GND)
  digitalWrite(col0, LOW);
  digitalWrite(col1, HIGH);
  digitalWrite(col2, HIGH);

  //read the three rows pins
    incomingValue0 = analogRead(row0);
    incomingValue1 = analogRead(row1);
    incomingValue2 = analogRead(row2);

  //set the col1 to low (GND)
  digitalWrite(col0, HIGH);
  digitalWrite(col1, LOW);
  digitalWrite(col2, HIGH);

    incomingValue3 = analogRead(row0);
    incomingValue4 = analogRead(row1);
    incomingValue5 = analogRead(row2);

  //set the col2 to low (GND)
  digitalWrite(col0, HIGH);
  digitalWrite(col1, HIGH);
  digitalWrite(col2, LOW);

    incomingValue6 = analogRead(row0);
    incomingValue7 = analogRead(row1);
    incomingValue8 = analogRead(row2);

  // Print the incoming values of the grid:

    Serial.print(incomingValue0);
    Serial.print("\t");
    Serial.print(incomingValue1);
    Serial.print("\t");
    Serial.print(incomingValue2);
    Serial.print("\t");
    Serial.print(incomingValue3);
    Serial.print("\t");
    Serial.print(incomingValue4);
    Serial.print("\t");
    Serial.print(incomingValue5);
    Serial.print("\t");
    Serial.print(incomingValue6);
    Serial.print("\t");
    Serial.print(incomingValue7);
    Serial.print("\t");
    Serial.println(incomingValue8);

delay(10); //wait millisecond
}
#include <CapacitiveSensor.h>

/*
 * Modified example from CapitiveSense Library Demo Sketch (Paul Badger 2008)
 * Uses a high value resistor e.g. 10M between send pin and receive pin
 * Resistor effects sensitivity, experiment with values, 50K - 50M. Larger resistor values yield larger sensor values.
 * Receive pin is the sensor pin - try different amounts of foil/metal on this pin
 */

CapacitiveSensor   cs_4_2 = CapacitiveSensor(4,2);   // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired

void setup()                    
{
   cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF);  // turn off autocalibrate on channel 1 - just as an example
   Serial.begin(9600);
}

void loop()                    
{
    long total1 =  cs_4_2.capacitiveSensor(30);
    Serial.println(total1);                  // print sensor output 1
    delay(50);
}
int sensorPin = 7;
int ledPin = 9;

void setup() {
  pinMode(sensorPin, INPUT_PULLUP); // legge HIGH quando aperto
  pinMode(ledPin, OUTPUT);
}

void loop() {
  int val = digitalRead(sensorPin);
  if (val == LOW) {             // LOW quando i patch si toccano
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
}
// === Arduino UNO - 3 Sensors → 3 LEDs ===
// Sensors: two conductive tape points close → circuit closes
// LEDs: independent output for each sensor
// Connections: digital pins as inputs/outputs

// ------------------- PIN ASSIGNMENTS -------------------
int sensor1Pin = 2;   // Sensor 1 input (digital)
int sensor2Pin = 3;   // Sensor 2 input
int sensor3Pin = 4;   // Sensor 3 input

int led1Pin = 5;      // LED 1 output (e.g., blue)
int led2Pin = 6;      // LED 2 output (e.g., white)
int led3Pin = 7;      // LED 3 output (e.g., green)

// ------------------- SETUP -------------------
void setup() {
  // configure sensor pins as input with internal pullup
  pinMode(sensor1Pin, INPUT_PULLUP);
  pinMode(sensor2Pin, INPUT_PULLUP);
  pinMode(sensor3Pin, INPUT_PULLUP);

  // configure LED pins as OUTPUT
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(led3Pin, OUTPUT);
}

// ------------------- MAIN LOOP -------------------
void loop() {
  // read sensors (LOW means circuit closed)
  int sensor1State = digitalRead(sensor1Pin);
  int sensor2State = digitalRead(sensor2Pin);
  int sensor3State = digitalRead(sensor3Pin);

  // control LEDs based on sensor state
  digitalWrite(led1Pin, sensor1State == LOW ? HIGH : LOW);
  digitalWrite(led2Pin, sensor2State == LOW ? HIGH : LOW);
  digitalWrite(led3Pin, sensor3State == LOW ? HIGH : LOW);

  // small delay to avoid bouncing issues (optional)
  delay(20);
}
#include <Adafruit_NeoPixel.h>

// neopixel interno
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(NUMPIXELS, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);

// sensori
int sensor1Pin = A0;   // sensore 1
int sensor2Pin = A1;   // sensore 2
int sensor3Pin = A3;   // sensore 3

void setup() {
  // neopixel
  pixels.begin();
  pixels.setBrightness(255);

  // sensori con pullup
  pinMode(sensor1Pin, INPUT_PULLUP);
  pinMode(sensor2Pin, INPUT_PULLUP);
  pinMode(sensor3Pin, INPUT_PULLUP);
}

void loop() {
  bool s1 = (digitalRead(sensor1Pin) == LOW);
  bool s2 = (digitalRead(sensor2Pin) == LOW);
  bool s3 = (digitalRead(sensor3Pin) == LOW);

  if (s1) {
    // BLUE
    pixels.setPixelColor(0, pixels.Color(0, 0, 200));
  }
  else if (s2) {
    // WHITE
    //pixels.setPixelColor(0, pixels.Color(180, 180, 180));
    //RED
       pixels.setPixelColor(0, pixels.Color(200, 0, 0));
  }
  else if (s3) {
    // GREEN
    pixels.setPixelColor(0, pixels.Color(0, 150, 0));
  }
  else {
    // OFF
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
  }

  pixels.show();
  delay(20);
}