Software

The code we used for this project was executed through Arduino IDE. In early versions of the prototype, a machine learning program known as ESP Gestures was used to track movement with the accelerometer. This program was not used in the iteration presented to the class, but if this prototype were to be developed further, the robust machine learning this program affords would be a valuable addition to the dueling wands’ gameplay potential.


The program works by looking out for two key activators: the press of the button on the wands and two unique gestures. Once both the activators have been successfully completed, the code corresponding to the given gesture executes.

//WAND ONE

//IR library & setup

#include <IRremote.h>

IRsend irsend;


//xBee library

#include <SoftwareSerial.h>


//Defined for our initial RGB LED, which we did not end up implementing. Instead,

//these pins correspond to the LEDs on the breadboard connected to the Arduino.

#define COMMON_ANODE

int redPin = 11;

int greenPin = 10;

int bluePin = 9;


//set up button

const int buttonPin = 12;  

// variables will change:

int buttonState = 0;         // variable for reading the pushbutton status


SoftwareSerial xBee(4, 5); //more xbee stuff


//setting up the pins for the accelerometer

int zpin = A2;

int ypin = A1;

int xpin = A0;


//a timer used in the accelerometer code

//long timer = 0;


void setup() {

 Serial.begin(9600);

 //setting up RGB pins

 pinMode(redPin, OUTPUT);

 pinMode(greenPin, OUTPUT);

 pinMode(bluePin, OUTPUT);

 //initialize xbee

 xBee.begin(9600);

 // initialize the pushbutton pin as an input:

 pinMode(buttonPin, INPUT);

 // initialize accelerometer xyz pins

 pinMode(xpin, INPUT);

 pinMode(ypin, INPUT);

 pinMode(zpin, INPUT);

}


void loop() {

 // read the state of the pushbutton value:

 buttonState = digitalRead(buttonPin);

 // print out the X-Y-Z acceleration to the serial as read from the accelerometer

 Serial.print(analogRead(xpin)); Serial.print("\t");

 Serial.print(analogRead(ypin)); Serial.print("\t");

 Serial.print(analogRead(zpin)); Serial.println();

 delay(10);

 // set color to nothing

 setColor(255, 255, 255);


 // Initially, we planned on using a machine learning program to register more

 // complicated gestures. however, for this prototype, we found it to be simple

 // and more reliable to simply use the raw values from the accelerometer to

 // recognize different gestures.

 //

 // For move 1, the user brings the wand up sharply, registering the x-acceleration

 // as at least 600. The button must be pressed for a spell to be cast

 if (analogRead(xpin) > 600 && buttonState == HIGH) { // gesture 1

     Serial.print("gesture 1"); Serial.println();

     setColor(0, 255, 0); //red

     //send out the infrared signal

     for (int i = 0; i < 50; i++) {

       irsend.sendSony (0xa90, 12); // Sony TV power code

       delay (40);

     }

     // send the letter recognized by the command center that corresponds with the spell

     sendxbee('z');

   }

   // For move 2, the user rotates the wand to the right, registering the y-acceleration

   // as at least 600. The button must be pressed for a spell to be cast

   if (analogRead(ypin) > 600 && buttonState == HIGH) { // gesture 2

     Serial.print("gesture 2"); Serial.println();

     setColor(0, 0, 255);  // green

     //send out the infrared signal

     for (int i = 0; i < 50; i++) {

       irsend.sendSony (0xa90, 12); // Sony TV power code

       delay (40);

     }

     // send the letter recognized by the command center that corresponds with the spell

     sendxbee('y');

   }


}


// given a char, sends through the xbee

void sendxbee(char spell) {

 if (xBee.available()) {

      xBee.print(spell);

 }

}


// sets the colors of the LEDs

void setColor(int red, int green, int blue)

{

 #ifdef COMMON_ANODE

   red = 255 - red;

   green = 255 - green;

   blue = 255 - blue;

 #endif

 analogWrite(redPin, red);

 analogWrite(greenPin, green);

 analogWrite(bluePin, blue);  

}


//WAND TWO

//Accelerometer libraries

#include <MPU6050_tockn.h>

#include <Wire.h>


//IR library & setup

