Amaldi / Mbed 2 deprecated Amaldi_16_Exercise_Game_rev3

Dependencies:   mbed

Committer:
pinofal
Date:
Wed Dec 05 15:50:10 2018 +0000
Revision:
3:58b0cfe9cc3a
Parent:
2:1bdcc88f5501
exercise 16

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 3:58b0cfe9cc3a 3 #include "SampledSoundBadScore_Dummy.h"
pinofal 3:58b0cfe9cc3a 4 #include "SampledSoundGoodScore_Dummy.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 3:58b0cfe9cc3a 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 3:58b0cfe9cc3a 61 // valore letto dall'ADC
pinofal 3:58b0cfe9cc3a 62 unsigned short usReadADC;
pinofal 3:58b0cfe9cc3a 63
pinofal 3:58b0cfe9cc3a 64 // Sensore Piezo su cui bisogna colpire per dare risposta
pinofal 3:58b0cfe9cc3a 65 AnalogIn InPiezo(PA_0);
pinofal 3:58b0cfe9cc3a 66
pinofal 2:1bdcc88f5501 67 // output analogico per i messaggi audio
pinofal 2:1bdcc88f5501 68 AnalogOut OutWave(PA_4);
pinofal 2:1bdcc88f5501 69
pinofal 3:58b0cfe9cc3a 70 // Uscita LED per sollecitare la risposta del giococatore
pinofal 3:58b0cfe9cc3a 71 DigitalOut TriggerLED (PC_10);
pinofal 3:58b0cfe9cc3a 72
pinofal 2:1bdcc88f5501 73 /****************************************/
pinofal 2:1bdcc88f5501 74 /* Gnerazione AudioMesaggio Good Result */
pinofal 2:1bdcc88f5501 75 /****************************************/
pinofal 2:1bdcc88f5501 76 void GoodScoreMessage(void)
pinofal 2:1bdcc88f5501 77 {
pinofal 2:1bdcc88f5501 78 //++++++++++++ INIZIO generazione messaggio di GoodScore +++++++++++++++++
pinofal 2:1bdcc88f5501 79 fAmpGoodScoreSound = 1.0; // fissa l'amplificazione per il messaggio di GoodScore. Valori da 0[min] a 1[max]
pinofal 2:1bdcc88f5501 80 fFreqGoodScoreSound=nSamplePerSecGoodScore/nUnderSampleFactorGoodScore;// campioni per secondo del GoodScore message da generare = nSamplePerSec/nUnderSampleFactor
pinofal 2:1bdcc88f5501 81 fDeltaTGoodScoreSound = (1.0/fFreqGoodScoreSound); // fFreq dipende dal periodo di campionamento e dal fattore di sottocampionamento
pinofal 2:1bdcc88f5501 82
pinofal 2:1bdcc88f5501 83
pinofal 2:1bdcc88f5501 84 for(nGoodScoreMsgIndex=0; nGoodScoreMsgIndex < nSampleNumGoodScore; nGoodScoreMsgIndex++)
pinofal 2:1bdcc88f5501 85 {
pinofal 2:1bdcc88f5501 86 // mette in output un campione della forma d'onda del GoodScore message moltiplicato per l'amplificazione fAmp
pinofal 2:1bdcc88f5501 87 OutWave.write_u16(naInputSoundWaveGoodScore[nGoodScoreMsgIndex]*fAmpGoodScoreSound);
pinofal 2:1bdcc88f5501 88
pinofal 2:1bdcc88f5501 89 // tra un campione e l'altro attendi un periodo pari al periodo di campionamento
pinofal 2:1bdcc88f5501 90 //wait(fDeltaTGoodScoreSound);
pinofal 2:1bdcc88f5501 91 wait_us(30);
pinofal 2:1bdcc88f5501 92 }
pinofal 2:1bdcc88f5501 93 //++++++++++++ FINE generazione messaggio di GoodScore +++++++++++++++++
pinofal 2:1bdcc88f5501 94 }
pinofal 2:1bdcc88f5501 95
pinofal 2:1bdcc88f5501 96 /****************************************/
pinofal 2:1bdcc88f5501 97 /* Gnerazione AudioMesaggio Good Result */
pinofal 2:1bdcc88f5501 98 /****************************************/
pinofal 2:1bdcc88f5501 99 void BadScoreMessage(void)
pinofal 2:1bdcc88f5501 100 {
pinofal 2:1bdcc88f5501 101 //++++++++++++ INIZIO generazione messaggio di BadScore +++++++++++++++++
pinofal 2:1bdcc88f5501 102 fAmpBadScoreSound = 1.0; // fissa l'amplificazione per il messaggio di BadScore. Valori da 0[min] a 1[max]
pinofal 2:1bdcc88f5501 103 fFreqBadScoreSound=nSamplePerSecBadScore/nUnderSampleFactorBadScore;// campioni per secondo del BadScore message da generare = nSamplePerSec/nUnderSampleFactor
pinofal 2:1bdcc88f5501 104 fDeltaTBadScoreSound = (1.0/fFreqBadScoreSound); // fFreq dipende dal periodo di campionamento e dal fattore di sottocampionamento
pinofal 2:1bdcc88f5501 105
pinofal 2:1bdcc88f5501 106
pinofal 2:1bdcc88f5501 107 for(nBadScoreMsgIndex=0; nBadScoreMsgIndex < nSampleNumBadScore; nBadScoreMsgIndex++)
pinofal 2:1bdcc88f5501 108 {
pinofal 2:1bdcc88f5501 109 // mette in output un campione della forma d'onda del BadScore message moltiplicato per l'amplificazione fAmp
pinofal 2:1bdcc88f5501 110 OutWave.write_u16(naInputSoundWaveBadScore[nBadScoreMsgIndex]*fAmpBadScoreSound);
pinofal 2:1bdcc88f5501 111
pinofal 2:1bdcc88f5501 112 // tra un campione e l'altro attendi un periodo pari al periodo di campionamento
pinofal 2:1bdcc88f5501 113 //wait(fDeltaTBadScoreSound);
pinofal 2:1bdcc88f5501 114 wait_us(30);
pinofal 2:1bdcc88f5501 115 }
pinofal 2:1bdcc88f5501 116 //++++++++++++ FINE generazione messaggio di BadScore +++++++++++++++++
pinofal 2:1bdcc88f5501 117 }
pinofal 2:1bdcc88f5501 118
pinofal 2:1bdcc88f5501 119 /********/
pinofal 2:1bdcc88f5501 120 /* MAIN */
pinofal 2:1bdcc88f5501 121 /********/
pinofal 2:1bdcc88f5501 122 int main()
pinofal 2:1bdcc88f5501 123 {
pinofal 2:1bdcc88f5501 124 // velocità di comunicazione sulla seriale con PC
pinofal 2:1bdcc88f5501 125 pc.baud(921600);
pinofal 2:1bdcc88f5501 126
pinofal 2:1bdcc88f5501 127 // messaggio di benvenuto
pinofal 2:1bdcc88f5501 128 pc.printf("\r\nHallo Amaldi Students - Exercise 16 \r\n");
pinofal 2:1bdcc88f5501 129 pc.printf("\r\n*** Let's Play ***\r\n");
pinofal 2:1bdcc88f5501 130
pinofal 2:1bdcc88f5501 131
pinofal 3:58b0cfe9cc3a 132 // inizialmente spegne i LED
pinofal 3:58b0cfe9cc3a 133 myLED=0;
pinofal 3:58b0cfe9cc3a 134 TriggerLED=0;
pinofal 2:1bdcc88f5501 135
pinofal 3:58b0cfe9cc3a 136 //++++++++++++++++++++++++++++++++++++++++++++++++++
pinofal 3:58b0cfe9cc3a 137 //++++++++++++ INIZIO CICLO PRINCIPALE ++++++++++++
pinofal 3:58b0cfe9cc3a 138 //++++++++++++++++++++++++++++++++++++++++++++++++++
pinofal 2:1bdcc88f5501 139 while(true)
pinofal 2:1bdcc88f5501 140 {
pinofal 2:1bdcc88f5501 141 //++++++ INIZIO Attendi pressione USER_BUTTON per Start Game +++++++
pinofal 2:1bdcc88f5501 142 pc.printf("\r\n*** PRESS Blue Button to START ***\r\n");
pinofal 2:1bdcc88f5501 143 while(myButton ==1)
pinofal 3:58b0cfe9cc3a 144 {}
pinofal 2:1bdcc88f5501 145 if(myButton ==0)
pinofal 2:1bdcc88f5501 146 {
pinofal 2:1bdcc88f5501 147 while(myButton ==0){};
pinofal 2:1bdcc88f5501 148 }
pinofal 2:1bdcc88f5501 149 //++++++ FINE Attendi pressione USER_BUTTON per Start Game +++++++
pinofal 2:1bdcc88f5501 150
pinofal 2:1bdcc88f5501 151 //++++++ INIZIO degli step del gioco +++++++++++++++++++++
pinofal 2:1bdcc88f5501 152 myTimer.start(); // avvia il timer
pinofal 2:1bdcc88f5501 153 for(nStepIndex =0; nStepIndex < GAMESTEPNUMBER; nStepIndex++)
pinofal 2:1bdcc88f5501 154 {
pinofal 2:1bdcc88f5501 155 pc.printf("\r\nINIZIO FASE %d\r\n",nStepIndex); // scopi diagnostici
pinofal 3:58b0cfe9cc3a 156
pinofal 3:58b0cfe9cc3a 157 //+++++++++++ INIZIO calcola ritardo variabile tra uno step e il successivo ++++++++
pinofal 3:58b0cfe9cc3a 158 // pc.printf("RANDMAX= %d\r\n", RAND_MAX); // scopi diagnostici
pinofal 2:1bdcc88f5501 159 //rand() fissa sempre la stessa sequenza di numeri patendo da 1,
pinofal 2:1bdcc88f5501 160 //srand(seed) fissa il numero di partenza, seed, ma la sequenza è sempre la stessa
pinofal 2:1bdcc88f5501 161 // 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 162 // RAND_MAX = 2147483647
pinofal 2:1bdcc88f5501 163 nSeed = unsigned(myTimer.read_ms()% RAND_MAX); // resto della divisione timer_read_us() / RAND_MAX
pinofal 2:1bdcc88f5501 164 srand(nSeed);
pinofal 2:1bdcc88f5501 165 // calcola il tempo da aggiungere come parte variabile al tempo tra uno step e l'altro
pinofal 2:1bdcc88f5501 166 fDelay = (nMultiplier * (float(rand()) / RAND_MAX));
pinofal 2:1bdcc88f5501 167 // pc.printf("\r\ndelay float = %f\r\n", fDelay); // scopi diagnostici
pinofal 2:1bdcc88f5501 168 nDelay = int(fDelay);
pinofal 2:1bdcc88f5501 169 pc.printf("delay [msec] = %d\r\n", nDelay); // scopi diagnostici
pinofal 2:1bdcc88f5501 170
pinofal 3:58b0cfe9cc3a 171 // se il ritardo è minore di 100, moltiplicalo per 2 fino a quando non diventa maggiore di 100
pinofal 3:58b0cfe9cc3a 172 nDelay +=1; // aggiungi sempre 1[msec] al valore del ritardo. Se nDelay=0, nei cicli while successivi potrebbe bloccarsi
pinofal 3:58b0cfe9cc3a 173 while(nDelay < 100)
pinofal 3:58b0cfe9cc3a 174 {
pinofal 3:58b0cfe9cc3a 175 nDelay *= 2;
pinofal 3:58b0cfe9cc3a 176
pinofal 3:58b0cfe9cc3a 177 }
pinofal 3:58b0cfe9cc3a 178
pinofal 2:1bdcc88f5501 179 // se il ritardo è maggiore di 500, dividilo per 3 fino a quando non diventa inferiore a 5000
pinofal 2:1bdcc88f5501 180 while(nDelay > 500)
pinofal 2:1bdcc88f5501 181 {
pinofal 2:1bdcc88f5501 182 nDelay /= 3;
pinofal 2:1bdcc88f5501 183 }
pinofal 2:1bdcc88f5501 184
pinofal 3:58b0cfe9cc3a 185
pinofal 2:1bdcc88f5501 186 // 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 187 wait_ms(TIMEBETWEEN+nDelay);
pinofal 2:1bdcc88f5501 188 pc.printf("Tempo tra due step [ms] = %d\r\n", (TIMEBETWEEN+nDelay)); // scopi diagnostici
pinofal 3:58b0cfe9cc3a 189 //+++++++++++ FINE calcola ritardo variabile tra uno step e il successivo ++++++++
pinofal 2:1bdcc88f5501 190
pinofal 3:58b0cfe9cc3a 191 //+++++++++++ INIZIO Accende LED e attende risposta del giocatore ++++++++
pinofal 2:1bdcc88f5501 192 // Accendi il LED per un tempo pari a una parte fissa in naStepDuration[nStepIndex] e una parte random pari a nDelay
pinofal 3:58b0cfe9cc3a 193 TriggerLED = 1; // Accendi LED di inizio Gioco
pinofal 3:58b0cfe9cc3a 194 myLED = 1; // scopi diagnostici
pinofal 2:1bdcc88f5501 195 nStartTimeGame = myTimer.read_ms();
pinofal 2:1bdcc88f5501 196 nElapsedTimeGame=0; // inizializza tempo trascorso
pinofal 3:58b0cfe9cc3a 197 usReadADC = 0; // inizializza valore letto dall'ADC collegato al piezo
pinofal 3:58b0cfe9cc3a 198 // attendi fino alla pressione del pulsante/piezo oppure al timeout. Il timeout è fissato nell'array naStepDuration[]. Valori molto vassi di Inpiezo sono considerati rumore
pinofal 3:58b0cfe9cc3a 199 while( (nElapsedTimeGame < naStepDuration[nStepIndex]) && (usReadADC < 0x200))
pinofal 2:1bdcc88f5501 200 {
pinofal 2:1bdcc88f5501 201 // misura il tempo trascorso da StartTimeGame
pinofal 2:1bdcc88f5501 202 nCurrentTimeGame = myTimer.read_ms();
pinofal 2:1bdcc88f5501 203 nElapsedTimeGame= nCurrentTimeGame-nStartTimeGame;
pinofal 3:58b0cfe9cc3a 204
pinofal 3:58b0cfe9cc3a 205 // acquisisce risposta dal sensore Piezo
pinofal 3:58b0cfe9cc3a 206 usReadADC = InPiezo.read_u16();
pinofal 3:58b0cfe9cc3a 207 //if(usReadADC > 0x1000)
pinofal 2:1bdcc88f5501 208 }
pinofal 3:58b0cfe9cc3a 209 TriggerLED = 0;// Spegni LED di fine gioco
pinofal 3:58b0cfe9cc3a 210 myLED =0; // scopi diagnostici
pinofal 3:58b0cfe9cc3a 211 pc.printf(" ADC0 = %x \n\r",usReadADC); // scopi diagnostici
pinofal 2:1bdcc88f5501 212 // memorizza lo score guadagnato nello Step
pinofal 2:1bdcc88f5501 213 naStepScore[nStepIndex] = nElapsedTimeGame;
pinofal 3:58b0cfe9cc3a 214 pc.printf("StepDuration= %d; Elapsed= %d\r\n", naStepDuration[nStepIndex], nElapsedTimeGame); //scopi diagnostici
pinofal 3:58b0cfe9cc3a 215 //+++++++++++ FINE Accende LED e attende risposta del giocatore ++++++++
pinofal 2:1bdcc88f5501 216
pinofal 3:58b0cfe9cc3a 217 //+++++++++++ INIZIO Calcola Score ++++++++
pinofal 2:1bdcc88f5501 218 // calcola lo score in percentuale della durata step. fScore = (durata dello step-tempo trascorso)/ durata dello step.
pinofal 2:1bdcc88f5501 219 fScore = ((float)(naStepDuration[nStepIndex] - naStepScore[nStepIndex])/(float)naStepDuration[nStepIndex])*100.0;
pinofal 2:1bdcc88f5501 220 pc.printf("Score [%%] %.2f \r\n",fScore); //scopi diagnostici
pinofal 2:1bdcc88f5501 221
pinofal 2:1bdcc88f5501 222 if(fScore <=0) // il tempo di risposta è stato superiore alla durata
pinofal 2:1bdcc88f5501 223 {
pinofal 2:1bdcc88f5501 224 // accendi LED RED relativo alla fase in cui ci si trova
pinofal 2:1bdcc88f5501 225 pc.printf("BAD :( :( :( \r\n"); // il giocatore ha risposto dopo la scadenza del timer
pinofal 2:1bdcc88f5501 226 BadScoreMessage();
pinofal 2:1bdcc88f5501 227 }
pinofal 2:1bdcc88f5501 228 if((fScore > 0) && (fScore <= 50))
pinofal 2:1bdcc88f5501 229 {
pinofal 2:1bdcc88f5501 230 // accendi LED YELLOW relativo alla fase in cui ci si trova
pinofal 3:58b0cfe9cc3a 231 pc.printf("SO-SO :| :| :| \r\n"); // il giocatore ha risposto in un tempo intermedio
pinofal 2:1bdcc88f5501 232 BadScoreMessage();
pinofal 2:1bdcc88f5501 233 }
pinofal 2:1bdcc88f5501 234 if(fScore > 50)
pinofal 2:1bdcc88f5501 235 {
pinofal 2:1bdcc88f5501 236 // accendi LED VERDE relativo alla fase in cui ci si trova
pinofal 2:1bdcc88f5501 237 pc.printf("GOOD :) :) :) \r\n"); // il giocatore ha risposto prima della scadenza del timer
pinofal 2:1bdcc88f5501 238 GoodScoreMessage();
pinofal 2:1bdcc88f5501 239 }
pinofal 3:58b0cfe9cc3a 240 //+++++++++++ FINE Calcola Score ++++++++
pinofal 2:1bdcc88f5501 241 }
pinofal 3:58b0cfe9cc3a 242 //++++++ FINE degli step del gioco +++++++++++++++++++++
pinofal 3:58b0cfe9cc3a 243 }
pinofal 3:58b0cfe9cc3a 244 //++++++++++++ INIZIO CICLO PRINCIPALE ++++++++++++
pinofal 2:1bdcc88f5501 245 }