DICE ROLLER

Dependencies:   mbed wave_player Servo mbed-rtos 4DGL-uLCD-SE SDFileSystem_OldbutworkswithRTOS PinDetect MMA8452

Revision:
10:5b1f8be6c4f3
Parent:
8:31e63caf37e2
--- a/main.cpp	Wed Oct 28 15:06:56 2015 +0000
+++ b/main.cpp	Mon Dec 09 03:56:43 2019 +0000
@@ -1,171 +1,366 @@
-// uLCD-144-G2 demo program for uLCD-4GL LCD driver library
-//
+#include "MMA8452.h"
 #include "mbed.h"
+#include "rtos.h"
 #include "uLCD_4DGL.h"
+#include "Servo.h"
+#include "PinDetect.h"
+#include "SDFileSystem.h"
+#include "Servo.h"
+#include "wave_player.h"
+
+AnalogIn photocell(p15);
+
+Serial pc(USBTX,USBRX);
+Servo myservo(p21);
+// SD CARD & SOUND
+SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
+AnalogOut DACout(p18);
+//SD CARD & SOUND
 
 uLCD_4DGL uLCD(p9,p10,p11); // serial tx, serial rx, reset pin;
+PinDetect pb1(p16);
+PinDetect pb2(p17);
+PinDetect pb3(p26);
 
