Simon: A Memory Game

Dependencies:   4DGL-uLCD-SE PinDetect mbed

Files at this revision

API Documentation at this revision

Comitter:
cmathis
Date:
Tue Oct 21 04:25:07 2014 +0000
Child:
1:cd222334a4fe
Commit message:
initial revision

Changed in this revision

4DGL-uLCD-SE.lib Show annotated file Show diff for this revision Revisions of this file
PinDetect.lib Show annotated file Show diff for this revision Revisions of this file
Speaker.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
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/4DGL-uLCD-SE.lib	Tue Oct 21 04:25:07 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#e39a44de229a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PinDetect.lib	Tue Oct 21 04:25:07 2014 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/AjK/code/PinDetect/#cb3afc45028b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Speaker.h	Tue Oct 21 04:25:07 2014 +0000
@@ -0,0 +1,20 @@
+#include "mbed.h"
+
+class Speaker
+{
+public:
+    Speaker(PinName pin) : _pin(pin) {
+// _pin(pin) means pass pin to the Speaker Constructor
+    }
+// class method to play a note based on PwmOut class
+    void PlayNote(float frequency, float duration, float volume) {
+        _pin.period(1.0/frequency);
+        _pin = volume/2.0;
+        wait(duration);
+        _pin = 0.0;
+    }
+ 
+private:
+// sets up specified pin for PWM using PwmOut class 
+    PwmOut _pin;
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Oct 21 04:25:07 2014 +0000
@@ -0,0 +1,383 @@
+/*********************************/
+// ECE 4180 Lab 4
+// Colton Mathis, Taylor Hawley
+/*********************************/
+
+#include "mbed.h"
+#include "uLCD_4DGL.h"
+#include "PinDetect.h"
+#include "Speaker.h"
+
+// pushbutton interrupts with debounce
+PinDetect pb1(p25, PullUp);
+PinDetect pb2(p26, PullUp);
+PinDetect pb3(p23, PullUp);
+PinDetect pb4(p24, PullUp);
+
+// four LED outputs
+DigitalOut led1(p7);
+DigitalOut led2(p9);
+DigitalOut led3(p8);
+DigitalOut led4(p6);
+
+// speaker object
+Speaker mySpeaker(p21);
+
+// LCD object
+uLCD_4DGL uLCD(p28, p27, p29);
+
+// analog input for seeding rand() function
+AnalogIn adcReading(p18);
+
+// variable declarations
+int levels[16];
+int levelsIndex;
+int level;
+int buttonPressed;
+int buttonPushes;
+int failed;
+int start = 1;
+int randomSeed;
+
+// function prototypes
+void enableInterrupts();
+void disableInterrupts();
+void startGame();
+void setLevels();
+void playSequence();
+void pushOne();
+void pushTwo();
+void pushThree();
+void pushFour();
+void failedGame();
+void endGame();
+
+int main() {
+    
+    // read in value from analog input as unsigned short instead of float
+    // and seed the rand() function with the value
+    randomSeed = adcReading.read_u16();
+    srand(randomSeed);
+    uLCD.baudrate(3000000);
+    
+    while(1) {
+        
+        // only initialize these variables at the start of each game
+        if(start == 1){
+            failed = 0;
+            level = 0;
+            buttonPressed = 0;
+            buttonPushes = 0;
+            levelsIndex = 0;
+            startGame();
+        }
+        start = 0;
+        
+        // generate and play the sequence of LEDs (and sounds) that the player copies
+        setLevels();
+        playSequence();
+        
+        // enable the four pushbutton interrupts
+        enableInterrupts();
+        
+        // wait in this loop until the user pushes buttons the same number of times as the current level
+        // or until the user has pushed an incorrect button
+        while(buttonPushes != level && failed == 0){
+            wait(0.5);
+        }
+        
+        // if the user has failed, disable the pushbutton interrupts, notify the user that they failed,
+        // and then set start=1 so that the game restarts from level 1
+        if(failed == 1){
+            disableInterrupts();
+            failedGame(); 
+            start = 1; 
+        }
+        
+        // if the user has completed all of the levels without failing, disable the pushbutton interrupts,
+        // notify the user that they won, and set start=1 so that the game restarts from level 1
+        if(level == 5 && failed == 0){
+            disableInterrupts();
+            endGame();
+            start = 1;
+        }
+        
+        // if the user has not failed or completed all of the levels, disable the interrupts and continue
+        disableInterrupts();
+        
+        // set buttonpushes=0 to record the button presses for the next level
+        buttonPushes = 0;
+        
+        // wait a short amount of time before starting the next game
+        if(start==1){
+            wait(2);
+        }
+        
+    }
+    
+}
+
+
+void enableInterrupts(){
+    
+    // set the four pushbutton interrupts to trigger on a falling edge
+    pb1.attach_deasserted(&pushOne);
+    pb2.attach_deasserted(&pushTwo);
+    pb3.attach_deasserted(&pushThree);
+    pb4.attach_deasserted(&pushFour);
+    
+    // start the four interrupts (default sample frequency is 20ms)
+    pb1.setSampleFrequency();
+    pb2.setSampleFrequency();
+    pb3.setSampleFrequency();
+    pb4.setSampleFrequency();
+    
+}
+
+
+void disableInterrupts(){
+    
+    // disable four interrupts by setting their service routine to NULL pointer
+    pb1.attach_deasserted(NULL);
+    pb2.attach_deasserted(NULL);
+    pb3.attach_deasserted(NULL);
+    pb4.attach_deasserted(NULL);
+
+}
+
+// this function is called at the beginning of the game
+void startGame(){
+    
+    uLCD.cls();
+    uLCD.display_control(PORTRAIT);
+//    uLCD.media_init(); // initialize uSD card
+//    uLCD.set_sector_address(0x20,0xFF);  // address of font file
+//    uLCD.set_font(MEDIAFONT);  // load new font from uSD
+    uLCD.color(BLUE);
+    uLCD.text_width(2);
+    uLCD.text_height(2);
+    uLCD.locate(2, 3);
+    uLCD.printf("SIMON");
+    
+    led1 = 1;
+    uLCD.filled_rectangle(0, 0, 63, 40, 0x00CC00);
+    wait(0.5);
+    led1 = 0;
+    uLCD.filled_rectangle(0, 0, 63, 40, 0x000000);
+    
+    led2 = 1;
+    uLCD.filled_rectangle(64, 0, 127, 40, 0xFF0000);
+    wait(0.5);
+    led2 = 0;
+    uLCD.filled_rectangle(64, 0, 127, 40, 0x000000);
+    
+    led3 = 1;
+    uLCD.filled_rectangle(64, 87, 127, 127, 0x0000FF);
+    wait(0.5);
+    led3 = 0;
+    uLCD.filled_rectangle(64, 87, 127, 127, 0x000000);
+    
+    led4 = 1;
+    uLCD.filled_rectangle(0, 87, 63, 127, 0xCCCC00);
+    wait(0.5);
+    led4 = 0;
+    uLCD.filled_rectangle(0, 87, 63, 127, 0x000000);
+    
+    wait(2);
+    
+    uLCD.cls();
+
+}
+
+
+void setLevels(){
+    
+    // "levels" array is a sequence of numbers 1-4 that determines which LEDs will light up
+    // during a given level --- grows by 1 value each level
+    level++;
+    levels[level-1] = rand()%4 + 1;
+    
+    uLCD.color(BLUE);
+    uLCD.text_width(2);
+    uLCD.text_height(2);
+    uLCD.locate(2, 2);
+    uLCD.printf("Level");
+    uLCD.locate(4, 4);
+    uLCD.printf("%d", level);
+    wait(1);
+    
+}
+
+
+void playSequence(){
+
+    // play the sequence of LEDs defined in the "levels" array along with the corresponding notes
+    for(int i = 0; i < level; i++){
+        switch(levels[i]){
+            case 1:
+                led1 = 1;
+                mySpeaker.PlayNote(659.26, 0.50, 0.2);
+                led1 = 0;
+                wait(0.025);
+                break;
+            case 2:
+                led2 = 1;
+                mySpeaker.PlayNote(554.00, 0.50, 0.2);
+                led2 = 0;
+                wait(0.025);
+                break;
+            case 3:
+                led3 = 1;
+                mySpeaker.PlayNote(440.00, 0.50, 0.2);
+                led3 = 0;
+                wait(0.025);
+                break;
+            case 4:
+                led4 = 1;
+                mySpeaker.PlayNote(329.63, 0.50, 0.2);
+                led4 = 0;
+                wait(0.025);
+                break;
+            default:
+                while(1){
+                    led1 = !led1;
+                    wait(0.5);
+                }
+        }   
+    }   
+   
+}
+
+// ISR for pushbutton 1 interrupt
+void pushOne(){
+    
+    buttonPushes++;
+    
+    led1 = 1;
+    mySpeaker.PlayNote(659.26, 0.25, 0.2);
+    led1 = 0;
+    
+    if(levels[buttonPushes-1] != 1){
+        failed = 1;   
+    }
+    
+}
+
+// ISR for pushbutton 2 interrupt
+void pushTwo(){
+    
+    buttonPushes++;
+    
+    led2 = 1;
+    mySpeaker.PlayNote(554.00, 0.25, 0.2);
+    led2 = 0;
+    
+    if(levels[buttonPushes-1] != 2){
+        failed = 1;   
+    }
+    
+}
+
+// ISR for pushbutton 3 interrupt
+void pushThree(){
+    
+    buttonPushes++;
+    
+    led3 = 1;
+    mySpeaker.PlayNote(440.00, 0.25, 0.2);
+    led3 = 0;
+    
+    if(levels[buttonPushes-1] != 3){
+        failed = 1;   
+    }
+    
+}
+
+// ISR for pushbutton 4 interrupt
+void pushFour(){
+    
+    buttonPushes++;
+    
+    led4 = 1;
+    mySpeaker.PlayNote(329.63, 0.25, 0.2);
+    led4 = 0;
+    
+    if(levels[buttonPushes-1] != 4){
+        failed = 1;   
+    }
+    
+}
+
+// this function is called when the user fails the game
+void failedGame(){
+    
+    uLCD.cls();
+    uLCD.color(RED);
+    uLCD.text_width(2);
+    uLCD.text_height(2);
+    uLCD.locate(2, 2);
+    uLCD.printf("Game");
+    uLCD.locate(2, 4);
+    uLCD.printf("Over");
+    
+    
+    mySpeaker.PlayNote(147.00, 0.60, 1);
+    mySpeaker.PlayNote(139.00, 0.60, 1);
+    mySpeaker.PlayNote(131.00, 0.60, 1);
+    mySpeaker.PlayNote(123.00, 1.60, 1);
+    
+}
+
+// this function is called if the user completes all levels
+void endGame(){
+    
+    uLCD.cls();
+    uLCD.color(GREEN);
+    uLCD.text_width(2);
+    uLCD.text_height(2);
+    uLCD.locate(2, 2);
+    uLCD.printf("YOU");
+    uLCD.locate(2, 4);
+    uLCD.printf("WIN!");
+    
+    int time = 0.01;
+    
+    mySpeaker.PlayNote(392.00, 0.33, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(349.23, 0.17, 0.2);
+    wait(time);
+    
+    mySpeaker.PlayNote(311.13, 0.33, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(311.13, 0.17, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(311.13, 0.33, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(349.23, 0.17, 0.2);
+    wait(time);
+    
+    mySpeaker.PlayNote(392.00, 0.33, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(392.00, 0.17, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(392.00, 0.165, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(349.23, 0.165, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(311.13, 0.17, 0.2);
+    wait(time);
+    
+    mySpeaker.PlayNote(349.23, 0.165, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(392.00, 0.165, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(349.23, 0.17, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(311.13, 0.33, 0.2);
+    wait(time);
+    mySpeaker.PlayNote(293.66, 0.17, 0.2);
+    wait(time);
+    
+    mySpeaker.PlayNote(311.13, 0.5, 0.2);
+    
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Oct 21 04:25:07 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1
\ No newline at end of file