Dependencies: MCP23S17 RPG SDFileSystem TextLCD mbed wave_player
Fork of MCP23S17_Basic_IO_Demo by
main.cpp
- Committer:
- rpere
- Date:
- 2013-03-04
- Revision:
- 3:accf08e39ba0
- Parent:
- 2:934a0500abde
- Child:
- 4:9ea6afd40e7e
File content as of revision 3:accf08e39ba0:
// See http://mbed.org/users/romilly/notebook/mcp23s17-addressable-16-bit-io-expander-with-spi/ // MCP23S17 datasheet http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf // uses MCP23S17 library version 0.4 #include "mbed.h" #include "MCP23S17.h" #include "TextLCD.h" #include "RPG.h" #include "wave_player.h" #include "SDFileSystem.h" #define S_BEGIN 0 #define S_PLAY 1 #define S_VICTORY 2 #define S_DEFEAT 3 // Creates an initializes all necessary objects void init(); // Obstains menu input and updates LCD text accordingly int handleMenu(); // Plays the current sequence so far using timing appropriate to the chosen difficulty void playSequence(); // Listens for the player move and returns a value indicating success or failure int listenSequence(); // Re-initializes the game void restart(); // Create SPI bus SPI spi(p5, p6, p7); // Create Text LCD Controller TextLCD lcd(p21, p22, p23, p24, p25, p26); // Create RPG interface RPG rpg(p16,p17,p20); // Create SD interface SDFileSystem sd(p11, p12, p13, p14, "sd"); // Sound output AnalogOut DACout(p18); // Wave file player wave_player waver(&DACout); // Sound files FILE *Sounds[11]; // Wiring Connections: // mbed p5,p6,p7 are tied to MCP23S17 SI, SO, SCK pins // mbed p8 to MCP23S17 CS // MCP23S17 reset pin pulled high // Chip addresses (opcodes) char opcodes[3]; // Chip objects MCP23S17* chips[3]; // Menu variables char* menuOptions[] = { " Easy >", "< Medium >", "< Hard " }; short menuState = 0; short oldMenuState = -1; short menuBuffer = 0; // Difficulty settings double timeoutVals[3] = { 2, 1.5, 1 }; double delayVals[3] = { 0.5, 0.3, 0.1}; short victoryVals[3] = {4 , 6, 8}; // Game variables short sequence[15]; short current = 0; short gameState = 0; short victory; double timeout; double delay; char input = 0; // Push button input int main() { init(); while (1) { int menuSelection; switch(gameState) { case S_BEGIN: menuSelection = handleMenu(); if(menuSelection > -1) { gameState = S_PLAY; timeout = timeoutVals[menuSelection]; delay = delayVals[menuSelection]; victory = victoryVals[menuSelection]; } break; case S_PLAY: playSequence(); if(!listenSequence()) gameState = S_DEFEAT; else if(current == victory) gameState = S_VICTORY; break; case S_VICTORY: lcd.cls(); lcd.locate(0,0); lcd.printf(" YOU WON :D "); lcd.printf(" <( . _ . )> "); waver.play(Sounds[10]); rewind(Sounds[10]); wait(5); gameState = S_BEGIN; restart(); break; case S_DEFEAT: lcd.cls(); lcd.locate(0,0); lcd.printf(" DEFEAT "); lcd.printf(" TRY HARDER "); waver.play(Sounds[9]); rewind(Sounds[9]); wait(5); gameState = S_BEGIN; restart(); break; default: lcd.printf("Invalid State"); } handleMenu(); } } void init() { // Set chips opcodes (Dependent on hardware connections) opcodes[0] = 0x40; opcodes[1] = 0x42; opcodes[2] = 0x44; /* Create IO Expander objects with their respective opcodes * and set port B of each chip for input and port A of each chip * for output. */ for(int i = 0; i <3 ; i++) { chips[i] = new MCP23S17(spi, p8, opcodes[i]); // Set all 8 Port A bits to output direction chips[i]->direction(PORT_A, 0x00); // Set all 8 Port B bits to input direction chips[i]->direction(PORT_B, 0xFF); // Turn off all LEDs chips[i]->write(PORT_A, 0); } // Clear sequence for(int i = 0; i < 15; i++) sequence[i] = 0 ; set_time(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37 // Initialize sounds and file system char ftotal[] = "/sd/sounds/x.wav"; for(int i = 0;i<9;i++) { ftotal[11] = i + '0'; Sounds[i] = fopen(ftotal, "r"); if(Sounds[i] == NULL) lcd.printf("SOUND ERROR"); } Sounds[9] = fopen("/sd/sounds/lose.wav", "r"); Sounds[10] = fopen("/sd/sounds/win.wav" , "r"); } int handleMenu() { menuBuffer +=rpg.dir(); if(menuBuffer == -15) { menuState++; menuBuffer = 0; } else if (menuBuffer == 15) { menuState--; menuBuffer = 0; } if(menuState < 0) menuState = 0; else if(menuState > 2) menuState = 2; if( oldMenuState != menuState) { lcd.cls(); lcd.printf("Difficulty:"); lcd.locate(0,1); lcd.printf("%s", menuOptions[menuState]); } oldMenuState = menuState; if(rpg.pb()) return menuState; else return -1; } void playSequence() { lcd.cls(); lcd.locate(0,0); lcd.printf("Sequence Playing"); lcd.printf("..."); wait(delay + 0.5); sequence[current] = time(NULL)%9 ; current++; for(int i = 0; i < current; i++) { int chipNum = sequence[i]/3; int ledNum = sequence[i]%3; chips[chipNum]->write(PORT_A, (1 << ledNum) ); waver.play(Sounds[sequence[i]]); rewind(Sounds[sequence[i]]); wait(delay); chips[chipNum]->write(PORT_A, 0); wait(delay); } lcd.cls(); lcd.locate(0,0); lcd.printf("Get ready..."); wait(timeout + 0.5 ); lcd.cls(); lcd.locate(0,0); lcd.printf("GO!!!"); wait(delay + 0.3); } int listenSequence() { time_t startTime = time(NULL); time_t currentTime = startTime; time_t timeDiff = 0; int totalTime = timeout * current; int currentCheck = 0; bool correct = false; int input; int oldInput[3] = {0, 0, 0}; lcd.cls(); while(timeDiff <= totalTime) { lcd.locate(0,0); lcd.printf("Time: %d", totalTime - timeDiff); if(totalTime - timeDiff < 10) lcd.printf(" "); lcd.locate(0,1); lcd.printf("Round: %d",current); currentTime = time(NULL); timeDiff = currentTime - startTime; for(int i = 0; i < 3; i++) { // Read lower 3 bits input = chips[i]->read(PORT_B) & 7; if(input != 0 && oldInput[i] == 0) { chips[i]->write(PORT_A, input); wait(0.3); chips[i]->write(PORT_A, 0); if(correct) return 0; int rest; if(input == 1) rest = 0; else if(input == 2) rest = 1; else if(input == 4) rest = 2; else rest = 3; if( i * 3 + rest == sequence[currentCheck]) { waver.play(Sounds[sequence[currentCheck]]); rewind(Sounds[sequence[currentCheck]]); currentCheck++; correct = true; } else { lcd.cls(); lcd.locate(0,0); lcd.printf("You pressed: %d", i * 3 + rest); lcd.locate(0,1); lcd.printf("Next Was: %d",sequence[currentCheck]); wait(6); return 0; } } oldInput[i] = input; } correct = false; if(currentCheck == current) break; } wait(delay + 0.5); if(currentCheck == current) return 1; else return 0; } void restart() { current = 0; menuState = 0 ; oldMenuState = -1; }