//****************************************************************** //* PROJECT: GripBuilder * //* ACTIVITY: MSOE Discover the Possibilities Biomedical Computing * //* AUTHOR: Dr. Russ Meier * //* DATE: 22 July 2016 * //* PROVIDES: * //* - a rehabilitation game for use by physical therapists * //* working with stroke patients or patients with neuromuscular * //* disorders. * //* * //* TO USE: * //* - Connect force sensor to Arduino. See schematic diagram. * //* - Power on through USB port * //****************************************************************** // include lcd library functions #include // construct global LCD object for use by all other functions LiquidCrystal lcd(8,9,4,5,6,7); // function: setup // purpose: runs once at power up to initialize system // algorithm: // - present welcome screen // - play welcome music // - tell user how to play void setup() { welcomeMessage(); welcomeMusic(); help(); } // function: loop // purpose: main control loop for game play // algorithm: // - initialize a starting grip goal // - do game play while goal < 900 // - if player reaches goal reward with siren and level up void loop() { int goal = 300; do { lcd.setCursor(4,0); // center on row 0 lcd.print("Hit: "); lcd.setCursor(9,0); lcd.print(goal); lcd.setCursor(4,1); // center on row 1 lcd.print("You: "); // eight blanks after : to clear ghosts lcd.setCursor(9,1); int sensorVal = analogRead(A5); lcd.print(sensorVal); if(sensorVal >= goal) { lcd.setCursor(4,0); lcd.print("Great Job"); lcd.setCursor(4,1); lcd.print("Let Go Now!"); while(analogRead(A5)>50) siren(); goal=goal+100; } delay(500); // human time }while(goal < 900); } // function: welcomeMessage // purpose: present a game on welcome screen, engage user // algorithm: // - ask LCD to power up // - center product title "GripBuilder!" // - product title grows from middle out with short, low tones // creating a growl effect void welcomeMessage() { char letters[12]={'u','B','i','p','l','i','d','r','e','G','r','!'}; int column[12] = {7,6,8,5,9,4,10,3,11,2,12,13}; lcd.begin(16,2); lcd.clear(); for(int x=0; x<12; x=x+1) { lcd.setCursor(column[x],0); lcd.print(letters[x]); tone(A1,100); delay(125); noTone(A1); delay(60); } delay(250); // a little screen delay } // function: welcomeMusic // purpose: play welcome music: theme from Rocky the movie // algorithm: // - use a for loop to play frequencies at rhythmic duration // - frequencies and rhythm read from sheet music // - startup scroll bar advances with music // - 67 notes / 16 columns = approx 4 notes per column // - use remainder function: only when x/4 has no remainder // print a *. void welcomeMusic() { int freq[67] = { 699,699,699,699,699,699,699,880,699, 699,699,880,880,880,880,880,880,880, 1047,880,880,880,880,880,880,880, 880,880,880,880,880,880,880,880,880, 880,880,880,880,1047,1175,1175, 1319,880,880,1047,1175,1175,1319,880, 0,784,698,784,698,784,880,0, 699,699,699,699,699,699,699,932,880 }; int dur[67] = { 2,2,1,1,2,1,1,2,1,1,2,2,2,1,1,2,1,1,2,1,1,4, 2,1,1,2,1,2,1,2,1,1,2,1,1,1,2,3,1,3,9,1,2,9, 1,3,9,1,3,9,1,1,1,3,1,2,5,1,1,1,2,1,3,1,3,2,9 }; lcd.setCursor(0,1); // adjust for scroll bar for(int x=0; x<67; x++) { if(freq[x]!=0) tone(A1,freq[x]); delay(100*dur[x]); noTone(A1); delay(50); if( (x%4) == 0 ) lcd.print("*"); } } // function: help // purpose: tell user what to do // algorithm: // - print commands to screen // - use two second read delay void help() { lcd.clear(); lcd.setCursor(3,0); lcd.print("Pinch Grip"); delay(2000); lcd.setCursor(0,1); lcd.print("Hard as You Can!"); delay(2000); lcd.clear(); lcd.setCursor(2,0); lcd.print("Hit The Goal"); delay(2000); lcd.setCursor(1,1); lcd.print("Earn a Reward!"); delay(2000); lcd.clear(); } void siren() { for(int x=0; x<3; x=x+1) { tone(A1,880); delay(125); tone(A1,440); delay(125); } noTone(A1); }