Skip to content

Skin Electronics

Inspired by invisible computing, augmenting human capabilities and magic, this week proposes novel ways of interacting with the world. The focus is on Katia Vega´s Beauty Technology, a wearable computing subfield that integrates technology into cosmetics to be applied directly to one’s skin, fingernails and hair in order to transform the body’s surface in an interactive platform. Conductive Makeup, Tech Nails, FX e-makeup and Hairware are some of Beauty Technologies. The assignements are :

  • Document the concept, sketches, references also to artistic and scientific publications ;
  • Design a skin circuit: Build your own version of the “Skin masquerade party” project or Build your own version of the “Twinkle Nails” project ;
  • Document the project and included all source files and all materials used ;
  • Make a video with your skin electronic working ;
  • Make a performance of your project functioning.

Twinkle nails

Katia Vega showed us during the lecture an amazing set up for data tags that make music called Twinkle nails. this image I love it, and Diane got all the material we need to make it come true! This week work was done with Lauriane Beaumont we planed to make a Twinkle Glove.

RFID/NFC explainations

How does this works? Collin will explain it to you in 3min40

The Adafruit PN532 RFID/NFC

Our first step was to discover one of the PN532 board than read RFID and NFC. Diane bought the Adafruit PN532, you can find the product description on Adafruit page. A very nice overview explains how to use it.

PN_532

Picture from Adafruit

Welding

To can be used on an arduino uno, Adafruit PN532 has to be welding on every pin. I was in charge on this part and I have to admit it is for me a very hard work, that has been done in multiple times to get the correct connexion and I get some help from Albin Chapoutat the fabmanager of Fabrico (Valence Fablab). weld pins


It finally works: good The "busy" light is always on, on this forum we read that it was on when ok to received information ond off when reading, i find it completely misnamed.

Install Adafruit_PN532 libraries

The library Adafruit-PN532 is available througt IDE, (if you don't find it, you can get it from GitHub). There are two Arduino libraries for using the Adafruit NFC boards. One library supported it over a SPI connection, and the other library supported it over an I2C connection. Ever if I don't understanf everything about it, I chose to get the I2C because it's the one by default on Adafruit PN532. I2C only uses two pins (Analog 4 and 5) to communicate . I2C is a 'shared' bus - unlike SPI - so you can put as many sensors as you'd like all on the same two pins, as long as their addresses don't collide/conflict. That's why you need to also get the "BusIO" library. I2C uses also one pin as an 'interrupt' pin (Digital 2) wich instead of constantly asking the NFC shield "is there a card in view yet? what about now?" constantly, the chip will alert us when a NFC target comes into the antenna range. You can find more explainations on PN532 overview). installation des librairies

The NFC chips

Presentation

we got two classes of NFC Chips, however the blink ones are not able to store data (they are designed to blink), we can only used the round ones.


Read the NFC chips identifications

The "ReadMiFare" sketch (you can find it in arduino IDE : files/examples/Adafruit PN532/readMifare) reads the chips, so we can collect identification of each chip. The first step was to get Mifare code for using the shield with I2C (the SPI connection is the defaut and recommanded one), here is the corrected version :

/**************************************************************************/
/*! 
    @file     readMifare.pde
    @author   Adafruit Industries
    @license  BSD (see license.txt)

    This example will wait for any ISO14443A card or tag, and
    depending on the size of the UID will attempt to read from it.

    If the card has a 4-byte UID it is probably a Mifare
    Classic card, and the following steps are taken:

    - Authenticate block 4 (the first block of Sector 1) using
      the default KEYA of 0XFF 0XFF 0XFF 0XFF 0XFF 0XFF
    - If authentication succeeds, we can then read any of the
      4 blocks in that sector (though only block 4 is read here)

    If the card has a 7-byte UID it is probably a Mifare
    Ultralight card, and the 4 byte pages can be read directly.
    Page 4 is read by default since this is the first 'general-
    purpose' page on the tags.


This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
This library works with the Adafruit NFC breakout 
  ----> https://www.adafruit.com/products/364

Check out the links above for our tutorials and wiring diagrams 
These chips use SPI or I2C to communicate.

Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!

*/
/**************************************************************************/
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>


// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
#define PN532_IRQ   (2)
#define PN532_RESET (3)  // Not connected by default on the NFC Shield


