Interactive Art project

Overview of project

When 3 characters created by layering laser cut material are placed on a stand, different combinations of pressed switches result in different effects. The two types of effects are lights and sound from a neopixel strip and a buzzer. For example, if A+B are present (A and B stand for a character each) then a song AB would play and a color combination would appear on the neopixel strip. The goal of this project is to create an interactive art piece using Arduino under the theme of Rpg games.

Materials 

  • 1/8 in wooden plank
  • Arduino uno
  • breadboard
  • 9 volt battery and battery cap
  •  FTM wires (10)
  • MTM (4)
  • Neopixel strip
  • RFID module
  • RFID cards (3)
  • Flip switch

Casing and wooden pieces 

The case and the designs on the wooden id cards were created using a laser printer following a drawn design which it proceeded to cut out and etch.

 

 

 

 

 

Code

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define NeoPixel_PIN 8
Adafruit_NeoPixel strip = Adafruit_NeoPixel(10, NeoPixel_PIN, NEO_GRB + NEO_KHZ800);
//////////////////////
#include <MFRC522.h>
#include”rfid.h”
RFID rfid;
#include <SoftwareSerial.h>
#include “Adafruit_Soundboard.h”
// Choose any two pins that can be used with SoftwareSerial to RX & TX
#define SFX_TX 5
#define SFX_RX 6
// Connect to the RST pin on the Sound Board
#define SFX_RST 4
// You can also monitor the ACT pin for when audio is playing!
// we’ll be using software serial
SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX);
// pass the software serial to Adafruit_soundboard, the second
// argument is the debug port (not used really) and the third
// arg is the reset pin
Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, SFX_RST);
// can also try hardware serial with
// Adafruit_Soundboard sfx = Adafruit_Soundboard(&Serial1, NULL, SFX_RST);
// audio track names on soundboard
char KavyaDanny[] =    “T01     WAV”;
char KavyaSar[] =    “T02     WAV”;
char DannySar[] =    “T03     WAV”;
char DannyKavyaSar[] =    “T04     WAV”;
int playing = 0;
#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_PIN          10        // Configurable, see typical pin layout above
MFRC522 rc(SS_PIN, RST_PIN);
int Kavya = 0;
int Danny = 0;
int Sar = 0;
int readsuccess;
int match = 0;
byte defcard[][4] = {{0x02, 0x98, 0x68, 0x5E}, {0x66, 0x41, 0x41, 0xD5}, {0xC2, 0x20, 0x28, 0x5E}}; //for multiple card
int N = 3; //change this to the number of cards/tags you will use
byte readcard[4]; //stores the UID of current tag which is read
int switchState = 0;
int switch_pin = 2;
const int ledPin =  13;      // the number of the LED pin
void setup() {
  pinMode(switch_pin, INPUT_PULLUP);
#if defined (__AVR_ATtiny85__)
#endif
  strip.begin();
  strip.show();
  Serial.begin(9600);
  //rfid.begin(7, A5, A4, 3, 6, 2);  //rfid.begin(IRQ_PIN,SCK_PIN,MOSI_PIN,MISO_PIN,NSS_PIN,RST_PIN)
  delay(100);
  rfid.init();
  SPI.begin();
  rc.PCD_Init(); //initialize the receiver
  rc.PCD_DumpVersionToSerial(); //show details of card reader module
  //  Serial.println(F(“the authorised cards are”)); //display authorised cards just to demonstrate you may comment this section out
  //  for (int i = 0; i < N; i++) {
  //    Serial.print(i + 1);
  //    Serial.print(”  “);
  //    for (int j = 0; j < 4; j++) {
  //      Serial.print(defcard[i][j], HEX);
  //    }
  //    Serial.println(“”);
  //  }
  //  Serial.println(“”);
  //  Serial.println(F(“Scan Access Card to see Details”));
  //  // softwareserial at 9600 baud
  ss.begin(9600);
  // can also do Serial1.begin(9600)
//  if (!sfx.reset()) {
//    Serial.println(“Not found”);
//    while (1);
//  }
//  Serial.println(“SFX board found”);
}
void loop() {
  switchState = digitalRead(switch_pin);
  if (switchState == HIGH) {
    // enter Read Card Mode
    // turn LED on:
    digitalWrite(ledPin, HIGH);
    readsuccess = getid();
    if (readsuccess) {
      int match = 0;
    }
    for (int i = 0; i < N; i++) {
      Serial.print(“Testing Against Authorised card no: “);
      Serial.println(i + 1);
      if (!memcmp(readcard, defcard[i], 4)) {
        match++;
      }
      if (match)
      {
        //Serial.println(“CARD AUTHORISED”);
        delay(500);
      }
      else {
        Serial.println(“CARD NOT Authorised”);
        delay(500);
      }
    }
  } else {  // gathering mode – outcome
    // turn LED off:
    digitalWrite(ledPin, LOW);
    // find out of the audio board is playing audio
    //int playing = digitalRead(ACT);
    if ((Sar == 1) && (Danny == 1) && (Kavya == 1)) {
      rainbow (20); //(Rainbow) NeoPixle LED
      playAudio(DannyKavyaSar, playing);
      playing = 0;
    }
    else if ((Kavya == 1) && (Danny == 1)) {
      theaterChase(strip.Color(0, 127, 0), 50); // Green
      playAudio(KavyaDanny, playing);
      playing = 0;
    }
    else if ((Sar == 1) && (Danny == 1)) {
      theaterChase(strip.Color(200, 0, 200), 50); //Purple
      playAudio(DannySar, playing);
      playing = 0;
      // sfx.playTrack(TRACK003WAV);
    }
    else if ((Sar == 1) && (Kavya == 1)) {
      theaterChase(strip.Color(255, 30, 0), 50); //Orange
      playAudio(KavyaSar, playing);
      playing = 0;
    }
    Kavya = 0;
    Danny = 0;
    Sar = 0;
  }
}
////////////////////////////////////////
int getid() {
  if (!rc.PICC_IsNewCardPresent()) {
    return 0;
  }
  if (!rc.PICC_ReadCardSerial()) {
    return 0;
  }
  for (int i = 0; i < 4; i++) {
    readcard[i] = rc.uid.uidByte[i]; //storing the UID of the tag in readcard
    Serial.print(readcard[i], HEX);
    if (readcard[0] == 0x66) {
      Danny = 1;
      Serial.println(“Danny is here!”);
    }
    else if (readcard[0] == 0x02) {
      Kavya = 1;
      Serial.println(“Kavya is here!”);
    }
    else if (readcard[0] == 0xC2) {
      Sar = 1;
      Serial.println(“Sar is here!”);
    }
  }
  Serial.println();
}
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);
  }
}
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);
}
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);
  }
}
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
    for (int q = 0; q < 3; q++) {
      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, c);  //turn every third pixel on
      }
      strip.show();
      delay(wait);
      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j = 0; j < 256; j++) {   // cycle all 256 colors in the wheel
    for (int q = 0; q < 3; q++) {
      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on
      }
      strip.show();
      delay(wait);
      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}
// 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);
  }
}
/* ************* Audio Board Helper Functions ************* */
// helper function to play a track by name on the audio board
//void playAudio( String trackname, int playing ) {
void playAudio( char * trackName, int playing ) {
  // stop track if one is going
  if (playing = 0) {
    sfx.stop();
    playing = 1;
  }
}