Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Speaker mbed mbed-rtos 4DGL-uLCD-SE PinDetect
Diff: main.cpp
- 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();
}
}