Amaldi / Mbed 2 deprecated Amaldi_16_Exercise_Game_rev3

Dependencies:   mbed

Committer:
pinofal
Date:
Tue Dec 04 13:45:23 2018 +0000
Revision:
2:1bdcc88f5501
Child:
3:58b0cfe9cc3a
Game rev2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pinofal 2:1bdcc88f5501 1 #include "mbed.h"
pinofal 2:1bdcc88f5501 2 #include "stdlib.h"
pinofal 2:1bdcc88f5501 3 #include "SampledSoundBadScore.h"
pinofal 2:1bdcc88f5501 4 #include "SampledSoundGoodScore.h"
pinofal 2:1bdcc88f5501 5
pinofal 2:1bdcc88f5501 6 // numero di Step in cui è suddiviso il gioco
pinofal 2:1bdcc88f5501 7 #define GAMESTEPNUMBER 4
pinofal 2:1bdcc88f5501 8
pinofal 2:1bdcc88f5501 9 // tempo di base tra due step di gioco in [msec]
pinofal 2:1bdcc88f5501 10 #define TIMEBETWEEN 5000
pinofal 2:1bdcc88f5501 11
pinofal 2:1bdcc88f5501 12 // genera un oggetto serial collegato al PC
pinofal 2:1bdcc88f5501 13 Serial pc(USBTX, USBRX);
pinofal 2:1bdcc88f5501 14
pinofal 2:1bdcc88f5501 15 DigitalOut myLed(LED2);
pinofal 2:1bdcc88f5501 16 DigitalIn myButton(USER_BUTTON);
pinofal 2:1bdcc88f5501 17
pinofal 2:1bdcc88f5501 18 // moltiplicatore del tempo in millisecondi
pinofal 2:1bdcc88f5501 19 double nMultiplier = 50.0;
pinofal 2:1bdcc88f5501 20 Timer myTimer;
pinofal 2:1bdcc88f5501 21
pinofal 2:1bdcc88f5501 22 // Tempo a disposizione del giocatore per colpire il piezo dopo l'accensiond del LED
pinofal 2:1bdcc88f5501 23 int32_t nDelay = 500; // tempo in [msec]
pinofal 2:1bdcc88f5501 24 float fDelay = 500.0; // tempo in [msec]
pinofal 2:1bdcc88f5501 25
pinofal 2:1bdcc88f5501 26 // tempi misurati con il timer
pinofal 2:1bdcc88f5501 27 int32_t nStartTimeGame, nElapsedTimeGame, nCurrentTimeGame;
pinofal 2:1bdcc88f5501 28
pinofal 2:1bdcc88f5501 29 // seme per la generazione di numeri casuali
pinofal 2:1bdcc88f5501 30 unsigned int nSeed;
pinofal 2:1bdcc88f5501 31
pinofal 2:1bdcc88f5501 32 // numero di fade del gioco
pinofal 2:1bdcc88f5501 33 int nStepIndex;
pinofal 2:1bdcc88f5501 34
pinofal 2:1bdcc88f5501 35 // tempo in [msec] di ciascuna fase. Per la fase numero nStepIndex, il LED viene acceso per il tempo naStepDuration[nStepIndex] e entro tale tempo fovrà arrivare la risposta del giocatore
pinofal 2:1bdcc88f5501 36 const int naStepDuration[GAMESTEPNUMBER]={1500, 1000, 500, 250}; // tempi in [msec]
pinofal 2:1bdcc88f5501 37
pinofal 2:1bdcc88f5501 38 // array contenente i punteggi di ciascuno step
pinofal 2:1bdcc88f5501 39 int naStepScore[GAMESTEPNUMBER];
pinofal 2:1bdcc88f5501 40
pinofal 2:1bdcc88f5501 41 // calcola lo score su ogni singolo Step
pinofal 2:1bdcc88f5501 42 double fScore;
pinofal 2:1bdcc88f5501 43
pinofal 2:1bdcc88f5501 44
pinofal 2:1bdcc88f5501 45 // indice per la generazione del messaggio di Good Score
pinofal 2:1bdcc88f5501 46 int nGoodScoreMsgIndex;
pinofal 2:1bdcc88f5501 47
pinofal 2:1bdcc88f5501 48 // amplificazione, frequenza e periodo del segnale di Good Score
pinofal 2:1bdcc88f5501 49 double fAmpGoodScoreSound;
pinofal 2:1bdcc88f5501 50 double fFreqGoodScoreSound;
pinofal 2:1bdcc88f5501 51 double fDeltaTGoodScoreSound;
pinofal 2:1bdcc88f5501 52 // indice per la generazione del messaggio di Bad Score
pinofal 2:1bdcc88f5501 53 int nBadScoreMsgIndex;
pinofal 2:1bdcc88f5501 54
pinofal 2:1bdcc88f5501 55 // amplificazione, frequenza e periodo del segnale di Bad Score
pinofal 2:1bdcc88f5501 56 double fAmpBadScoreSound;
pinofal 2:1bdcc88f5501 57 double fFreqBadScoreSound;
pinofal 2:1bdcc88f5501 58 double fDeltaTBadScoreSound;
pinofal 2:1bdcc88f5501 59
pinofal 2:1bdcc88f5501 60
pinofal 2:1bdcc88f5501 61 // pulsante su cui bisogna colpire
pinofal 2:1bdcc88f5501 62 DigitalIn InPiezo(PA_0);
pinofal 2:1bdcc88f5501 63 // output analogico per i messaggi audio
pinofal 2:1bdcc88f5501 64 AnalogOut OutWave(PA_4);
pinofal 2:1bdcc88f5501 65
pinofal 2:1bdcc88f5501 66 /****************************************/
pinofal 2:1bdcc88f5501 67 /* Gnerazione AudioMesaggio Good Result */
pinofal 2:1bdcc88f5501 68 /****************************************/
pinofal 2:1bdcc88f5501 69 void GoodScoreMessage(void)
pinofal 2:1bdcc88f5501 70 {
pinofal 2:1bdcc88f5501 71 //++++++++++++ INIZIO generazione messaggio di GoodScore +++++++++++++++++
pinofal 2:1bdcc88f5501 72 fAmpGoodScoreSound = 1.0; // fissa l'amplificazione per il messaggio di GoodScore. Valori da 0[min] a 1[max]
pinofal 2:1bdcc88f5501 73 fFreqGoodScoreSound=nSamplePerSecGoodScore/nUnderSampleFactorGoodScore;// campioni per secondo del GoodScore message da generare = nSamplePerSec/nUnderSampleFactor
pinofal 2:1bdcc88f5501 74 fDeltaTGoodScoreSound = (1.0/fFreqGoodScoreSound); // fFreq dipende dal periodo di campionamento e dal fattore di sottocampionamento
pinofal 2:1bdcc88f5501 75
pinofal 2:1bdcc88f5501 76
pinofal 2:1bdcc88f5501 77 for(nGoodScoreMsgIndex=0; nGoodScoreMsgIndex < nSampleNumGoodScore; nGoodScoreMsgIndex++)
pinofal 2:1bdcc88f5501 78 {
pinofal 2:1bdcc88f5501 79 // mette in output un campione della forma d'onda del GoodScore message moltiplicato per l'amplificazione fAmp
pinofal 2:1bdcc88f5501 80 OutWave.write_u16(naInputSoundWaveGoodScore[nGoodScoreMsgIndex]*fAmpGoodScoreSound);
pinofal 2:1bdcc88f5501 81
pinofal 2:1bdcc88f5501 82 // tra un campione e l'altro attendi un periodo pari al periodo di campionamento
pinofal 2:1bdcc88f5501 83 //wait(fDeltaTGoodScoreSound);
pinofal 2:1bdcc88f5501 84 wait_us(30);
pinofal 2:1bdcc88f5501 85 }
pinofal 2:1bdcc88f5501 86 //++++++++++++ FINE generazione messaggio di GoodScore +++++++++++++++++
pinofal 2:1bdcc88f5501 87 }
pinofal 2:1bdcc88f5501 88
pinofal 2:1bdcc88f5501 89 /****************************************/
pinofal 2:1bdcc88f5501 90 /* Gnerazione AudioMesaggio Good Result */
pinofal 2:1bdcc88f5501 91 /****************************************/
pinofal 2:1bdcc88f5501 92 void BadScoreMessage(void)
pinofal 2:1bdcc88f5501 93 {
pinofal 2:1bdcc88f5501 94 //++++++++++++ INIZIO generazione messaggio di BadScore +++++++++++++++++
pinofal 2:1bdcc88f5501 95 fAmpBadScoreSound = 1.0; // fissa l'amplificazione per il messaggio di BadScore. Valori da 0[min] a 1[max]
pinofal 2:1bdcc88f5501 96 fFreqBadScoreSound=nSamplePerSecBadScore/nUnderSampleFactorBadScore;// campioni per secondo del BadScore message da generare = nSamplePerSec/nUnderSampleFactor
pinofal 2:1bdcc88f5501 97 fDeltaTBadScoreSound = (1.0/fFreqBadScoreSound); // fFreq dipende dal periodo di campionamento e dal fattore di sottocampionamento
pinofal 2:1bdcc88f5501 98
pinofal 2:1bdcc88f5501 99
pinofal 2:1bdcc88f5501 100 for(nBadScoreMsgIndex=0; nBadScoreMsgIndex < nSampleNumBadScore; nBadScoreMsgIndex++)
pinofal 2:1bdcc88f5501 101 {
pinofal 2:1bdcc88f5501 102 // mette in output un campione della forma d'onda del BadScore message moltiplicato per l'amplificazione fAmp
pinofal 2:1bdcc88f5501 103 OutWave.write_u16(naInputSoundWaveBadScore[nBadScoreMsgIndex]*fAmpBadScoreSound);
pinofal 2:1bdcc88f5501 104
pinofal 2:1bdcc88f5501 105 // tra un campione e l'altro attendi un periodo pari al periodo di campionamento
pinofal 2:1bdcc88f5501 106 //wait(fDeltaTBadScoreSound);
pinofal 2:1bdcc88f5501 107 wait_us(30);
pinofal 2:1bdcc88f5501 108 }
pinofal 2:1bdcc88f5501 109 //++++++++++++ FINE generazione messaggio di BadScore +++++++++++++++++
pinofal 2:1bdcc88f5501 110 }
pinofal 2:1bdcc88f5501 111
pinofal 2:1bdcc88f5501 112 /********/
pinofal 2:1bdcc88f5501 113 /* MAIN */
pinofal 2:1bdcc88f5501 114 /********/
pinofal 2:1bdcc88f5501 115 int main()
pinofal 2:1bdcc88f5501 116 {
pinofal 2:1bdcc88f5501 117 // velocità di comunicazione sulla seriale con PC
pinofal 2:1bdcc88f5501 118 pc.baud(921600);
pinofal 2:1bdcc88f5501 119
pinofal 2:1bdcc88f5501 120 // messaggio di benvenuto
pinofal 2:1bdcc88f5501 121 pc.printf("\r\nHallo Amaldi Students - Exercise 16 \r\n");
pinofal 2:1bdcc88f5501 122 pc.printf("\r\n*** Let's Play ***\r\n");
pinofal 2:1bdcc88f5501 123
pinofal 2:1bdcc88f5501 124
pinofal 2:1bdcc88f5501 125 // inizialmente spegne LED
pinofal 2:1bdcc88f5501 126 myLed=0;
pinofal 2:1bdcc88f5501 127
pinofal 2:1bdcc88f5501 128 // pc.printf("RANDMAX= %d\r\n", RAND_MAX); // scopi diagnostici
pinofal 2:1bdcc88f5501 129
pinofal 2:1bdcc88f5501 130 while(true)
pinofal 2:1bdcc88f5501 131 {
pinofal 2:1bdcc88f5501 132 //++++++ INIZIO Attendi pressione USER_BUTTON per Start Game +++++++
pinofal 2:1bdcc88f5501 133 pc.printf("\r\n*** PRESS Blue Button to START ***\r\n");
pinofal 2:1bdcc88f5501 134 while(myButton ==1)
pinofal 2:1bdcc88f5501 135 {
pinofal 2:1bdcc88f5501 136 //myLed = 1;
pinofal 2:1bdcc88f5501 137 }
pinofal 2:1bdcc88f5501 138 if(myButton ==0)
pinofal 2:1bdcc88f5501 139 {
pinofal 2:1bdcc88f5501 140 while(myButton ==0){};
pinofal 2:1bdcc88f5501 141 //myLed = 0;
pinofal 2:1bdcc88f5501 142 //BadScoreMessage();
pinofal 2:1bdcc88f5501 143 //GoodScoreMessage();
pinofal 2:1bdcc88f5501 144 }
pinofal 2:1bdcc88f5501 145 //++++++ FINE Attendi pressione USER_BUTTON per Start Game +++++++
pinofal 2:1bdcc88f5501 146
pinofal 2:1bdcc88f5501 147 //++++++ INIZIO degli step del gioco +++++++++++++++++++++
pinofal 2:1bdcc88f5501 148 myTimer.start(); // avvia il timer
pinofal 2:1bdcc88f5501 149 for(nStepIndex =0; nStepIndex < GAMESTEPNUMBER; nStepIndex++)
pinofal 2:1bdcc88f5501 150 {
pinofal 2:1bdcc88f5501 151 pc.printf("\r\nINIZIO FASE %d\r\n",nStepIndex); // scopi diagnostici
pinofal 2:1bdcc88f5501 152
pinofal 2:1bdcc88f5501 153 //rand() fissa sempre la stessa sequenza di numeri patendo da 1,
pinofal 2:1bdcc88f5501 154 //srand(seed) fissa il numero di partenza, seed, ma la sequenza è sempre la stessa
pinofal 2:1bdcc88f5501 155 // per generare una sequenza diversa partendo da un numero diverso il seed lo imposto leggendo l'orologio di sistema (p.e. timer)
pinofal 2:1bdcc88f5501 156 // RAND_MAX = 2147483647
pinofal 2:1bdcc88f5501 157 nSeed = unsigned(myTimer.read_ms()% RAND_MAX); // resto della divisione timer_read_us() / RAND_MAX
pinofal 2:1bdcc88f5501 158 srand(nSeed);
pinofal 2:1bdcc88f5501 159 // calcola il tempo da aggiungere come parte variabile al tempo tra uno step e l'altro
pinofal 2:1bdcc88f5501 160 fDelay = (nMultiplier * (float(rand()) / RAND_MAX));
pinofal 2:1bdcc88f5501 161 // pc.printf("\r\ndelay float = %f\r\n", fDelay); // scopi diagnostici
pinofal 2:1bdcc88f5501 162 nDelay = int(fDelay);
pinofal 2:1bdcc88f5501 163 pc.printf("delay [msec] = %d\r\n", nDelay); // scopi diagnostici
pinofal 2:1bdcc88f5501 164
pinofal 2:1bdcc88f5501 165 // se il ritardo è maggiore di 500, dividilo per 3 fino a quando non diventa inferiore a 5000
pinofal 2:1bdcc88f5501 166 while(nDelay > 500)
pinofal 2:1bdcc88f5501 167 {
pinofal 2:1bdcc88f5501 168 nDelay /= 3;
pinofal 2:1bdcc88f5501 169 }
pinofal 2:1bdcc88f5501 170
pinofal 2:1bdcc88f5501 171 // se il ritardo è minore di 100, moltiplicalo per 2 fino a quando non diventa maggiore di 100
pinofal 2:1bdcc88f5501 172 while(nDelay < 50)
pinofal 2:1bdcc88f5501 173 {
pinofal 2:1bdcc88f5501 174 nDelay *= 2;
pinofal 2:1bdcc88f5501 175 }
pinofal 2:1bdcc88f5501 176 // tra uno step e l'altro attendi (TIMEBETWEEN + nDelay) [msec]. In questo modo il giocatore non può memorizzare i tempi di risposta
pinofal 2:1bdcc88f5501 177 wait_ms(TIMEBETWEEN+nDelay);
pinofal 2:1bdcc88f5501 178 pc.printf("Tempo tra due step [ms] = %d\r\n", (TIMEBETWEEN+nDelay)); // scopi diagnostici
pinofal 2:1bdcc88f5501 179
pinofal 2:1bdcc88f5501 180 // Accendi il LED per un tempo pari a una parte fissa in naStepDuration[nStepIndex] e una parte random pari a nDelay
pinofal 2:1bdcc88f5501 181 myLed=1; // Accendi LED
pinofal 2:1bdcc88f5501 182 nStartTimeGame = myTimer.read_ms();
pinofal 2:1bdcc88f5501 183 nElapsedTimeGame=0; // inizializza tempo trascorso
pinofal 2:1bdcc88f5501 184 // attendi fino alla pressione del pulsante/piezo oppure al timeout. Il timeout è fissato nell'array naStepDuration[]. mYButton diventa '0' alla pressione
pinofal 2:1bdcc88f5501 185 while( (nElapsedTimeGame < naStepDuration[nStepIndex]) && (myButton == 1))
pinofal 2:1bdcc88f5501 186 {
pinofal 2:1bdcc88f5501 187 // misura il tempo trascorso da StartTimeGame
pinofal 2:1bdcc88f5501 188 nCurrentTimeGame = myTimer.read_ms();
pinofal 2:1bdcc88f5501 189 nElapsedTimeGame= nCurrentTimeGame-nStartTimeGame;
pinofal 2:1bdcc88f5501 190 }
pinofal 2:1bdcc88f5501 191 myLed=0; // Spegni LED
pinofal 2:1bdcc88f5501 192 // memorizza lo score guadagnato nello Step
pinofal 2:1bdcc88f5501 193 naStepScore[nStepIndex] = nElapsedTimeGame;
pinofal 2:1bdcc88f5501 194
pinofal 2:1bdcc88f5501 195 pc.printf("StepDuration= %d; Elapsed= %d\r\n", naStepDuration[nStepIndex], nElapsedTimeGame); //scopi diagnostici
pinofal 2:1bdcc88f5501 196
pinofal 2:1bdcc88f5501 197 // calcola lo score in percentuale della durata step. fScore = (durata dello step-tempo trascorso)/ durata dello step.
pinofal 2:1bdcc88f5501 198 fScore = ((float)(naStepDuration[nStepIndex] - naStepScore[nStepIndex])/(float)naStepDuration[nStepIndex])*100.0;
pinofal 2:1bdcc88f5501 199 pc.printf("Score [%%] %.2f \r\n",fScore); //scopi diagnostici
pinofal 2:1bdcc88f5501 200
pinofal 2:1bdcc88f5501 201 if(fScore <=0) // il tempo di risposta è stato superiore alla durata
pinofal 2:1bdcc88f5501 202 {
pinofal 2:1bdcc88f5501 203 // accendi LED RED relativo alla fase in cui ci si trova
pinofal 2:1bdcc88f5501 204 pc.printf("BAD :( :( :( \r\n"); // il giocatore ha risposto dopo la scadenza del timer
pinofal 2:1bdcc88f5501 205 BadScoreMessage();
pinofal 2:1bdcc88f5501 206 }
pinofal 2:1bdcc88f5501 207 if((fScore > 0) && (fScore <= 50))
pinofal 2:1bdcc88f5501 208 {
pinofal 2:1bdcc88f5501 209 // accendi LED YELLOW relativo alla fase in cui ci si trova
pinofal 2:1bdcc88f5501 210 pc.printf("SO-SO !!! \r\n"); // il giocatore ha risposto in un tempo intermedio
pinofal 2:1bdcc88f5501 211 BadScoreMessage();
pinofal 2:1bdcc88f5501 212 }
pinofal 2:1bdcc88f5501 213 if(fScore > 50)
pinofal 2:1bdcc88f5501 214 {
pinofal 2:1bdcc88f5501 215 // accendi LED VERDE relativo alla fase in cui ci si trova
pinofal 2:1bdcc88f5501 216 pc.printf("GOOD :) :) :) \r\n"); // il giocatore ha risposto prima della scadenza del timer
pinofal 2:1bdcc88f5501 217 GoodScoreMessage();
pinofal 2:1bdcc88f5501 218 }
pinofal 2:1bdcc88f5501 219
pinofal 2:1bdcc88f5501 220 }
pinofal 2:1bdcc88f5501 221
pinofal 2:1bdcc88f5501 222 }
pinofal 2:1bdcc88f5501 223 }