Leann Mayberry / Mbed 2 deprecated 4180MusicPlayGame_LeannMayberry

Dependencies:   Speaker mbed mbed-rtos 4DGL-uLCD-SE PinDetect

Revision:
1:e84293b09274
Parent:
0:9439ccb44422
diff -r 9439ccb44422 -r e84293b09274 main.cpp
--- a/main.cpp	Fri Nov 28 18:00:06 2014 +0000
+++ b/main.cpp	Thu Apr 30 20:57:15 2020 +0000
@@ -1,75 +1,496 @@
 #include "mbed.h"
 #include "rtos.h"
+#include "uLCD_4DGL.h"
+#include "Speaker.h"
+#include "SongPlayer.h"
 DigitalOut myled(LED1);
 PwmOut myled2(LED2);
 PwmOut myled3(LED3);
 PwmOut myled4(LED4);
 
-inline float random_number(){
-    return (rand()/(float(RAND_MAX)));
-}
+uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin;
+
+AnalogIn touchg(p17);
+AnalogIn touchr(p16);
+AnalogIn touchb(p15);
+
+float gVal = 0.0;
+float rVal = 0.0;
+float bVal = 0.0;
+
+Mutex stdio_mutex;
+
+Speaker mySpeaker(p21);
+
+SongPlayer mySpeakerSP(p21);
+
+//States: {STARTSCREEN = 0, MENU = 1, SONG1 = 2, SONG2 = 3, LISTENMODE = 4};
+int currState = 0;
+int prevState = 0;
+int selected = 1;
+
+float score = 10.0;
+int numPlayedS1 = 0;
+int numPlayedS2 = 0;
+int passedPlayS1 = 0;
+int passedPlayS2 = 0;
+
+float t = 2.5; // tempo controller
+
+DigitalIn pbL(p9);
+DigitalIn pbR(p8);
+
+
+
+float ramblinFirst[] = {783.991, 698.456,622.254,622.254,622.254,698.456,
+                        783.991,783.991,783.991,698.456,622.254,698.456,
+                        698.456,698.456,622.254,587.330,622.254};
+float ramblinSecond[] = {1.0/t,0.5/t,0.9/t,0.4/t,1.0/t,0.5/t,0.9/t,
+                        0.4/t,0.5/t,0.5/t,0.5/t,0.4/t,0.4/t,
+                        0.5/t,1.0/t,0.5/t,2.5/t};
+float ramblinThird[] = {0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,
+                        0.1,0.1,0.1,0.1,0.1,0.1,0.1};
+
+//int ramblinRows[24];
+//int imagineRows[70];
+//
+//int ramblinColors[24];
+//int imagineColors[70];
+
+class MovingNotes
+{
+protected:
+  int y_pos;
+  int x_pos;
+  int moving;
+  float freq;
+  float dur;
+  float val;
+public:
+  void setStart(int h) {y_pos = h;}
+  void setWidth (int w) {x_pos = w;}
+  void setMoving (int m) {moving = m;}
+  void setFreq(float f) {freq = f;}
+  void setDur (float d) {dur = d;}
+  void setVal (float v) {val = v;}
+ // int getFreq() {return freq;}
+//  int getDur() {return dur;}
+//  int getVal() {return val;}
+  virtual void draw()= 0; 
+  virtual void update(){}
+};
+
+MovingNotes * ramb_ptr[17];
+
+class redNotes: public MovingNotes
+{
+    virtual void draw()
+    {
+        uLCD.filled_circle(x_pos, y_pos, 10, RED);
+    }
+    virtual void update() { 
+        if (moving == 1) { 
+            gVal = touchg.read();
+            rVal = touchr.read();
+            bVal = touchb.read();
+            if (x_pos == 18 && y_pos > 90 && y_pos < 144 && gVal >0.5f) {
+                score++;
+                mySpeaker.PlayNote(freq,dur,val);
+            } else if (x_pos == 64 && y_pos > 90 && y_pos < 144 && rVal >0.5f) {
+                score++;
+                mySpeaker.PlayNote(freq,dur,val);
+            } else if (x_pos == 110 && y_pos > 90 && y_pos < 144 && bVal >0.5f) {
+                score++;
+                mySpeaker.PlayNote(freq,dur,val);
+            } 
+            if (y_pos < 144) {
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 11;
+                uLCD.filled_circle(x_pos, y_pos, 10, RED);
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 11;
+                uLCD.filled_circle(x_pos, y_pos, 10, RED);
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 11;
+                uLCD.filled_circle(x_pos, y_pos, 10, RED);
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 11;
+                uLCD.filled_circle(x_pos, y_pos, 10, RED);
+            } else {
+                setMoving(0);
+                y_pos = 35;
+            }
+        }
+    }
+};
+
+class blueNotes: public MovingNotes
+{
+    virtual void draw()
+    {
+        uLCD.filled_circle(x_pos, y_pos, 10, BLUE);
+    }
+    virtual void update() { 
+        if (moving == 1) { 
+            gVal = touchg.read();
+            rVal = touchr.read();
+            bVal = touchb.read();
+            if (x_pos == 18 && y_pos > 90 && y_pos < 144 && gVal >0.5f) {
+                score++;
+                mySpeaker.PlayNote(freq,dur,val);
+            } else if (x_pos == 64 && y_pos > 90 && y_pos < 144 && rVal >0.5f) {
+                score++;
+                mySpeaker.PlayNote(freq,dur,val);
+            } else if (x_pos == 110 && y_pos > 90 && y_pos < 144 && bVal >0.5f) {
+                score++;
+                mySpeaker.PlayNote(freq,dur,val);
+            } 
+            if (y_pos < 144) {
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 9;
+                uLCD.filled_circle(x_pos, y_pos, 10, BLUE);
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 9;
+                uLCD.filled_circle(x_pos, y_pos, 10, BLUE);
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 9;
+                uLCD.filled_circle(x_pos, y_pos, 10, BLUE);
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 9;
+                uLCD.filled_circle(x_pos, y_pos, 10, BLUE);
+            } else {
+                setMoving(0);
+                y_pos = 35;
+            }
+        }
+    }
+};
+
+class greenNotes: public MovingNotes
+{
+    virtual void draw()
+    {
+        uLCD.filled_circle(x_pos, y_pos, 10, GREEN);
+    }
+    virtual void update() { 
+        if (moving == 1) { 
+            gVal = touchg.read();
+            rVal = touchr.read();
+            bVal = touchb.read();
+            if (x_pos == 18 && y_pos > 90 && y_pos < 144 && gVal >0.5f) {
+                score++;
+                mySpeaker.PlayNote(freq,dur,val);
+            } else if (x_pos == 64 && y_pos > 90 && y_pos < 144 && rVal >0.5f) {
+                score++;
+                mySpeaker.PlayNote(freq,dur,val);
+            } else if (x_pos == 110 && y_pos > 90 && y_pos < 144 && bVal >0.5f) {
+                score++;
+                mySpeaker.PlayNote(freq,dur,val);
+            } 
+            if (y_pos < 144) {
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 18;
+                uLCD.filled_circle(x_pos, y_pos, 10, GREEN);
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 18;
+                uLCD.filled_circle(x_pos, y_pos, 10, GREEN);
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 18;
+                uLCD.filled_circle(x_pos, y_pos, 10, GREEN);
+                Thread::wait(1000.00*0.1);
+                uLCD.filled_circle(x_pos, y_pos, 10, BLACK);
+                y_pos += 18;
+                uLCD.filled_circle(x_pos, y_pos, 10, GREEN);
+            } else {
+                setMoving(0);
+                y_pos = 35;
+            }
+        }
+    }
+};
  
 void beacon(void const *args){
     while(1) {
-        //LED warm up effect using PWM
-        for(int i=0; i<50; i++) {
-            myled2 = i/50.0;
-            Thread::wait(1000.0*0.02);
+        if (!pbL) {
+            if (currState == 0) {
+                prevState = 0;
+                currState = 1;
+                Thread::wait(1000.00*0.5);
+            } else if (currState == 1) {
+                if (selected == 1) {
+                    printf("play ramblin wreck");
+                    currState = 2;
+                    prevState = 1;
+                    Thread::wait(1000.00*0.5);
+                } else if (selected == 2) {
+                    printf("play other song");
+                    currState = 3;
+                    prevState = 1;
+                    Thread::wait(1000.00*0.5);
+                } else if (selected == 3) {
+                    currState = 4;
+                    prevState = 1;
+                    Thread::wait(1000.00*0.5);
+                } else if (selected == 4) {
+                    currState = 0;
+                    prevState = 1;
+                    Thread::wait(1000.00*0.5);
+                }
+            } else if (currState == 2 || currState == 3 || currState == 4) {
+                score = 0;
+                numPlayedS1 = 0;
+                numPlayedS2 = 0;
+                currState = 1;
+                Thread::wait(1000.00*0.5);
+            }
+            printf("pbL  ");
+            printf("currState: %d", currState);
+            printf(" prevstate: %d\n", prevState);
+        } else if (!pbR) {
+            
+            if (currState == 0) {
+                prevState = 0;
+                currState = 1;
+                Thread::wait(1000.00*0.2);
+            } else if (currState == 1) {
+                selected++;
+                if (selected >= 5) {
+                    selected = 1;
+                }
+                Thread::wait(1000.00*0.5);
+            }
+            printf("pbR  ");
+            printf("currState: %d", currState);
+            printf(" prevstate: %d\n", prevState);
         }
-        //LED at full brightness level
-        myled2 = 1.0;
-        Thread::wait(1000.0*0.25);
-        //LED cool down effect using PWM
-        for(int i=49; i>0; i--) {
-            myled2 = i/50.0;
-            Thread::wait(1000.0*0.02);
-        }
-        //LED off
-        myled2 = 0.0;
-        Thread::wait(1000.0*1.5);
     }
 }
 void welding(void const *args) {
-    float x = 0.0;
     while(1) {
-        //get a new random number for PWM
-        x = random_number();
-        //add some exponential brightness scaling
-        //for more of a fast flash effect
-        myled3 = x*x*x;
-        //fast update rate for welding flashes
-        Thread::wait(1000.0*0.02);
-        //add a random pause between welds
-        if (random_number()>0.9925) {
-            myled3 = 0.0;
-            Thread::wait(1000.0*4.0*random_number());
+       if (currState == 4) { // Listen to RW
+            stdio_mutex.lock();
+            Thread::wait(1000.00*1);
+            if (prevState != 4) {
+                uLCD.cls();
+            }
+            mySpeaker.PlayNote(783.991,1.0/t,0.1); // G
+            mySpeaker.PlayNote(698.456,0.5/t,0.1); //F
+            mySpeaker.PlayNote(622.254,0.9/t,0.1); //E flat
+            mySpeaker.PlayNote(0.0,0.1/t,0.0); //separation between the same notes
+            mySpeaker.PlayNote(622.254,0.4/t,0.1); //E flat
+            mySpeaker.PlayNote(0.0,0.1/t,0.0);
+            mySpeaker.PlayNote(622.254,1.0/t,0.1); //E flat
+            mySpeaker.PlayNote(698.456,0.5/t,0.1); //F
+            mySpeaker.PlayNote(783.991,0.9/t,0.1); // G
+            mySpeaker.PlayNote(0.0,0.1/t,0.0);
+            mySpeaker.PlayNote(783.991,0.4/t,0.1); // G
+            mySpeaker.PlayNote(0.0,0.1/t,0.0);
+            mySpeaker.PlayNote(783.991,0.5/t,0.1); // G
+            mySpeaker.PlayNote(698.456,0.5/t,0.1); //F
+            mySpeaker.PlayNote(622.254,0.5/t,0.1); //E flat
+            mySpeaker.PlayNote(698.456,0.4/t,0.1); //F
+            mySpeaker.PlayNote(0.0,0.1/t,0.0);
+            mySpeaker.PlayNote(698.456,0.4/t,0.1); //F
+            mySpeaker.PlayNote(0.0,0.1/t,0.0);
+            mySpeaker.PlayNote(698.456,0.5/t,0.1); //F
+            mySpeaker.PlayNote(622.254,1.0/t,0.1); //E flat
+            mySpeaker.PlayNote(587.330,0.5/t,0.1); //D
+            mySpeaker.PlayNote(622.254,2.5/t,0.1); //E flat
+            mySpeaker.PlayNote(0.0,0.5/t,0.0); //rest then repeat
+            Thread::wait(1000.00*0.5);
+            prevState = 4;
+            stdio_mutex.unlock();
+            break;
+        } else if (currState == 2) { //Playing Ramblin Wreck
+            stdio_mutex.lock();
+            if (prevState != 2) {
+                uLCD.text_width(1); 
+                uLCD.text_height(2);
+                uLCD.locate(5,5);
+                uLCD.color(RED);
+                uLCD.printf("3 ");
+                Thread::wait(1000.00*0.4);
+                uLCD.printf("2 ");
+                Thread::wait(1000.00*0.4);
+                uLCD.printf("1 ");
+                Thread::wait(1000.00*0.4);
+                uLCD.printf("GO!");
+                Thread::wait(1000.00*0.3);
+                uLCD.cls();
+            }
+            // Set up Background
+            uLCD.line(42,25-4,42,127,WHITE);
+            uLCD.line(2*42+1,25-4,2*42+1,127,WHITE);
+            uLCD.circle(20,127-20,20,GREEN);
+            uLCD.circle(64,127-20,20,RED);
+            uLCD.circle(127-20,127-20,20,BLUE);
+            uLCD.rectangle(2,20,127,2,WHITE);
+            uLCD.locate(1,1);
+            uLCD.printf("Score: %f",score);
+            if (numPlayedS1 < 17) {
+                ramb_ptr[numPlayedS1] -> draw();
+                ramb_ptr[numPlayedS1] -> setMoving(1);
+                numPlayedS1++;
+                float waitTime = 0.17 - numPlayedS1*0.01;
+                Thread::wait(1000.00*waitTime);
+            }
+            for (int i=0; i < 17; i++) {
+            ramb_ptr[i] -> update();  
+            }
+            gVal = touchg.read();
+            rVal = touchr.read();
+            bVal = touchb.read();
+            
+            if (gVal > 0.5f) {
+                uLCD.circle(20,107,19,GREEN);
+                uLCD.circle(20,107,21,GREEN);
+            } else {
+                uLCD.circle(20,107,19,BLACK);
+                uLCD.circle(20,107,21,BLACK);
+            }
+            if (rVal > 0.5f) {
+                uLCD.circle(64,107,19,RED);
+                uLCD.circle(64,107,21,RED);
+            } else {
+                uLCD.circle(64,107,19,BLACK);
+                uLCD.circle(64,107,21,BLACK);
+            }
+            if (bVal > 0.5f) {
+                uLCD.circle(107,107,19,BLUE);
+                uLCD.circle(107,107,21,BLUE);
+            } else {
+                uLCD.circle(107,107,19,BLACK);
+                uLCD.circle(107,107,21,BLACK);
+            }
+            stdio_mutex.unlock();
+            prevState = 2;
+        } else if (currState == 3) { //Playing Song2
+            //stdio_mutex.lock();
+            Thread::wait(1000.00*1);
+            prevState = 3;
+            //stdio_mutex.unlock();
         }
     }
 }
 
-void lighthouse(void const *args){
-    float y=0.0;
-    while(1) {
-        for(double x=0.0; x <= 3.14159; x = x + 0.0314159) {
-            y = sin(x); //nice periodic function 0..1..0
-            myled4 = y*y*y;//exponential effect - needs a sharp peak
-            Thread::wait(1000.0*.025);
-        }
-        myled4 = 0.0;
-        //most lighthouses have a 5 second delay - so add another 2.5
-        Thread::wait(1000.0*2.5);
-    }
-}
+
+
+
+
 
 int main() {
+    // Set up PushButtons
+    pbL.mode(PullUp);
+    pbR.mode(PullUp);
+    
     Thread thread2(beacon);
     Thread thread3(welding);
-    Thread thread4(lighthouse);
-    //main runs standard LED blink demo
+    //Thread thread4(lighthouse);
+    
+    // Set up Random Note Positions
+    set_time(1256729738);  // by updating this creates new values each compilation
+    srand( static_cast<unsigned int>(time(0)));
+    
+    // create random assigner for each note   
+    for (int i=0; i < 17; i++) {
+        int ramblinColors = rand() % 3;
+        int ramblinRows = rand() % 3;
+        int x = 0;
+        if (ramblinRows == 0) {
+            x = 18;
+        } else if (ramblinRows == 1) {
+            x = 64;
+        } else if (ramblinRows == 2) {
+            x = 110;
+        }
+        if (ramblinColors == 0) {
+            ramb_ptr[i] = new redNotes;
+        } else if (ramblinColors == 1) {
+            ramb_ptr[i] = new greenNotes;
+        } else if (ramblinColors == 2) {
+            ramb_ptr[i] = new blueNotes;
+        } 
+        ramb_ptr[i] -> setStart(35);
+        ramb_ptr[i] -> setWidth(x);
+        ramb_ptr[i] -> setFreq(ramblinFirst[i]);
+        ramb_ptr[i] -> setDur(ramblinSecond[i]);
+        ramb_ptr[i] -> setVal(ramblinThird[i]);
+    }
+    
     while(1) {
+        gVal = touchg.read();
+        rVal = touchr.read();
+        bVal = touchb.read();
+        // LED to Indicate Program Running
         myled = 1;
         Thread::wait(1000.0*0.2);
         myled = 0;
         Thread::wait(1000.0*0.2);
+        // Display Startup Page
+        stdio_mutex.lock();
+        if (currState == 0) {
+            if (prevState != 0) {
+                uLCD.cls();
+            }
+            uLCD.text_width(2); 
+            uLCD.text_height(3);
+            uLCD.color(BLUE);
+            uLCD.locate(1.4, 0);
+            uLCD.printf("Welcome    to \nMusicPlay");
+            
+            uLCD.text_width(1); 
+            uLCD.text_height(1);
+            uLCD.color(RED);
+            uLCD.locate(3.5, 12);
+            uLCD.printf("Press Either     Button to Start");
+            prevState = 0;
+        } else if (currState == 1) { // Display Menu
+            if (prevState != 1) {
+                uLCD.cls();
+            }
+            uLCD.text_width(1);
+            uLCD.text_height(1);
+            if (selected == 1) {
+                uLCD.color(RED);
+            } else {
+                uLCD.color(BLUE);
+            }
+            uLCD.locate(2, 1);
+            uLCD.printf("Ramblin Wreck");
+            if (selected == 2) {
+                uLCD.color(RED);
+            } else {
+                uLCD.color(BLUE);
+            }
+            uLCD.locate(6, 3);
+            uLCD.printf("Song2");
+            if (selected == 3) {
+                uLCD.color(RED);
+            } else {
+                uLCD.color(BLUE);
+            }
+            uLCD.locate(3, 5);
+            uLCD.printf("Just Listen!");
+            if (selected == 4) {
+                uLCD.color(RED);
+            } else {
+                uLCD.color(BLUE);
+            }
+            uLCD.locate(7, 7);
+            uLCD.printf("Back");
+            prevState = 1;
+        } 
+        stdio_mutex.unlock();
     }
 }