#include <IRremote.h>

IRsend irsend;


//xBee library

#include <SoftwareSerial.h>


//Defined for our initial RGB LED, which we did not end up implementing. Instead,

//these pins correspond to the LEDs on the breadboard connected to the Arduino.

#define COMMON_ANODE

int redPin = 11;

int greenPin = 10;

int bluePin = 9;


//set up button

const int buttonPin = 12;  

// variables will change:

int buttonState = 0;         // variable for reading the pushbutton status


// for the Acceleromter pins

#define rxPin 4

#define txPin 5


SoftwareSerial xBee = SoftwareSerial(rxPin, txPin); //more xbee stuff


//setting up accelerometer

MPU6050 mpu6050(Wire);


// timer to track duration

long timer = 0;


void setup() {

 Serial.begin(9600);


 //various accelerometer initializations

 Wire.begin();

 mpu6050.begin();

 mpu6050.calcGyroOffsets(true);


 //setting up RGB pins

 pinMode(redPin, OUTPUT);

 pinMode(greenPin, OUTPUT);

 pinMode(bluePin, OUTPUT);


 //initializing accelerometer pins

 pinMode(rxPin, INPUT);

 pinMode(txPin, OUTPUT);


 //initialize xbee

 xBee.begin(9600);


 // initialize the pushbutton pin as an input:

 pinMode(buttonPin, INPUT);

}


void loop() {

 // read the state of the pushbutton value:

 buttonState = digitalRead(buttonPin);


 //get the most recent accelerometer info

 mpu6050.update();


 // if the accelerometer has finished initializing...

 if(millis() - timer > 1000){

   // print readings from accelerometer's angle & acceleration readings

   Serial.print("angleX : ");Serial.print(mpu6050.getAngleX());

   Serial.print("\tangleY : ");Serial.print(mpu6050.getAngleY());

   Serial.print("\tangleZ : ");Serial.println(mpu6050.getAngleZ());

   Serial.println("=======================================================\n");*/

   Serial.print(mpu6050.getAccX()); Serial.print("\t");

   Serial.print(mpu6050.getAccY()); Serial.print("\t");

   Serial.print(mpu6050.getAccZ()); Serial.println();

   delay(10);


   // set color to null

   setColor(255, 255, 255);


   //update timer

   timer = millis();


   // Initially, we planned on using a machine learning program to register more

   // complicated gestures. however, for this prototype, we found it to be simple

   // and more reliable to simply use the raw values from the accelerometer to

   // recognize different gestures.

   //

   // For move 1, the user brings the wand up sharply, registering the y-acceleration

   // of more than 0.10. The button must be pressed for a spell to be cast

   if (mpu6050.getAccY() > 0.10 && buttonState == HIGH) { // gesture 1

     Serial.print("gesture 1"); Serial.println();

     setColor(0, 255, 0); //red

     //send out the infrared signal

     for (int i = 0; i < 50; i++) {

       irsend.sendSony (0xa90, 12); // Sony TV power code

       delay (40);

     }

     // send the letter recognized by the command center that corresponds with the spell

     sendxbee('x');

   }

   // For move 2, the user rotates the wand to the right, registering an x-acceleration

   // less than -0.40. The button must be pressed for a spell to be cast

   if (mpu6050.getAccX() < -0.40 && buttonState == HIGH) { // gesture 2

     Serial.print("gesture 2"); Serial.println();

     setColor(0, 0, 255);  // green

     //send out the infrared signal

     for (int i = 0; i < 50; i++) {

       irsend.sendSony (0xa90, 12); // Sony TV power code

       delay (40);

     }

    // send the letter recognized by the command center that corresponds with the spell

    sendxbee('w');

   }

 }


}


// given a char, sends through the xbee

void sendxbee(char spell) {

 if (xBee.available()) {

      xBee.print(spell);

 }

}


// sets the colors of the LEDs

void setColor(int red, int green, int blue)

{

 #ifdef COMMON_ANODE

   red = 255 - red;

   green = 255 - green;

   blue = 255 - blue;

 #endif

 analogWrite(redPin, red);

 analogWrite(greenPin, green);

 analogWrite(bluePin, blue);  

}