// Uncomment just _one_ line below depending on how your breakout or shield
// is connected to the Arduino:

// Use this line for a breakout with a SPI connection:
//Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);

// Use this line for a breakout with a hardware SPI connection.  Note that
// the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
// hardware SPI SCK, MOSI, and MISO pins.  On an Arduino Uno these are
// SCK = 13, MOSI = 11, MISO = 12.  The SS line can be any digital IO pin.
//Adafruit_PN532 nfc(PN532_SS);

// Or use this line for a breakout or shield with an I2C connection:
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

void setup(void) {
  Serial.begin(115200);
  while (!Serial) delay(10); // for Leonardo/Micro/Zero

  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

  // configure board to read RFID tags
  nfc.SAMConfig();

  Serial.println("Waiting for an ISO14443A Card ...");
}


void loop(void) {
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

  if (success) {
    // Display some basic information about the card
    Serial.println("Found an ISO14443A card");
    Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("  UID Value: ");
    nfc.PrintHex(uid, uidLength);
    Serial.println("");

    if (uidLength == 4)
    {
      // We probably have a Mifare Classic card ... 
      Serial.println("Seems to be a Mifare Classic card (4 byte UID)");

      // Now we need to try to authenticate it for read/write access
      // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
      Serial.println("Trying to authenticate block 4 with default KEYA value");
      uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

      // Start with block 4 (the first block of sector 1) since sector 0
      // contains the manufacturer data and it's probably better just
      // to leave it alone unless you know what you're doing
      success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);

      if (success)
      {
        Serial.println("Sector 1 (Blocks 4..7) has been authenticated");
        uint8_t data[16];

        // If you want to write something to block 4 to test with, uncomment
        // the following line and this text should be read back in a minute
        //memcpy(data, (const uint8_t[]){ 'a', 'd', 'a', 'f', 'r', 'u', 'i', 't', '.', 'c', 'o', 'm', 0, 0, 0, 0 }, sizeof data);
        // success = nfc.mifareclassic_WriteDataBlock (4, data);

        // Try to read the contents of block 4
        success = nfc.mifareclassic_ReadDataBlock(4, data);

        if (success)
        {
          // Data seems to have been read ... spit it out
          Serial.println("Reading Block 4:");
          nfc.PrintHexChar(data, 16);
          Serial.println("");

          // Wait a bit before reading the card again
          delay(1000);
        }
        else
        {
          Serial.println("Ooops ... unable to read the requested block.  Try another key?");
        }
      }
      else
      {
        Serial.println("Ooops ... authentication failed: Try another key?");
      }
    }

    if (uidLength == 7)
    {
      // We probably have a Mifare Ultralight card ...
      Serial.println("Seems to be a Mifare Ultralight tag (7 byte UID)");

      // Try to read the first general-purpose user page (#4)
      Serial.println("Reading page 4");
      uint8_t data[32];
      success = nfc.mifareultralight_ReadPage (4, data);
      if (success)
      {
        // Data seems to have been read ... spit it out
        nfc.PrintHexChar(data, 4);
        Serial.println("");

        // Wait a bit before reading the card again
        delay(1000);
      }
      else
      {
        Serial.println("Ooops ... unable to read the requested page!?");
      }
    }
  }
}
Unfortunately, we had different types of wrong messages, putting us in a dead end for the next steps. problem lecture tag problem lecture tag It was because the frequency send was on 9600baud in the sketch ReadMifareClassical the 115000baud is indicated as the good one. Thanks to Diane who saw it we got it working and get the results, the NFC identification of our chips are:

  • {0x04, 0x08, 0x80, 0x52, 0x9E, 0x11, 0x91},
  • {0x04, 0x31, 0x81, 0x52, 0x9E, 0x11, 0x90},
  • {0x04, 0x21, 0x80, 0x52, 0x9E, 0x11, 0x90},
  • {0x04, 0xEB, 0x66, 0x8A, 0xA9, 0x11, 0x90}

We only had 4 chips because I lost one :/

Adapting the twinkle sketch

Katia Vega sketch is (available on GitHub), we make some changes to can use it with our chips:

