12. Skin Electronics#
assignment#
- 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
introduction#
I want to make twinkle nails with NFC tags. Adafruit made NeoPixel Manicure before(without NFC tags), but I think this is not pretty. I trid to make it more sophisticated.
image source: Adafruit
Here is what I want to make.
preparation#
First, I read UID data from NFC tags.
After wiring arduino and an NFC reader as a schematic shown below, I uplaoaded DumpInfo.ino. The sketch will be in File > Examples > MFRC522 after installing the Arduino RFID Library for MFRC522.
image source: RANDOM NERD TUTORIALS
If wiring is right, you can see UID data on serial monitor as shown below(yellow underlined)
Here is five UIDs I used later prototyping.
Card UID1: 04 81 5D AA 61 3E 80
Card UID2: 04 A4 5D AA 61 3E 80
Card UID3: 04 5F 5D AA 61 3E 80
Card UID4: 04 3E 5D AA 61 3E 80
Card UID5: 04 82 5D AA 61 3E 80
prototyping#
Other than NFC tags, I bought nail tips and glue. reused Neopixels I modified in week 5.
I connected neopixels with a polyurethan insulated wire as I used in week 9.
It was painstaking job. I checked it worked properly before putting on my nails.
I glued LEDs on my nails with doublesided tapes.
Now I know why Adafruit’s NeoPixels Manicure went ugly
I put NFC tag embedded nail tips on LEDS. This is ugly…
Here is how naiLED works. I had a difficulty with letting LEDs glow once a tag’s UID is detected and a tag is apart from a sensor.
I naiLED it?
code#
#include <SPI.h>
#include <MFRC522.h>
#include <FastLED.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
#define UID1 "04 BA 5E AA 61 3E 80"
#define UID2 "04 96 5E AA 61 3E 80"
#define UID3 "04 5F 5D AA 61 3E 80"
#define UID4 "04 3E 5D AA 61 3E 80"
#define UID5 "04 82 5D AA 61 3E 80"
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
MFRC522::MIFARE_Key key;
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1
#define PIN 6
// How many NeoPixels are attached to the Arduino?
#define NUM_PIXELS 5
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, PIN, NEO_GRB + NEO_KHZ800);
int delayval = 500; // delay for half a second
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
dump_byte_array(key.keyByte, MFRC522::MF_KEY_SIZE);
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code
strip.begin(); // This initializes the NeoPixel library.
strip.show(); // Initialize all pixels to 'off'
strip.setBrightness(100);
}
void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
//return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
//return;
}
String strBuf[mfrc522.uid.size];
for (byte i = 0; i < mfrc522.uid.size; i++) {
strBuf[i] = String(mfrc522.uid.uidByte[i], HEX); // (E)using a constant integer
if(strBuf[i].length() == 1){
strBuf[i] = "0" + strBuf[i];
}
}
String strUID = strBuf[0] + " " + strBuf[1] + " " + strBuf[2] + " " + strBuf[3] + " " + strBuf[4] + " " + strBuf[5] + " " + strBuf[6];
if ( strUID.equalsIgnoreCase(UID1) ){
Serial.println("1");
Serial.println(UID1);
knightRider(1, 70, 8, 0xFF1000); // Cycles, Speed, Width, RGB Color (original orange-red)
}
else if ( strUID.equalsIgnoreCase(UID2) ){
Serial.println("2");
Serial.println(UID2);
knightRider(1, 70, 8, 0x0000FF); // Cycles, Speed, Width, RGB Color (blue)
}
else if ( strUID.equalsIgnoreCase(UID3) ){
Serial.println("3");
Serial.println(UID3);
knightRider(1, 70, 8, 0x00FF00); // Cycles, Speed, Width, RGB Color (green)
}
else if ( strUID.equalsIgnoreCase(UID4) ){
Serial.println("4");
Serial.println(UID4);
knightRider(1, 70, 20, 0xFFFF00); // Cycles, Speed, Width, RGB Color (yellow)
}
else if ( strUID.equalsIgnoreCase(UID5) ){
Serial.println("5");
Serial.println(UID5);
rainbowCycle(1);
}
}
/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
// Cycles - one cycle is scanning through all pixels left then right (or right then left)
// Speed - how fast one cycle is (32 with 16 pixels is default KnightRider speed)
// Width - how wide the trail effect is on the fading out LEDs. The original display used
// light bulbs, so they have a persistance when turning off. This creates a trail.
// Effective range is 2 - 8, 4 is default for 16 pixels. Play with this.
// Color - 32-bit packed RGB color value. All pixels will be this color.
// knightRider(cycles, speed, width, color);
void knightRider(uint16_t cycles, uint16_t speed, uint8_t width, uint32_t color) {
uint32_t old_val[NUM_PIXELS]; // up to 256 lights!
// Larson time baby!
for(int i = 0; i < cycles; i++){
for (int count = 1; count<NUM_PIXELS; count++) {
strip.setPixelColor(count, color);
old_val[count] = color;
for(int x = count; x>0; x--) {
old_val[x-1] = dimColor(old_val[x-1], width);
strip.setPixelColor(x-1, old_val[x-1]);
}
strip.show();
delay(speed);
}
for (int count = NUM_PIXELS-1; count>=0; count--) {
strip.setPixelColor(count, color);
old_val[count] = color;
for(int x = count; x<=NUM_PIXELS ;x++) {
old_val[x-1] = dimColor(old_val[x-1], width);
strip.setPixelColor(x+1, old_val[x+1]);
}
strip.show();
delay(speed);
}
}
}
uint32_t dimColor(uint32_t color, uint8_t width) {
return (((color&0xFF0000)/width)&0xFF0000) + (((color&0x00FF00)/width)&0x00FF00) + (((color&0x0000FF)/width)&0x0000FF);
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
references#
- Arduino RFID Library for MFRC522 - GitHub
- NeoPixel Manicure - Adafruit
- 非接触ICタグで遊ぼう!ArduinoでRFIDリーダRC522を使う方法
- 「光るネイルを作ってみた」 メイキング編 (nailium)
- Security Access using MFRC522 RFID Reader with Arduino - RANDOM NERD TUTORIALS