A note hitting game for the mbed LPC 1768. User uses a joystick to hit notes as they come down the screen in 3 different lanes.

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player

Files at this revision

API Documentation at this revision

Comitter:
jmpin
Date:
Thu Mar 17 21:12:59 2016 +0000
Parent:
0:1340139c5758
Commit message:
Game is pretty much finished, minus the sound coming from .wav files from the SD card

Changed in this revision

Nav_Switch.cpp Show annotated file Show diff for this revision Revisions of this file
Nav_Switch.h Show annotated file Show diff for this revision Revisions of this file
SongPlayer.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mpr121.cpp Show diff for this revision Revisions of this file
mpr121.h Show diff for this revision Revisions of this file
note.cpp Show annotated file Show diff for this revision Revisions of this file
note_private.h Show annotated file Show diff for this revision Revisions of this file
note_public.h Show annotated file Show diff for this revision Revisions of this file
player.cpp Show annotated file Show diff for this revision Revisions of this file
player.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Nav_Switch.cpp	Thu Mar 17 21:12:59 2016 +0000
@@ -0,0 +1,38 @@
+#include "mbed.h"
+#include "Nav_Switch.h"
+
+
+Nav_Switch::Nav_Switch (PinName up,PinName down,PinName left,PinName right,PinName fire):
+    _pins(up, down, left, right, fire)
+{
+    _pins.mode(PullUp); //needed if pullups not on board or a bare nav switch is used - delete otherwise
+    wait(0.001); //delays just a bit for pullups to pull inputs high
+}
+inline bool Nav_Switch::up()
+{
+    return !(_pins[0]);
+}
+inline bool Nav_Switch::down()
+{
+    return !(_pins[1]);
+}
+inline bool Nav_Switch::left()
+{
+    return !(_pins[2]);
+}
+inline bool Nav_Switch::right()
+{
+    return !(_pins[3]);
+}
+bool Nav_Switch::fire()
+{
+    return !(_pins[4]);
+}
+int Nav_Switch::read()
+{
+    return _pins.read();
+}
+Nav_Switch::operator int()
+{
+    return _pins.read();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Nav_Switch.h	Thu Mar 17 21:12:59 2016 +0000
@@ -0,0 +1,23 @@
+#include "mbed.h"
+
+class Nav_Switch
+{
+    public:
+    Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire);
+    int read();
+//boolean functions to test each switch
+    bool up();
+    bool down();
+    bool left();
+    bool right();
+    bool fire();
+//automatic read on RHS
+    operator int ();
+//index to any switch array style
+    bool operator[](int index) {
+        return _pins[index];
+    };
+private:
+    BusIn _pins;
+ 
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SongPlayer.h	Thu Mar 17 21:12:59 2016 +0000
@@ -0,0 +1,41 @@
+#include "mbed.h"
+// new class to play a note on Speaker based on PwmOut class
+class SongPlayer
+{
+public:
+    SongPlayer(PinName pin) : _pin(pin) {
+// _pin(pin) means pass pin to the constructor
+    }
+// class method to play a note based on PwmOut class
+    void PlaySong(float frequency[], float duration[], float volume=1.0) {
+        vol = volume;
+        notecount = 0;
+        _pin.period(1.0/frequency[notecount]);
+        _pin = volume/2.0;
+        noteduration.attach(this,&SongPlayer::nextnote, duration[notecount]);
+        // setup timer to interrupt for next note to play
+        frequencyptr = frequency;
+        durationptr = duration;
+        //returns after first note starts to play
+    }
+    void nextnote();
+private:
+    Timeout noteduration;
+    PwmOut _pin;
+    int notecount;
+    float vol;
+    float * frequencyptr;
+    float * durationptr;
+};
+//Interrupt Routine to play next note
+void SongPlayer::nextnote()
+{
+    _pin = 0.0;
+    notecount++; //setup next note in song
+    if (durationptr[notecount]!=0.0) {
+        _pin.period(1.0/frequencyptr[notecount]);
+        noteduration.attach(this,&SongPlayer::nextnote, durationptr[notecount]);
+        _pin = vol/2.0;
+    } else
+        _pin = 0.0; //turn off on last note
+}
\ No newline at end of file
--- a/main.cpp	Sun Mar 13 17:00:12 2016 +0000
+++ b/main.cpp	Thu Mar 17 21:12:59 2016 +0000
@@ -3,133 +3,132 @@
 #include "SDFileSystem.h"
 #include "uLCD_4DGL.h"
 #include "wave_player.h"
+#include "SongPlayer.h"
+#include "note_public.h"
+#include "player.h"
+#include "Nav_Switch.h"
 #include <stdlib.h>
 #include <time.h>
-#include <mpr121.h>
 #include <string>
 #include <list>
 
-// Create the interrupt receiver object on pin 23
-InterruptIn interrupt(p23);
-// Setup the i2c bus on pins 9 and 10
-I2C i2c(p9, p10);
-// Setup the Mpr121:
-// constructor(i2c object, i2c address of the mpr121)
-Mpr121 mpr121(&i2c, Mpr121::ADD_VSS);
-
 AnalogOut DACout(p18); // used to play sound on speaker
 
 //wave player plays a *.wav file to D/A and a PWM
 wave_player waver(&DACout);
+SongPlayer mySpeaker(p21);
 
 uLCD_4DGL uLCD(p13,p14,p11); // serial tx, serial rx, reset pin;
-Serial pc(USBTX, USBRX);
-
+Serial pc(USBTX, USBRX);    // for debugging
+ 
 SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card setup
 
-Mutex mtx;
+Mutex mtx;  // for rtos
 
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
+Nav_Switch myNav( p26, p29, p28, p30, p27); //pin order on Sparkfun breakout; this is for joystick
  
-// Key hit/release interrupt routine
-void fallInterrupt() {
-  pc.printf("Interrupt routine triggered");
-  int key_code=0;
-  int i=0;
-  int value=mpr121.read(0x00);
-  value +=mpr121.read(0x01)<<8;
-  // LED demo mod
-  i=0;
-  // puts key number out to LEDs for demo
-  
-  for (i=0; i<12; i++) {
-  if (((value>>i)&0x01)==1) key_code=i+1;
-  }
-  pc.printf("key_code value: %i\n",key_code);
-  // USE KEY_CODE HERE TO DETERMINE WHAT TO DO WHEN CERTAIN BUTTONS ARE PRESSED
-  /*
-  while(key_code==1)
-  {
-      //LEFT NOTE
-      pc.printf("Left button pressed\n\r");
-      mtx.lock();
-      uLCD.filled_circle(105,15,4,BLUE);
-      mtx.unlock();
-      break;
-  }
-  while (key_code == 5)
-  {
-      //MIDDLE NOTE
-      pc.printf("Middle button pressed\n\r");
-      mtx.lock();
-      uLCD.filled_circle(65,15,4,BLUE);
-      mtx.unlock();
-      break;
-    }
-  while(key_code == 9)
-  {
-      //RIGHT NOTE
-      pc.printf("Right button pressed\n\r");
-      mtx.lock();
-      uLCD.filled_circle(25,15,4,BLUE);
-      mtx.unlock();
-      break;
-    }
-    */
-      
 
-}
-
-void graphics_thread(void const *argument)
-{
- // GRAPHICS IMPLEMENTATION GOES HERE
-        uLCD.locate(0,0);
-        uLCD.line(0,35,128,35,GREEN);
-        uLCD.line(43,0,43,128,GREEN);
-        uLCD.line(86,0,86,128,GREEN);
-    //while(1){
-    //    
-    //    }
- 
- }
+volatile int currentDirection;      // current direction of the joystick
  
 void controls_thread(void const *argument)
 {
- // CONTROLS CHECKING (JOYSTICK AND TOUCHPAD) GO HERE, PROBABLY SOUND TOO
- //interrupt.fall(&fallInterrupt);
- //interrupt.mode(PullUp);
+ // CONTROLS CHECKING (JOYSTICK) GO HERE
+
+ while(1) {
+        if((myNav & 0x0F) == 14){
+        // Up on joystick
+        currentDirection = 1;
+        }    
+        else if((myNav & 0x0F) == 13){
+        // Down on joystick
+        currentDirection = 2;
+        }
+        else if((myNav & 0x0F) == 11){
+        // Left on joystick
+        currentDirection = 3;
+        }
+        else if((myNav & 0x0F)== 7){
+        // Right on joystick
+        currentDirection = 4;
+        }
+        else
+        currentDirection = 0;
+ //pc.printf("Value of (myNav & 0x0F) is %i\n\r",(myNav & 0x0F)); FOR DEBUGGING PURPOSES
+ //pc.printf("Value of currentDirection is %i\n\r",currentDirection); FOR DEBUGGING PURPOSES
+ Thread::wait(100); // ADJUST THIS TO SET HOW FAST INPUTS FROM JOYSTICK ARE 'CLOCKED' IN
+ }
  }
  
  
 int main() {
-        double lives = 20;
-        // IF MISS NOTE - 2 lives
-        // IF HIT NOTE + 1.2 lives
-        uLCD.locate(0,0);
-        uLCD.line(0,35,128,35,GREEN);
-        uLCD.line(43,0,43,128,GREEN);
-        uLCD.line(86,0,86,128,GREEN);
-        uLCD.circle(108,15,10,WHITE); //LEFT
-        uLCD.filled_circle(108,15,4,WHITE);
-        uLCD.circle(65,15,10,WHITE); //MIDDLE
-        uLCD.filled_circle(65,15,4,WHITE);
-        uLCD.circle(22,15,10,WHITE); //RIGHT
-        uLCD.filled_circle(22,15,4,WHITE);
-        for(int i = 5;i<10;i++)
-        {
-            uLCD.circle(108,15,i,GREEN);
-            uLCD.circle(65,15,i,RED);
-            uLCD.circle(22,15,i,0xFFFF00);
-        }
-        interrupt.fall(&fallInterrupt);
-        interrupt.mode(PullUp);
-  while (1) {
-      //Thread thread1(graphics_thread);
-      //Thread thread2(controls_thread);
-      pc.printf("Program is running...\n\r");
-      wait(5);
+        //FILE *greenNote;
+        //FILE *yellowNote;
+        //FILE *redNote;
+        //greenNote=fopen("/sd/wavfiles/bassDrum.wav","r");
+        //redNote=fopen("/sd/wavfiles/highHat.wav","r");
+        //yellowNote=fopen("/sd/wavfiles/snareDrum.wav","r");
+        
+        //INITIALIZE IMPORTANT VARIABLES
+        float greenNote[2]= {440.0,0.0}; // Tone played when green direction is pressed on joystick
+        float redNote[2] = {261.626,0.0}; // Tone played when red direction is pressed on joystick
+        float yellowNote[2] = {196,0.0}; // Tone played when yellow direction is pressed on joystick
+        float duration[2]= {0.1, 0.0};  // Duration of tone (set to .1 seconds)
+        bool gameOver = false;          // Ends game when this is true
+        Thread thread1(controls_thread); // Thread handling controls (joystick)
+        
+        
+        //INITIALIZE THE PLAYER
+        player_init();
+        //INITIALIZE THE GUI
+        gui_init();
+        
+  while (gameOver==false) {     // Main game loop
+      
+    
+      
+      
+      
+      //START THE NOTE GENERATOR AND KEEP TRACK OF NOTES
+        note_generator();
+        detect_note_miss();
+          if(currentDirection==4) //LEFT ON JOYSTICK
+            {
+                mtx.lock();
+                uLCD.filled_circle(108,128-15,4,BLUE);  //Make center of note area light up blue momentarily to show you are trying to hit a note there
+                mySpeaker.PlaySong(greenNote,duration);   //Play tone when you try to hit a note
+                detect_note_hit(2);                     // Detect note hit in this lane
+                //uLCD.filled_circle(108,128-15,4,WHITE);
+                //pc.printf("detect_note_hit function called on button 1\n\r"); FOR DEBUGGING PURPOSES
+                mtx.unlock();
+            }
+        else if(currentDirection==1) //UP ON JOYSTICK
+            {
+                mtx.lock();
+                uLCD.filled_circle(65,128-15,4,BLUE);   //Make center of note area light up blue momentarily to show you are trying to hit a note there
+                mySpeaker.PlaySong(redNote,duration);   //Play tone when you try to hit a note
+                detect_note_hit(1);                     // Detect note hit in this lane
+                //uLCD.filled_circle(65,128-15,4,WHITE);
+                //pc.printf("detect_note_hit function called on button 2\n\r"); FOR DEBUGGING PURPOSES
+                mtx.unlock();
+            }
+        else if(currentDirection==3) //RIGHT ON JOYSTICK
+            {
+                 mtx.lock();
+                 uLCD.filled_circle(22,128-15,4,BLUE);      //Make center of note area light up blue momentarily to show you are trying to hit a note there
+                 mySpeaker.PlaySong(yellowNote,duration);   //Play tone when you try to hit a note
+                 detect_note_hit(0);                         // Detect note hit in this lane
+                 //uLCD.filled_circle(22,128-15,4,WHITE);
+                 //pc.printf("detect_note_hit function called on button 3\n\r"); FOR DEBUGGING PURPOSES
+                 mtx.unlock();
+            }
+        else if(currentDirection==0) //FINGER COMING OFF KEY
+            {
+                uLCD.filled_circle(22,128-15,4,WHITE);
+                uLCD.filled_circle(65,128-15,4,WHITE);
+                uLCD.filled_circle(108,128-15,4,WHITE);
+            }
+        gameOver = detect_lose_conditions();
       }
+      uLCD.printf("\n\n\n\n\n     Game Over\n\n");            //Displays the game over screen
+      uLCD.printf("   Your Score: %i",get_player_score()); //Displays the score of the player once they have lost
 }
\ No newline at end of file
--- a/mpr121.cpp	Sun Mar 13 17:00:12 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-/*
-Copyright (c) 2011 Anthony Buckton (abuckton [at] blackink [dot} net {dot} au)
- 
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
- 
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
- 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#include <mbed.h>
-#include <sstream>
-#include <string>
-#include <list>
-
-#include <mpr121.h>
-    
-Mpr121::Mpr121(I2C *i2c, Address i2cAddress)
-{
-    this->i2c = i2c;
-    
-    address = i2cAddress;
-           
-    // Configure the MPR121 settings to default
-    this->configureSettings();
-}
-
-   
-void Mpr121::configureSettings()
-{
-    // Put the MPR into setup mode
-    this->write(ELE_CFG,0x00);
-    
-    // Electrode filters for when data is > baseline
-    unsigned char gtBaseline[] = {
-         0x01,  //MHD_R
-         0x01,  //NHD_R 
-         0x00,  //NCL_R
-         0x00   //FDL_R
-         };
-         
-    writeMany(MHD_R,gtBaseline,4);   
-                 
-     // Electrode filters for when data is < baseline   
-     unsigned char ltBaseline[] = {
-        0x01,   //MHD_F
-        0x01,   //NHD_F
-        0xFF,   //NCL_F
-        0x02    //FDL_F
-        };
-        
-    writeMany(MHD_F,ltBaseline,4);
-        
-    // Electrode touch and release thresholds
-    unsigned char electrodeThresholds[] = {
-        E_THR_T, // Touch Threshhold
-        E_THR_R  // Release Threshold
-        };
-
-    for(int i=0; i<12; i++){
-        int result = writeMany((ELE0_T+(i*2)),electrodeThresholds,2);
-    }   
-
-    // Proximity Settings
-    unsigned char proximitySettings[] = {
-        0xff,   //MHD_Prox_R
-        0xff,   //NHD_Prox_R
-        0x00,   //NCL_Prox_R
-        0x00,   //FDL_Prox_R
-        0x01,   //MHD_Prox_F
-        0x01,   //NHD_Prox_F
-        0xFF,   //NCL_Prox_F
-        0xff,   //FDL_Prox_F
-        0x00,   //NHD_Prox_T
-        0x00,   //NCL_Prox_T
-        0x00    //NFD_Prox_T
-        };
-    writeMany(MHDPROXR,proximitySettings,11);
-
-    unsigned char proxThresh[] = {
-        PROX_THR_T, // Touch Threshold
-        PROX_THR_R  // Release Threshold
-        };
-    writeMany(EPROXTTH,proxThresh,2); 
-       
-    this->write(FIL_CFG,0x04);
-    
-    // Set the electrode config to transition to active mode
-    this->write(ELE_CFG,0x0c);
-}
-
-void Mpr121::setElectrodeThreshold(int electrode, unsigned char touch, unsigned char release){
-    
-    if(electrode > 11) return;
-    
-    // Get the current mode
-    unsigned char mode = this->read(ELE_CFG);
-    
-    // Put the MPR into setup mode
-    this->write(ELE_CFG,0x00);
-    
-    // Write the new threshold
-    this->write((ELE0_T+(electrode*2)), touch);
-    this->write((ELE0_T+(electrode*2)+1), release);
-    
-    //Restore the operating mode
-    this->write(ELE_CFG, mode);
-}
-    
-    
-unsigned char Mpr121::read(int key){
-
-    unsigned char data[2];
-    
-    //Start the command
-    i2c->start();
-
-    // Address the target (Write mode)
-    int ack1= i2c->write(address);
-
-    // Set the register key to read
-    int ack2 = i2c->write(key);
-
-    // Re-start for read of data
-    i2c->start();
-
-    // Re-send the target address in read mode
-    int ack3 = i2c->write(address+1);
-
-    // Read in the result
-    data[0] = i2c->read(0); 
-
-    // Reset the bus        
-    i2c->stop();
-
-    return data[0];
-}
-
-
-int Mpr121::write(int key, unsigned char value){
-    
-    //Start the command
-    i2c->start();
-
-    // Address the target (Write mode)
-    int ack1= i2c->write(address);
-
-    // Set the register key to write
-    int ack2 = i2c->write(key);
-
-    // Read in the result
-    int ack3 = i2c->write(value); 
-
-    // Reset the bus        
-    i2c->stop();
-    
-    return (ack1+ack2+ack3)-3;
-}
-
-
-int Mpr121::writeMany(int start, unsigned char* dataSet, int length){
-    //Start the command
-    i2c->start();
-
-    // Address the target (Write mode)
-    int ack= i2c->write(address);
-    if(ack!=1){
-        return -1;
-    }
-    
-    // Set the register key to write
-    ack = i2c->write(start);
-    if(ack!=1){
-        return -1;
-    }
-
-    // Write the date set
-    int count = 0;
-    while(ack==1 && (count < length)){
-        ack = i2c->write(dataSet[count]);
-        count++;
-    } 
-    // Stop the cmd
-    i2c->stop();
-    
-    return count;
-}
-      
-
-bool Mpr121::getProximityMode(){
-    if(this->read(ELE_CFG) > 0x0c)
-        return true;
-    else
-        return false;
-}
-
-void Mpr121::setProximityMode(bool mode){
-    this->write(ELE_CFG,0x00);
-    if(mode){
-        this->write(ELE_CFG,0x30); //Sense proximity from ALL pads
-    } else {
-        this->write(ELE_CFG,0x0c); //Sense touch, all 12 pads active.
-    }
-}
-
-
-int Mpr121::readTouchData(){
-    return this->read(0x00);
-}
\ No newline at end of file
--- a/mpr121.h	Sun Mar 13 17:00:12 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/*
-Copyright (c) 2011 Anthony Buckton (abuckton [at] blackink [dot} net {dot} au)
-
- 
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
- 
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
- 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-   Parts written by Jim Lindblom of Sparkfun
-   Ported to mbed by A.Buckton, Feb 2011
-*/
-
-#ifndef MPR121_H
-#define MPR121_H
-
-//using namespace std;
-
-class Mpr121 
-{
-
-public:
-    // i2c Addresses, bit-shifted
-    enum Address { ADD_VSS = 0xb4,// ADD->VSS = 0x5a <-wiring on Sparkfun board
-                   ADD_VDD = 0xb6,// ADD->VDD = 0x5b
-                   ADD_SCL = 0xb8,// ADD->SDA = 0x5c
-                   ADD_SDA = 0xba // ADD->SCL = 0x5d
-                 };
-
-    // Real initialiser, takes the i2c address of the device.
-    Mpr121(I2C *i2c, Address i2cAddress);
-    
-    bool getProximityMode();
-    
-    void setProximityMode(bool mode);
-    
-    int readTouchData();
-               
-    unsigned char read(int key);
-    
-    int write(int address, unsigned char value);
-    int writeMany(int start, unsigned char* dataSet, int length);
-
-    void setElectrodeThreshold(int electrodeId, unsigned char touchThreshold, unsigned char releaseThreshold);
-        
-protected:
-    // Configures the MPR with standard settings. This is permitted to be overwritten by sub-classes.
-    void configureSettings();
-    
-private:
-    // The I2C bus instance.
-    I2C *i2c;
-
-    // i2c address of this mpr121
-    Address address;
-};
-
-
-// MPR121 Register Defines
-#define    MHD_R        0x2B
-#define    NHD_R        0x2C
-#define    NCL_R        0x2D
-#define    FDL_R        0x2E
-#define    MHD_F        0x2F
-#define    NHD_F        0x30
-#define    NCL_F        0x31
-#define    FDL_F        0x32
-#define    NHDT         0x33
-#define    NCLT         0x34
-#define    FDLT         0x35
-// Proximity sensing controls
-#define    MHDPROXR     0x36
-#define    NHDPROXR     0x37
-#define    NCLPROXR     0x38
-#define    FDLPROXR     0x39
-#define    MHDPROXF     0x3A
-#define    NHDPROXF     0x3B
-#define    NCLPROXF     0x3C
-#define    FDLPROXF     0x3D
-#define    NHDPROXT     0x3E
-#define    NCLPROXT     0x3F
-#define    FDLPROXT     0x40
-// Electrode Touch/Release thresholds
-#define    ELE0_T       0x41
-#define    ELE0_R       0x42
-#define    ELE1_T       0x43
-#define    ELE1_R       0x44
-#define    ELE2_T       0x45
-#define    ELE2_R       0x46
-#define    ELE3_T       0x47
-#define    ELE3_R       0x48
-#define    ELE4_T       0x49
-#define    ELE4_R       0x4A
-#define    ELE5_T       0x4B
-#define    ELE5_R       0x4C
-#define    ELE6_T       0x4D
-#define    ELE6_R       0x4E
-#define    ELE7_T       0x4F
-#define    ELE7_R       0x50
-#define    ELE8_T       0x51
-#define    ELE8_R       0x52
-#define    ELE9_T       0x53
-#define    ELE9_R       0x54
-#define    ELE10_T      0x55
-#define    ELE10_R      0x56
-#define    ELE11_T      0x57
-#define    ELE11_R      0x58
-// Proximity Touch/Release thresholds
-#define    EPROXTTH     0x59
-#define    EPROXRTH     0x5A
-// Debounce configuration
-#define    DEB_CFG      0x5B
-// AFE- Analogue Front End configuration
-#define    AFE_CFG      0x5C 
-// Filter configuration
-#define    FIL_CFG      0x5D
-// Electrode configuration - transistions to "active mode"
-#define    ELE_CFG      0x5E
-
-#define GPIO_CTRL0      0x73
-#define GPIO_CTRL1      0x74
-#define GPIO_DATA       0x75
-#define    GPIO_DIR     0x76
-#define    GPIO_EN      0x77
-#define    GPIO_SET     0x78
-#define GPIO_CLEAR      0x79
-#define GPIO_TOGGLE     0x7A
-// Auto configration registers
-#define    AUTO_CFG_0   0x7B
-#define    AUTO_CFG_U   0x7D
-#define    AUTO_CFG_L   0x7E
-#define    AUTO_CFG_T   0x7F
-
-// Threshold defaults
-// Electrode touch threshold
-#define    E_THR_T      0x0F   
-// Electrode release threshold 
-#define    E_THR_R      0x0A    
-// Prox touch threshold
-#define    PROX_THR_T   0x02
-// Prox release threshold
-#define    PROX_THR_R   0x02
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/note.cpp	Thu Mar 17 21:12:59 2016 +0000
@@ -0,0 +1,141 @@
+#include "note_private.h"
+extern Serial pc;
+
+NOTE note_record[MAX_NUM_NOTE];
+int note_tick=0;            // Internal note tick, used to make the note move at the appropriate speed
+int note_interval = 25;     // The interval on which notes are created. Higher number is more frequent
+int note_speed = 4;         // The speed at which the notes travel
+
+// See the comments in note_public.h
+void note_generator(void){
+    note_tick++;
+    // only create the notes at certain ticks
+    if((note_tick % note_interval)==0 || note_tick==0){
+        note_create();
+    }
+    
+    // update the notes and draw them
+    note_update_position();
+}
+
+// set note speed (default speed is 4)
+void set_note_speed(int speed){
+    if(speed>=1 && speed<=8){  
+        note_speed = speed;
+    }
+}
+
+// set note interval (default interval is 25)
+void set_note_interval(int interval){
+    if(interval>=1 && interval<=100){
+        note_interval = interval;
+    }
+}
+
+// See the comments in note_public.h
+NOTE note_get_info(int index){
+    return note_record[index];
+}
+
+// See the comments in note_public.h
+void note_set_played(int index){
+    note_record[index].status = NOTE_PLAYED;
+    //pc.printf("Note %i has been changed to played",index); FOR DEBUGGING PURPOSES
+}
+
+// See the comments in note_public.h
+void note_set_missed(int index){
+    note_record[index].status = NOTE_MISSED;
+    //pc.printf("Note %i has been changed to missed",index); FOR DEBUGGING PURPOSES
+}
+
+// See the comments in hote_public.h
+void set_note_color(int index, int color){
+    note_record[index].color = color;
+}
+
+/** This function finds an empty slot of note_record, and actives it.
+*/
+void note_create(void){
+    int i,laneIndex;
+    int startingPoints[3] = {22,65,108};    // The three possibilities for the X coordinate of the center of the note
+    int colors[3] = {0xFFFF00,RED,GREEN};   // The three possibilities for the color of the note
+    for(i=0;i<MAX_NUM_NOTE;i++){
+        if(note_record[i].status == NOTE_DEACTIVE){ // Only create new notes in a space where there is a deactive note
+            laneIndex = (rand() % 3);               // Randomly choose which lane to put the note in
+            note_record[i].y = 0;                   // Initialize the note's Y value
+            //each note has its own tick
+            note_record[i].tick = 0;
+            //set a random source for the note
+            note_record[i].source_x = startingPoints[laneIndex];
+            note_record[i].lane = laneIndex;
+            //pc.printf("Note %i is in lane %i \n\r",i,laneIndex); FOR DEBUGGING PURPOSES
+            //set appropriate color for note
+            note_record[i].color = colors[laneIndex];
+            //the note starts at its source
+            note_record[i].x = note_record[i].source_x;
+            //the note must be set to active
+            note_record[i].status = NOTE_ACTIVE;
+            break;
+        }
+    }
+}
+
+/** This function update the position of all notes and draws them
+*/
+void note_update_position(void){
+    int i;
+    double delta_y;
+    //controls how fast the note will move
+    int rate = note_speed * 25;
+    for(i=0;i<MAX_NUM_NOTE;i++){
+        if(note_record[i].status == NOTE_ACTIVE){
+            // update note position
+            delta_y = 200/rate;
+            note_draw(note_record[i], BLACK);                               // Draw over old location of note
+            note_record[i].y = (int)((delta_y*(note_record[i].tick%rate))); // Update the Y value of the note
+            //pc.printf("Note %i has a y value of %i \n\r",i,note_record[i].y); FOR DEBUGGING PURPOSES
+            note_draw(note_record[i], note_record[i].color);                 // Draw note in its new location
+            //update note's internal tick
+            note_record[i].tick++;
+        }       
+        else if((note_record[i].status == NOTE_PLAYED) || (note_record[i].status == NOTE_MISSED)){  // If the status of the note is not active
+            // clear the note off the screen
+            note_draw(note_record[i], BLACK);
+            // we are done with this note, mark as deactive
+            note_record[i].status = NOTE_DEACTIVE;
+            //resets the note's internal tick
+            note_record[i].tick = 0;
+            //resets the note's y position 
+            note_record[i].y = 128;
+        }
+        
+    }
+}
+
+/** This function draws a note.
+    @param note The note to be drawn
+    @param color The color of the note
+*/
+void note_draw(NOTE note, int color){
+    int current_x,current_y;
+    current_x = note.x;
+    current_y = note.y;
+    if(color != BLACK)              // If we arent erasing a note
+    {
+    uLCD.filled_circle(current_x, current_y,4, WHITE);
+    uLCD.circle(current_x, current_y,10,WHITE);
+    for(int i = 5;i<10;i++)
+        {
+            uLCD.circle(current_x,current_y,i,color);
+        }
+    }
+    else
+    {
+        uLCD.filled_circle(current_x,current_y,10,BLACK);
+        
+        }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/note_private.h	Thu Mar 17 21:12:59 2016 +0000
@@ -0,0 +1,41 @@
+/* Gatech ECE2035 2014 FALL missile command
+ * Copyright (c) 2014 Gatech ECE2035
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef NOTE_PRIVATE_H
+#define NOTE_PRIVATE_H
+
+#include "mbed.h"
+#include "uLCD_4DGL.h"
+#include "note_public.h"
+extern uLCD_4DGL uLCD;
+
+//==== [private settings] ====
+
+//==== [private type] ====
+
+
+//==== [private function] ====
+void note_create(void);
+void note_draw(NOTE note, int color);
+
+#endif //NOTE_PRIVATE_H
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/note_public.h	Thu Mar 17 21:12:59 2016 +0000
@@ -0,0 +1,66 @@
+#ifndef NOTE_PUBLIC_H
+#define NOTE_PUBLIC_H
+
+//The note status
+typedef enum {
+    NOTE_MISSED=3, //note has been missed
+    NOTE_PLAYED=2,//note has been played
+    NOTE_ACTIVE=1,//note is active
+    NOTE_DEACTIVE=0//note is no longer active
+} NOTE_STATUS;
+
+// The structure to store the information of a note
+typedef struct {
+    int x;                   // The x-coordinate of note's current position
+    int y;                   // The y-coordinate of note's current position
+    double source_x;           // The x-coordinate of the note's origin
+    int tick;                  // The note's internal tick
+    int color;                  // The note's color
+    int lane;                   // Which lane is the note in
+    NOTE_STATUS status;   // The note status, see NOTE_STATUS
+} NOTE;
+
+#define MAX_NUM_NOTE 5
+
+/** This function draws the notes onto the screen
+    Call note_generator() repeatedly in game-loop
+*/
+void note_generator(void);
+
+/** The function set the status of note to be NOTE_PLAYED
+    @param index The index in note_record. It must be smaller than MAX_NUM_NOTE.
+*/
+void note_set_played(int index);
+
+/** The function sets the status of note to be NOTE_MISSED
+    @param index The index in note_record. It must be smaller than MAX_NUM_NOTE.
+*/
+
+void note_set_missed(int index);
+
+/** Get the information of a note
+    @param index The index in note_record. It must be smaller than MAX_NUM_NOTE.
+    @return The structure of note information
+*/
+
+NOTE note_get_info(int index);
+
+/** Set the speed of notes, Speed has range of 1-8 with 1 being fastest and 8 being slowest
+*/
+void set_note_speed(int speed);
+
+/** Set the interval that the notes occur, interval has range of 1-100 with 1 being created in
+    very quick succession and 100 being created very slowly after one another
+*/
+void set_note_interval(int interval);
+
+/** The function set the color of note to be color
+    @param color The color in note_record.
+*/
+
+void set_note_color(int index, int color);
+
+//The function updates the position of the notes on the board
+void note_update_position(void);
+
+#endif //NOTE_PUBLIC_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/player.cpp	Thu Mar 17 21:12:59 2016 +0000
@@ -0,0 +1,128 @@
+#include "mbed.h"
+#include "uLCD_4DGL.h"
+#include "player.h"
+#include "note_public.h"
+#include <math.h>
+
+extern int note_speed;  // Note speed
+extern int note_interval; // Interval on which notes are created
+extern uLCD_4DGL uLCD;  // LCD display
+extern Serial pc;       // For debugging 
+
+PLAYER CURRENT_PLAYER;  // Player object
+NOTE note_array[MAX_NUM_NOTE];  // Structure containing the Note objects
+
+void player_init() {            // Initializes the player object with default values
+    CURRENT_PLAYER.score = 0;
+    CURRENT_PLAYER.lives = 20;
+    CURRENT_PLAYER.status = ALIVE;
+}
+
+void gui_init() {               // Draws the GUI on the LCD
+        uLCD.locate(0,0);
+        uLCD.line(43,0,43,128,GREEN);           //Lines separating the lanes
+        uLCD.line(86,0,86,128,GREEN);           //Lines separating the lanes
+        uLCD.circle(108,128-15,10,WHITE);       //Left note
+        uLCD.filled_circle(108,128-15,4,WHITE); //Left note
+        uLCD.circle(65,128-15,10,WHITE);        //Middle note
+        uLCD.filled_circle(65,128-15,4,WHITE);  //Middle note
+        uLCD.circle(22,128-15,10,WHITE);        //Right note
+        uLCD.filled_circle(22,128-15,4,WHITE);  //Right note
+        for(int i = 5;i<10;i++)                 //Loop used to fill in the notes with appropriate color
+        {
+            uLCD.circle(108,128-15,i,GREEN);
+            uLCD.circle(65,128-15,i,RED);
+            uLCD.circle(22,128-15,i,0xFFFF00);
+        }
+}
+
+double get_player_lives() {                     // Gets number of lives player has remaining
+    
+    return(CURRENT_PLAYER.lives); 
+}
+
+int get_player_score() {                        // Gets score of player
+    pc.printf("Player's Score: %i\n\r",CURRENT_PLAYER.score);
+    return(CURRENT_PLAYER.score);
+    }
+
+void update_values(){                           // Updates the structure containing the Note object data
+    for(int index=0;index<MAX_NUM_NOTE;index++)
+        {
+        note_array[index]=note_get_info(index);
+        //pc.printf("The y value of note %i is %d\n\r",index,note_array[index].y); FOR DEBUGGING PURPOSES
+        }
+}
+
+bool detect_lose_conditions(){                  // Detects when the game is over by checking the player's lives
+    bool game_over = false;
+    if(CURRENT_PLAYER.lives <= 0){
+        game_over=true;
+    }
+    return(game_over);
+}
+
+float get_distance(int index){                      // Detects distance between notes in the lane and the note registration zone
+    float distance = 0;
+    int y2 = note_array[index].y;
+    distance = abs(y2-(128.0-15.0));                // 113.0 is the location of the center of the registration zone in the y direction
+    //pc.printf("The Y value for note %i is %i \n\r",index,y2);                           FOR DEBUGGING PURPOSES
+    //pc.printf("The distance between the note and the checkpoint is: %f\n\r",distance);  FOR DEBUGGING PURPOSES
+    return (distance);
+    }
+    
+bool detect_note_miss(){                            // Detects when notes go past the checkpoint, also will check to see if player has lost all their lives
+        bool gameOver = false;                      // Assume the player has not lost the game yet
+        update_values();                            // Make sure the location data for all notes is current
+        for(int index=0;index<5;index++){
+                if((note_array[index].y >=(128-10)) && (note_array[index].y != 128))    // If the note has passed the registration/checkpoint zone
+                    { 
+                        note_set_missed(index);                                                 // Set note as missed
+                        note_update_position();                                                 // Update its status 
+                        gui_init();                                                             // Redraw the GUI 
+                        CURRENT_PLAYER.lives -= 2;                                              // Lose 2 lives for a missed note
+                        gameOver = detect_lose_conditions();                                    // Determine if this has lost the player the game
+                        //pc.printf("Note went past registration zone!\n\r");                   // FOR DEBUGGING PURPOSES
+                        //break;                                                                  
+                    }
+        }
+        return(gameOver);
+}
+                
+bool detect_note_hit(int lane){                     // Detects when a note is hit, is called whenever a direction is input on the joystick
+        bool gameOver = false;                      // Assume player has not lost the game yet
+        update_values();                            // Make sure the location data for all notes is current
+        int minDistance = 128;                      // We only want to look at the closest note in the lane we care about
+        int indexToCheck;                           // We only need to look at one note per function call
+        for(int i=0;i<5;i++)
+        {
+            //pc.printf("Checking note %i, current lane: %i \n\r",i,note_array[i].lane); FOR DEBUGGING PURPOSES
+            if(note_array[i].lane+1 == (lane+1))
+            {
+                if(get_distance(i) < minDistance)
+                {
+                    minDistance = get_distance(i);  // Make sure we get the note with the least distance to the checkpoint
+                    indexToCheck=i;                 // This is the note we want to check if we hit
+                }
+            }
+        }
+        //pc.printf("Found a match!"); FOR DEBUGGING PURPOSES
+        double distance = get_distance(indexToCheck);  // Check distance of selected note from checkpoint zone
+        if(distance <= 4.0){                // If note is close enough, proceed
+        note_set_played(indexToCheck);                 // Set note status to NOTE_PLAYED
+        note_update_position();             // Update note position
+        gui_init();                         // Redraw the GUI
+        CURRENT_PLAYER.lives += 1.2;        // Player gets 1.2 lives back for each note hit
+        CURRENT_PLAYER.score += 1.0;        // Player gets 1 point for every note hit
+        //pc.printf("Note hit!\n\r");       FOR DEBUGGING PURPOSES
+        }
+        else if(distance > 4)               // If note is not close enough, proceed with miss protocol
+        {             
+            CURRENT_PLAYER.lives -=1.0;         // If a note is missed in this manner, player loses 1 life
+            gameOver = detect_lose_conditions();// Check to see if this has caused the player to lose all their lives and the game
+            //pc.printf("Note missed...\n\r");  DEBUGGING PURPOSES
+        }
+        return(gameOver);
+}
+
+                    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/player.h	Thu Mar 17 21:12:59 2016 +0000
@@ -0,0 +1,50 @@
+
+// Template of player header file
+#ifndef PLAYER_H
+#define PLAYER_H
+
+typedef enum {
+    ALIVE=1,      // The game screen will be shown 
+    DEAD=0   // The game screen will not be shown
+} PLAYER_STATUS;
+
+typedef struct {
+    int score;      // Score of the player
+    double lives;      // Number of remaining lives
+    PLAYER_STATUS status;  // See enum PLAYER_STATUS
+} PLAYER;
+
+#define MAX_NUM_PLAYER 1    // There can only be a single player
+
+// The function returns the number of lives the player has remaining
+double get_player_lives();
+
+// The function returns the score of the player
+int get_player_score();
+
+// Initializes the player object
+void player_init();
+
+// Initializes/Draws the GUI on the LCD
+void gui_init();
+
+/** The function gets the distance from the checkpoint/registration zone to the nearest note in the lane specified by index
+    @param index The index in the structure containing the note objects of the note to be checked
+*/
+float get_distance(int index);
+
+// Function to make sure all the Note objects in the structure containing the notes is up to date
+void update_values();
+
+// The function returns a boolean stating whether the player has lost the game or not. Function also checks to see if a note has passed the registration zone
+bool detect_note_miss();
+
+/** The function detects whether a note is close enough to the checkpoint to be a hit or not. Returns a boolean to determine if the player has lost all their lives as well.
+    @param index The lane in which the notes are to be looked for.
+*/
+bool detect_note_hit(int index);
+
+// The function determines whether or not the player has lost all their lives or not. Returns a boolean which describes whether the player has lost or not.
+bool detect_lose_conditions();
+
+#endif //PLAYER_H
\ No newline at end of file