Arduino - 21

# Esercizi - 03 - misura dei riflessi

# esercizio_03_riflessi.ino

    /* esercizio_03_riflessi
     * test del display sullo shield arduino.
     * accende per 250mS ogni segmento ed il punto
     *
     * Connessioni dello shield e
     *
     * Digital 2 - In   Tasto S3
     * Digital 4 [3] - Out  Segmento e
     * Digital 3 [4]4 - In   Tasto S2
     * Digital 5 - Out  Segmento d
     * Digital 6 - Out  Segmento c
     * Digital 7 - Out  dp - Punto Decimale
     * Digital 8 - In   Tasto S1
     * Digital 9 - Out  Segmento b
     * Digital 10 - Out Segmento a
     * Digital 11 - Out Segmento f
     * Digital 12 - Out Segmento g
     * Analog 0 - Fotoresistenza - Luce
     * Analog 1 - NTC - Temperatura
     *     --a--
     *    |     |
     *    f     b
     *    |     |
     *     --g--
     *    |     |
     *    e     c
     *    |     |
     *     --d--  dp
     */

    #define NUMPROVE  10

    #define LEDPIN  13

    #define  APIN   10
    #define  BPIN   9
    #define  CPIN   6
    #define  DPIN   5
    #define  EPIN   4 /* 3 */
    #define  FPIN   11
    #define  GPIN   12
    #define  DPPIN  7
    #define  S1PIN  8
    #define  S2PIN  3 /* 4 */
    #define  S3PIN  2
    #define  LUCE   1
    #define  TEMP   0

    #define  NUMSEGS  8

    /* Array dei numeri di piedino, per ogni segmento del display */
    char segments [] = {
      APIN,
      BPIN,
      CPIN,
      DPIN,
      EPIN,
      FPIN,
      GPIN,
      DPPIN
    };

    /* Matrice di decodifica da esadecimale allo stato dei segmenti */
    boolean cifre [16][7] = {
    // a     b      c      d      e      f      g
      {true,  true,  true,  true,  true,  true,  false },  // 0
      {false, true,  true,  false, false, false, false },  // 1
      {true,  true,  false, true,  true,  false, true },   // 2
      {true,  true,  true,  true,  false, false, true },   // 3
      {false, true,  true,  false, false, true,  true },   // 4
      {true,  false, true,  true,  false, true,  true },   // 5
      {true,  false, true,  true,  true,  true,  true },   // 6
      {true,  true,  true,  false, false, false, false },  // 7
      {true,  true,  true,  true,  true,  true,  true },   // 8
      {true,  true,  true,  true,  false,  true,  true },  // 9
      {true,  true,  true,  false, true,  true,  true },   // A
      {false, false, true,  true,  true,  true,  true },   // B
      {true,  false, false, true,  true,  true,  false },  // C
      {false, true,  true,  true,  true,  false,  true },  // D
      {true,  false, false, true,  true,  true,  true },   // E
      {true,  false, false, false, true,  true,  true },   // F
    };

    void setup () {
      int i;

      for (i = 0; i < NUMSEGS; i++) {
        pinMode(segments [i], OUTPUT);      // Imposta il piedino del segmento a in uscita
        digitalWrite(segments [i], HIGH);   // Spegne il LED
      }
      Serial.begin (9600);                  // Imposta la velocita' della seriale
      randomSeed(analogRead(5));           // Inizializza il generatore di numeri seriali
    }

    /* Funzione che visualizza un numero sul display
     * Parametri:
     * n -> il numero da visualizzare (limitato a 0-15)
     * Ritorna:
     * niente
     */
    void digit (int n) {
      int i;
      n = n % 16;  // limita ad una cifra
      for (i = 0; i < 7; i++) {
        digitalWrite(segments [i], (cifre[n][i]) ? LOW : HIGH);   // Accende il LED
      }
    }

    void resetDisp () {
      int i;

      for (i = 0; i < NUMSEGS; i++) {
        digitalWrite(segments [i], HIGH);   // Spegne il LED
      }
    }

    void loop () {
      int i = 0;
      int side;
      long startTime = micros ();
      long totale = 0;
      long minimo = 10000000;
      long massimo = 0;

      resetDisp ();                  // Spengo il display
      digitalWrite(APIN, LOW);       // Accendo il segmento "a"

      while (digitalRead(S2PIN)) {  // Attendo che venga premuto il tasto "START" (S2)
        if (micros () > startTime + 1000000) { // Ogni secondo
          // Cmbio il segmento acceso, tra quelli orizzontali
          startTime = micros ();
          switch (i++ % 3) {
            case 0:
              digitalWrite(APIN, HIGH);
              digitalWrite(GPIN, LOW);
              break;
            case 1:
              digitalWrite(GPIN, HIGH);
              digitalWrite(DPIN, LOW);
              break;
            case 2:
              digitalWrite(DPIN, HIGH);
              digitalWrite(APIN, LOW);
              break;
          }
        }
      }

      delay(10);  // Ritardo per attendere la fine dei rimbalzi
      if (!digitalRead(S2PIN)) {  // Il tasto e' ancora premuto
        while (!digitalRead(S2PIN));  // Attende il rilascio
      }

      for (i=0; i < NUMPROVE; i++) {  // Ripeto per "NUMPROVE" volte la prova di riflesso
        int bottone;
        resetDisp ();                 // Spengo il display
        delay (random (1500,2500));   // Attendo un tempo casuale tra 1,5 e 2 secondi
        if (random (2)) {             // seleziono un lato a caso
          digitalWrite(EPIN, LOW);    // Accendo il lato sinistro (segmenti "e" e "f")
          digitalWrite(FPIN, LOW);
          bottone=S3PIN;              // e seleziono il pulsante sinistro
        } else {
          digitalWrite(BPIN, LOW);    // Accendo il lato destro (segmenti "b" e "c")
          digitalWrite(CPIN, LOW);
          bottone=S1PIN;              // e seleziono il pulsante destro
        }

        startTime = micros ();        // registro il momento dell'inizio dell'attesa

        if (digitalRead(S1PIN) && digitalRead(S3PIN)) {      // Se non c'Ã¨ nessun bottone premuto al momento (falsa partenza)
          while (digitalRead(S1PIN) && digitalRead(S3PIN));  // Attende fino a che non viene premuto S1 o S3

          if (!digitalRead(S1PIN) && !digitalRead(S3PIN)) {
            i --;  // Tasti premuti insieme - salto la prova
          } else {
            if (!digitalRead(bottone)) {              // Se il bottone premuto Ã¨ quello giusto
              long riflesso = micros () - startTime;  // calcolo quanto tempo Ã¨ passato
              totale += riflesso;                     // Sommo il tempo attuale a quello delle aptrre prove
              if (riflesso < minimo) {                // guardo se il tempo attuale Ã¨ il nuovo minimo
                minimo = riflesso;                    // se lo Ã¨, aggiorno il minimo
              }
              if  (riflesso > massimo) {              // guardo se il tempo attuale Ã¨ il nuovo massimo
                massimo = riflesso;                   // se lo Ã¨, aggiorno il massimo
              }
            } else {
              i--; // bottone sbagliato - ripeto la prova
            }
          }

        } else {
          i--;  // Era giÃ  premuto, quindi ripeto la prova
        }
        while (!digitalRead(S1PIN) || !digitalRead(S3PIN));  // Attende fino a che non viene rilasciato S1 o S3
      }
      /* Stampa il risultato sul terminale */
      Serial.print ("Riflesso minimo = ");
      Serial.print (minimo);
      Serial.print (" massimo = ");
      Serial.print (massimo);
      Serial.print (" media = ");
      Serial.println (totale / NUMPROVE);

      /* Stampa il risultato sul display */
      digit (totale / 50000 / NUMPROVE);
      delay (2500);
    }

© Ing. Stefano Salvi - released under FDL licence