DICE ROLLER
Dependencies: mbed wave_player Servo mbed-rtos 4DGL-uLCD-SE SDFileSystem_OldbutworkswithRTOS PinDetect MMA8452
Diff: main.cpp
- 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); + + } +}