-int main()
-{
-    // basic printf demo = 16 by 18 characters on screen
-    uLCD.printf("\nHello uLCD World\n"); //Default Green on black text
-    uLCD.printf("\n  Starting Demo...");
-    uLCD.text_width(4); //4X size text
-    uLCD.text_height(4);
-    uLCD.color(RED);
-    for (int i=10; i>=0; --i) {
-        uLCD.locate(1,2);
-        uLCD.printf("%2D",i);
-        wait(.5);
-    }
-    uLCD.cls();
-    uLCD.printf("Change baudrate......");
-    uLCD.baudrate(3000000); //jack up baud rate to max for fast display
-    //if demo hangs here - try lower baud rates
-    //
-    // printf text only full screen mode demo
-    uLCD.background_color(BLUE);
-    uLCD.cls();
-    uLCD.locate(0,0);
-    uLCD.color(WHITE);
-    uLCD.textbackground_color(BLUE);
-    uLCD.set_font(FONT_7X8);
-    uLCD.text_mode(OPAQUE);
-    int i=0;
-    while(i<64) {
-        if(i%16==0) uLCD.cls();
-        uLCD.printf("TxtLine %2D Page %D\n",i%16,i/16 );
-        i++; //16 lines with 18 charaters per line
+AnalogIn pot1(p19);
+AnalogIn pot2(p20);
+
+DigitalOut led1(p30);
+DigitalOut led2(p29);
+DigitalOut led3(p25);
+DigitalOut led4(p24);
+DigitalOut led5(p23);
+DigitalOut led6(p22);
+
+Mutex lcd_mutex;
+
+MMA8452 acc(p28, p27, 100000);
+wave_player waver(&DACout);
+
+////////////////// GLOBAL VARIABLES /////////////////////////////
+int game_state = 0;
+int player_guess = 1;
+float dice_color = 16777215;
+float result_rolled;
+double xg,yg,zg;
+float dot_size;
+
+FILE *audio;
+/////////////////////////////////////////////////////////////////
+
+void one_led(){
+    led1 = 1;
+    led2 = 0;
+    led3 = 0;
+    led4 = 0;
+    led5 = 0;
+    led6 = 0;
     }
-    wait(0.5);
-    //demo graphics commands
-    uLCD.background_color(BLACK);
-    uLCD.cls();
-    uLCD.background_color(DGREY);
-    uLCD.filled_circle(60, 50, 30, 0xFF00FF);
-    uLCD.triangle(120, 100, 40, 40, 10, 100, 0x0000FF);
-    uLCD.line(0, 0, 80, 60, 0xFF0000);
-    uLCD.filled_rectangle(50, 50, 100, 90, 0x00FF00);
-    uLCD.pixel(60, 60, BLACK);
-    uLCD.read_pixel(120, 70);
-    uLCD.circle(120, 60, 10, BLACK);
-    uLCD.set_font(FONT_7X8);
-    uLCD.text_mode(TRANSPARENT);
-    uLCD.text_bold(ON);
-    uLCD.text_char('B', 9, 8, BLACK);
-    uLCD.text_char('I',10, 8, BLACK);
-    uLCD.text_char('G',11, 8, BLACK);
-    uLCD.text_italic(ON);
-    uLCD.text_string("This is a test of string", 1, 4, FONT_7X8, WHITE);
-    wait(2);
-
-//Bouncing Ball Demo
-    float fx=50.0,fy=21.0,vx=1.0,vy=0.4;
-    int x=50,y=21,radius=4;
-    uLCD.background_color(BLACK);
-    uLCD.cls();
-    //draw walls
-    uLCD.line(0, 0, 127, 0, WHITE);
-    uLCD.line(127, 0, 127, 127, WHITE);
-    uLCD.line(127, 127, 0, 127, WHITE);
-    uLCD.line(0, 127, 0, 0, WHITE);
-    for (int i=0; i<1500; i++) {
-        //draw ball
-        uLCD.filled_circle(x, y, radius, RED);
-        //bounce off edge walls and slow down a bit?
-        if ((x<=radius+1) || (x>=126-radius)) vx = -.90*vx;
-        if ((y<=radius+1) || (y>=126-radius)) vy = -.90*vy;
-        //erase old ball location
-        uLCD.filled_circle(x, y, radius, BLACK);
-        //move ball
-        fx=fx+vx;
-        fy=fy+vy;
-        x=(int)fx;
-        y=(int)fy;
+    
+void two_led(){
+    led1 = 1;
+    led2 = 1;
+    led3 = 0;
+    led4 = 0;
+    led5 = 0;
+    led6 = 0;
+    }
+void three_led(){
+    led1 = 1;
+    led2 = 1;
+    led3 = 1;
+    led4 = 0;
+    led5 = 0;
+    led6 = 0;
+    }
+void four_led(){
+    led1 = 1;
+    led2 = 1;
+    led3 = 1;
+    led4 = 1;
+    led5 = 0;
+    led6 = 0;
+    }
+void five_led(){
+    led1 = 1;
+    led2 = 1;
+    led3 = 1;
+    led4 = 1;
+    led5 = 1;
+    led6 = 0;
+    }
+void six_led(){
+    led1 = 1;
+    led2 = 1;
+    led3 = 1;
+    led4 = 1;
+    led5 = 1;
+    led6 = 1;
+    }
+    
+void guess_up() {
+    player_guess++;
+    if (player_guess > 6) {player_guess = 6;}
+    }
+    
+void guess_down() {
+    player_guess--;
+    if (player_guess < 1) {player_guess = 1;}
     }
-    wait(0.5);
-//draw an image pixel by pixel
-    int pixelcolors[50][50];
-    uLCD.background_color(BLACK);
+    
+
+void next_state() {
+    game_state++;
+    if (game_state == 3) {game_state = 0;}
+    else if(game_state == 2) {game_state = 1;}
+}
+
+void dice1(){
+    lcd_mutex.lock();
+    uLCD.filled_rectangle(20, 20, 108, 108, dice_color);
+    uLCD.filled_circle(64,64,dot_size,BLACK);
+    Thread::wait(1000);
+    uLCD.cls();
+    lcd_mutex.unlock();
+    Thread::wait(1000);
+}
+void dice2(){
+    lcd_mutex.lock();
+    uLCD.filled_rectangle(20, 20, 108, 108, dice_color);
+    uLCD.filled_circle(88,40,dot_size,BLACK);
+    uLCD.filled_circle(40,88,dot_size,BLACK);
+    Thread::wait(1000);
     uLCD.cls();
-//compute Mandelbrot set image for display
-//image size in pixels
-    const unsigned ImageHeight=128;
-    const unsigned ImageWidth=128;
-    //"c" region to display
-    double MinRe = -0.75104;
-    double MaxRe = -0.7408;
-    double MinIm = 0.10511;
-    double MaxIm = MinIm+(MaxRe-MinRe)*ImageHeight/ImageWidth;
-    double Re_factor = (MaxRe-MinRe)/(ImageWidth-1);
-    double Im_factor = (MaxIm-MinIm)/(ImageHeight-1);
-    unsigned MaxIterations = 2048;
-    for(unsigned y=0; y<ImageHeight; ++y) {
-        double c_im = MaxIm - y*Im_factor;
-        for(unsigned x=0; x<ImageWidth; ++x) {
-            double c_re = MinRe + x*Re_factor;
-            double Z_re = c_re, Z_im = c_im;
-            int niterations=0;
-            for(unsigned n=0; n<MaxIterations; ++n) {
-                double Z_re2 = Z_re*Z_re, Z_im2 = Z_im*Z_im;
-                if(Z_re2 + Z_im2 > 4) {
-                    niterations = n;
-                    break;
-                }
-                Z_im = 2*Z_re*Z_im + c_im;
-                Z_re = Z_re2 - Z_im2 + c_re;
-            }
-            if (niterations!=(MaxIterations-1))
-                uLCD.pixel(x,y,((niterations & 0xF00)<<12)+((niterations & 0xF0)<<8)+((niterations & 0x0F)<<4) );
-        }
-    }
-    wait(5);
-// PLASMA wave BLIT animation
-//draw an image using BLIT (Block Image Transfer) fastest way to transfer pixel data
+    lcd_mutex.unlock();
+    Thread::wait(1000);
+}
+void dice3(){
+    lcd_mutex.lock();
+    uLCD.filled_rectangle(20, 20, 108, 108, dice_color);
+    uLCD.filled_circle(64,64,dot_size,BLACK);
+    uLCD.filled_circle(88,40,dot_size,BLACK);
+    uLCD.filled_circle(40,88,dot_size,BLACK);
+    Thread::wait(1000);
+    uLCD.cls();
+    lcd_mutex.unlock();
+    Thread::wait(1000);   
+}
+void dice4(){
+    lcd_mutex.lock();
+    uLCD.filled_rectangle(20, 20, 108, 108, dice_color);
+    uLCD.filled_circle(88,40,dot_size,BLACK);
+    uLCD.filled_circle(40,88,dot_size,BLACK);
+    uLCD.filled_circle(40,40,dot_size,BLACK);
+    uLCD.filled_circle(88,88,dot_size,BLACK);
+    Thread::wait(1000);
+    uLCD.cls();
+    lcd_mutex.unlock();
+    Thread::wait(1000);   
+}
+void dice5(){
+    lcd_mutex.lock();
+    uLCD.filled_rectangle(20, 20, 108, 108, dice_color);
+    uLCD.filled_circle(64,64,dot_size,BLACK);
+    uLCD.filled_circle(88,40,dot_size,BLACK);
+    uLCD.filled_circle(40,88,dot_size,BLACK);
+    uLCD.filled_circle(40,40,dot_size,BLACK);
+    uLCD.filled_circle(88,88,dot_size,BLACK);
+    Thread::wait(1000);
     uLCD.cls();
-    int num_cols=50;
-    int num_rows=50;
-    int frame=0;
-    double a,b,c=0.0;
-    while(frame<75) {
-        for (int k=0; k<num_cols; k++) {
-            b= (1+sin(3.14159*k*0.75/(num_cols-1.0)+c))*0.5;
-            for (int i=0; i<num_rows; i++) {
-                a= (1+sin(3.14159*i*0.75/(num_rows-1.0)+c))*0.5;
-                // a and b will be a sine wave output between 0 and 1
-                // sine wave was scaled for nice effect across array
-                // uses a and b to compute pixel colors based on rol and col location in array
-                // also keeps colors at the same brightness level
-                if ((a+b) <.667)
-                    pixelcolors[i][k] =  (255-(int(254.0*((a+b)/0.667)))<<16) | (int(254.0*((a+b)/0.667))<<8) | 0;
-                else if ((a+b)<1.333)
-                    pixelcolors[i][k] = (0 <<16) | (255-(int (254.0*((a+b-0.667)/0.667)))<<8) | int(254.0*((a+b-0.667)/0.667));
-                else
-                    pixelcolors[i][k] = (int(255*((a+b-1.333)/0.667))<<16) | (0<<8)  | (255-(int (254.0*((a+b-1.333)/0.667))));
-            }
+    lcd_mutex.unlock();
+    Thread::wait(1000);   
+}
+void dice6(){
+    lcd_mutex.lock();
+    uLCD.filled_rectangle(20, 20, 108, 108, dice_color);
+    uLCD.filled_circle(88,40,dot_size,BLACK);
+    uLCD.filled_circle(40,88,dot_size,BLACK);
+    uLCD.filled_circle(40,40,dot_size,BLACK);
+    uLCD.filled_circle(88,88,dot_size,BLACK);
+    uLCD.filled_circle(40,40,dot_size,BLACK);//Not finished yet
+    uLCD.filled_circle(88,88,dot_size,BLACK);
+    Thread::wait(1000);
+    uLCD.cls();
+    lcd_mutex.unlock();
+    Thread::wait(1000);   
+}
+
+////////////// SECOND THREAD //////////////////////////////////////////////////
+void input_guess_change_settings(void const *args){
+    while(true){
+        if (game_state == 1){
+            lcd_mutex.lock();
+            uLCD.printf("Input your guess\nof the dice roll\nwith the buttons\non the breadbaord.\n\n");
+            Thread::wait(300);
+            uLCD.printf("Pick a number 1-6\nthen roll the die.\n\n");
+            Thread::wait(200);
+            uLCD.printf("If you want to\nchange the dot\nsize or color,\nyou can with the\npots.");
+            Thread::wait(600);
+            uLCD.cls();
+            lcd_mutex.unlock();
+            player_guess = 1;
+            led1 = 1;
+            while(game_state == 1) {
+                
+                // if accelerometer changes enough, go to next state
+                acc.readXYZGravity(&xg,&yg,&zg);
+                zg = abs(zg);
+                if(zg>1.1f || zg < 0.75f){
+                    game_state = 2;
+                    }
+                dice_color = (floor(100.0f * float(pot1))/100.0f);
+                dice_color = dice_color * 16777215.0f;
+                if (float(photocell) < 0.4f) {
+                    dice_color = RED;
+                    }
+                
+                dot_size = ((floor(100.0f * float(pot2))/100.0f)*10 )+2;
+                
+                lcd_mutex.lock();
+                uLCD.filled_rectangle(20, 20, 108, 108, dice_color);
+                uLCD.filled_circle(64,64,dot_size,BLACK);
+                uLCD.filled_circle(88,40,dot_size,BLACK);
+                uLCD.filled_circle(40,88,dot_size,BLACK);
+                Thread::wait(1000);
+                uLCD.cls();
+                lcd_mutex.unlock();
+                
+                switch (player_guess){
+                    case 1: one_led();
+                        break;
+                    case 2: two_led();
+                        break;
+                    case 3: three_led();
+                        break;
+                    case 4: four_led();
+                        break;
+                    case 5: five_led();
+                        break;
+                    case 6: six_led();
+                        break;
+                    }
+                    
+                }
         }
-        uLCD.BLIT(39, 39, 50, 50, &pixelcolors[0][0]);
-        c = c + 0.0314159*3.0;
-        if (c > 6.2831) c = 0.0;
-        frame++;
-    }
-    //Load Image Demo
-    uLCD.cls();
-    //SD card needed with image and video files for last two demos
-    uLCD.cls();
-    uLCD.media_init();
-    uLCD.printf("\n\nAn SD card is needed for image and video data");
-    uLCD.set_sector_address(0x001D, 0x4C01);
-    uLCD.display_image(0,0);
-    wait(10);
-    //Play video demo
-    while(1) {
-        uLCD.cls();
-        uLCD.media_init();
-        uLCD.set_sector_address(0x001D, 0x4C42);
-        uLCD.display_video(0,0);
+    Thread::wait(1000);
     }
 }
-
+////////////////////////////////////////////////////////////////////////////////
 
+////////////// THIRD THREAD ////////////////////////////////////////////////////
+void view_result_high_five(void const *args) {
+    while(true){
+        if(game_state == 2){
+            
+            audio = fopen("/sd/roll.wav","r");
+            waver.play(audio);
+            fclose(audio);
+            
+            result_rolled = rand()%6 + 1;
+            switch(int(result_rolled)){
+                case 1: dice1();
+                    audio = fopen("/sd/one.wav", "r");
+                    waver.play(audio);
+                    fclose(audio);
+                    break;
+                case 2: dice2();
+                    audio = fopen("/sd/two.wav", "r");
+                    waver.play(audio);
+                    fclose(audio);
+                    break;
+                case 3: dice3();
+                    audio = fopen("/sd/three.wav", "r");
+                    waver.play(audio);
+                    fclose(audio);
+                    break;
+                case 4: dice4();
+                    audio = fopen("/sd/four.wav", "r");
+                    waver.play(audio);
+                    fclose(audio);
+                    break;
+                case 5: dice5();
+                    audio = fopen("/sd/five.wav", "r");
+                    waver.play(audio);
+                    fclose(audio);
+                    break;
+                case 6: dice6();
+                    audio = fopen("/sd/six.wav", "r");
+                    waver.play(audio);
+                    fclose(audio);
+                    break;}
+            Thread::wait(1000);
+            
+            while(game_state == 2){
+                if(player_guess == result_rolled){
+                    audio = fopen("/sd/won.wav", "r");
+                    waver.play(audio);
+                    fclose(audio);
+                    lcd_mutex.lock();
+                    uLCD.printf("     You WIN!!\n\n     High five!");
+                    Thread::wait(1000);
+                    uLCD.cls();
+                    lcd_mutex.unlock();
+                    for(float p=0; p<1.0; p += 0.01) {
+                        myservo = p;
+                        Thread::wait(0.2);
+                    }
+                    
+                    Thread::wait(4000);
+                
+                    for(float p=1; p>0.0; p -= 0.01) {
+                        myservo = p;
+                        Thread::wait(0.2);
+                    }
+                    ///////////////////////////////////////
+                }
+                else if(player_guess != result_rolled) {
+                    audio = fopen("/sd/lost.wav", "r");
+                    waver.play(audio);
+                    fclose(audio);
+                    lcd_mutex.lock();
+                    uLCD.printf("    you lose.....");
+                    Thread::wait(1000);
+                    uLCD.cls();
+                    lcd_mutex.unlock();
+                }
+                lcd_mutex.lock();
+                uLCD.printf("Press the button\nto play again!");
+                while(game_state == 2){Thread::wait(250);}
+                uLCD.cls();
+                lcd_mutex.unlock();
+            }
+        }  
+    }
+}
+///////////////////////////////////////////////////////////////////////////////
 
+int main(){
+    pb1.mode(PullDown);
+    pb1.attach_deasserted(&guess_down);
+    pb1.setSampleFrequency();
+    
+    pb2.mode(PullDown);
+    pb2.attach_deasserted(&guess_up);
+    pb2.setSampleFrequency();
+    
+    pb3.mode(PullDown);
+    pb3.attach_deasserted(&next_state);
+    pb3.setSampleFrequency();
+    
+    Thread t2(input_guess_change_settings);
+    Thread t3(view_result_high_five);
+    
+    while(1){
+       if (game_state == 0){
+          myservo = 0;
+          lcd_mutex.lock();
+          uLCD.printf("\n\n      Welcome!\n\n\nPress the button\nto start.");
+          Thread::wait(1000);
+          while(game_state == 0){Thread::wait(250);}
+          uLCD.cls();
+          lcd_mutex.unlock();
+        }
+        Thread::wait(250);
+   
+    }
+}