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;
}
}