* make it available for IC2 connection ;
* take out the 6 uneeded chips because she done sketch it for 10 chips ;
* replace her chips identifications by ours ;
* copy the Pitches.h file (we didn't fing how to include the to our IDE).

Defining the notes we want to use.

int notes[] = {
      NOTE_E4, NOTE_C4, NOTE_G4, NOTE_D4
    };
Calling them by their name :
if (count == 7) 
          {
            Serial.print("i: ");Serial.println(i);
            if (i==0 || i==5) {tone(8, notes[0], 325); Serial.println("MI");return;}
            if (i==1 || i==6) {tone(8, notes[1], 325); Serial.println("DO");return;}
            if (i==2 || i==7) {tone(8, notes[2], 325); Serial.println("SOL");return;}
            if (i==3 || i==8) {tone(8, notes[3], 325); Serial.println("RE");return;}

            //if (i==4 || i==9) {tone(8, notes[4], 325); Serial.println("SOL");return;}//
          }

The final sketch is:

#include <Wire.h>
   #include <SPI.h>
   #include <Adafruit_PN532.h>

   #define NOTE_B0  31
   #define NOTE_C1  33
   #define NOTE_CS1 35
   #define NOTE_D1  37
   #define NOTE_DS1 39
   #define NOTE_E1  41
   #define NOTE_F1  44
   #define NOTE_FS1 46
   #define NOTE_G1  49
   #define NOTE_GS1 52
   #define NOTE_A1  55
   #define NOTE_AS1 58
   #define NOTE_B1  62
   #define NOTE_C2  65
   #define NOTE_CS2 69
   #define NOTE_D2  73
   #define NOTE_DS2 78
   #define NOTE_E2  82
   #define NOTE_F2  87
   #define NOTE_FS2 93
   #define NOTE_G2  98
   #define NOTE_GS2 104
   #define NOTE_A2  110
   #define NOTE_AS2 117
   #define NOTE_B2  123
   #define NOTE_C3  131
   #define NOTE_CS3 139
   #define NOTE_D3  147
   #define NOTE_DS3 156
   #define NOTE_E3  165
   #define NOTE_F3  175
   #define NOTE_FS3 185
   #define NOTE_G3  196
   #define NOTE_GS3 208
   #define NOTE_A3  220
   #define NOTE_AS3 233
   #define NOTE_B3  247
   #define NOTE_C4  262
   #define NOTE_CS4 277
   #define NOTE_D4  294
   #define NOTE_DS4 311
   #define NOTE_E4  330
   #define NOTE_F4  349
   #define NOTE_FS4 370
   #define NOTE_G4  392
   #define NOTE_GS4 415
   #define NOTE_A4  440
   #define NOTE_AS4 466
   #define NOTE_B4  494
   #define NOTE_C5  523
   #define NOTE_CS5 554
   #define NOTE_D5  587
   #define NOTE_DS5 622
   #define NOTE_E5  659
   #define NOTE_F5  698
   #define NOTE_FS5 740
   #define NOTE_G5  784
   #define NOTE_GS5 831
   #define NOTE_A5  880
   #define NOTE_AS5 932
   #define NOTE_B5  988
   #define NOTE_C6  1047
   #define NOTE_CS6 1109
   #define NOTE_D6  1175
   #define NOTE_DS6 1245
   #define NOTE_E6  1319
   #define NOTE_F6  1397
   #define NOTE_FS6 1480
   #define NOTE_G6  1568
   #define NOTE_GS6 1661
   #define NOTE_A6  1760
   #define NOTE_AS6 1865
   #define NOTE_B6  1976
   #define NOTE_C7  2093
   #define NOTE_CS7 2217
   #define NOTE_D7  2349
   #define NOTE_DS7 2489
   #define NOTE_E7  2637
   #define NOTE_F7  2794
   #define NOTE_FS7 2960
   #define NOTE_G7  3136
   #define NOTE_GS7 3322
   #define NOTE_A7  3520
   #define NOTE_AS7 3729
   #define NOTE_B7  3951
   #define NOTE_C8  4186
   #define NOTE_CS8 4435
   #define NOTE_D8  4699
   #define NOTE_DS8 4978

   int notes[] = {
     NOTE_E4, NOTE_C4, NOTE_G4, NOTE_D4
   };

   // If using the breakout with SPI, define the pins for SPI communication.
   /*#define PN532_SCK  (2)
   #define PN532_MOSI (3)
   #define PN532_SS   (4)
   #define PN532_MISO (5)*/

   // If using the breakout or shield with I2C, define just the pins connected
   // to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
   #define PN532_IRQ   (2)
   #define PN532_RESET (3)  // Not connected by default on the NFC Shield

   Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

   #if defined(ARDUINO_ARCH_SAMD)
   // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
   // also change #define in Adafruit_PN532.cpp library file
     #define Serial SerialUSB
   #endif

   const int numCards = 4;
   uint32_t cards[numCards][7]= { 
   {0x04, 0x08, 0x80, 0x52, 0x9E, 0x11, 0x91}, 
   {0x04, 0x31, 0x81, 0x52, 0x9E, 0x11, 0x90},
   {0x04, 0x21, 0x80, 0x52, 0x9E, 0x11, 0x90},
   {0x04, 0xEB, 0x66, 0x8A, 0xA9, 0x11, 0x90}
   };

   void setup(void) {
     #ifndef ESP8266
       while (!Serial); // for Leonardo/Micro/Zero
     #endif
     Serial.begin(115200);
     Serial.println("Hello!");

     nfc.begin();

     uint32_t versiondata = nfc.getFirmwareVersion();
     if (! versiondata) {
       Serial.print("Didn't find PN53x board");
       while (1); // halt
     }
     // Got ok data, print it out!
     Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
     Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
     Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

     // configure board to read RFID tags
     nfc.SAMConfig();

     Serial.println("Waiting for an ISO14443A Card ...");
   }

   void loop(void) {
     uint8_t success;
     uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
     uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

     // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
     // 'uid' will be populated with the UID, and uidLength will indicate
     // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
     success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

     if (success) {
       // Display some basic information about the card
       Serial.println("Found an ISO14443A card");
       Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
       Serial.print("  UID Value: ");
       nfc.PrintHex(uid, uidLength);

       lookForCard (uid);
     }


   }

   void lookForCard(uint8_t cardID[7])
   {
     for (int i =0; i<numCards;i++)
     {
       int count =0;
       for (int j =0; j<7;j++)
         {
           //Serial.print("cardid: ");Serial.print(cardID[j],HEX);
           //Serial.print(" cards: ");Serial.println(cards[i][j],HEX);
             if (cardID[j]== cards[i][j])
             {
               count++;

             }
         }
         Serial.print("count: ");Serial.println(count);

         if (count == 7) 
         {
           Serial.print("i: ");Serial.println(i);
           if (i==0 || i==5) {tone(8, notes[0], 325); Serial.println("MI");return;}
           if (i==1 || i==6) {tone(8, notes[1], 325); Serial.println("DO");return;}
           if (i==2 || i==7) {tone(8, notes[2], 325); Serial.println("SOL");return;}
           if (i==3 || i==8) {tone(8, notes[3], 325); Serial.println("RE");return;}

           //if (i==4 || i==9) {tone(8, notes[4], 325); Serial.println("SOL");return;}//
         }
     }  
   }

As we cannot play two notes at the same time on the board, we can't have harmonies, only single notes. Lauriane wanted to programm bases notes of each chord, so she could sing along with my bases. Unfortunately, the notes library doesn't consider sharp and flat (# & ♭), there is only sharps and for a chord, it's not the same thing.

She programmed E / C / G / D.

chip note designation correspondence in TonePitch's library
0 MI E NOTE_E5 659
1 DO# C NOTE_C5 523
2 SOL G NOTE_G5 784
3 RE♮ D NOTE_D5 587

Tests

We just taped the chips to Lauriane's fingers and tested it at different levels /octaves (on the left). It works!

Twinkle box for a twinkle glove

We used Lauriane glove from week03 (Circular Open Source Fashion), I love it! And add a coordinated box with the modules to pack the arduino and the Adafruit PN532 boards:

Time for the show!

The original theme is "Au clair de la lune" a french lullaby

NFC Tools application

Presentation

On the phone, NFC tools application let us read the chips and code them. You can find it on the Apple store and the Google play but will only be able to use it if your phone is quite new (mine is from 2014, we used Lauriane one)

Use

It was impossible to create a Vcard because the chip memoire is too small for that: 135bytes. We added a small text that gives the reference of the note programmed on it.

My week review for instagram



Last update: 2022-12-19