Cronometro TM1637

Ringraziando tutti per l'aiuto ricevuto, ci tengo ad allegare le foto del risultato finito.

A banco funziona tutto alla perfezione: la misura delle distanze, il cronometro, parziali, totali, azzeramento, ecc.
Purtroppo però, montando lo strumento ed il sensore in macchina nella posizione definitiva, qualcosa non quadra, probabilmente a causa di disturbi elettromagnetici.

Riflettendoci, pur senza un'adeguata conoscenza del fenomeno, credo che le possibili cause possano essere:

  • disturbi nell'alimentazione
  • disturbi nel cavo del sensore
  • disturbi direttamente su Arduino (posizionato nel cruscotto, a poca distanza da bobine, candele, ecc)

Per quanto riguarda il primo punto, ho provveduto ad alimentare Arduino tramite un piccolo trasformatore ed una prolunga dalla rete di casa, ma i disturbi, che si manifestano in un aumento della distanza pur restando fermi, o un azzeramento pur senza premere il relativo pulsante, non sembrano diminuire. Non mi sento di escludere l'alimentazione dalle cause, ma sicuramente non è il problema principale.

Domani proverò ad utilizzare un altro sensore, collegandolo provvisoriamente allo strumento e tenendo a mano il cavo dentro l'abitacolo, lontano dal motore, così da capire se possa essere il cavo non schermato la fonte dei disturbi. In caso positivo provvederò ad utilizzare un cavo con schermatura.

Se invece dovesse essere proprio la troppa vicinanza di Arduino al motore che crea problemi? Si può risolvere rivestendo il case con nastro alluminio e mettendolo a massa?

Allego infine il codice definitivo, con solo qualche lievissimo ritocco dall'ultimo postato.

////////////////////////////////////////////////////////////////////////////////// T R I P M A S T E R //////////////////////////////////////////////////////////////////////////////////

#include <TM1637Display.h>
#define CLK1 12
#define DIO1 11
#define CLK2 10
#define DIO2 9
TM1637Display display1(CLK1, DIO1);
TM1637Display display2(CLK2, DIO2);

const byte switch_1 = 3;                // switch tra dist - time               ---->  lo switch avviene mandando a massa i pin per poter utilizzare la resistenza di pullup interna
const byte switch_3 = 4;                // switch tra avanti - indietro
const byte switch_4 = 5;                // switch tra a - b
const byte azzera   = 6;                // azzeramento                          ---->  l'azzeramento avviene mandando a massa il pin per poter utilizzare la resistenza di pullup interna

float trip_a, trip_b, odo;
unsigned long t_parz_a, t_parz_b, t_tot;
unsigned long t0_a = 0, t0_b = 0, t_disp = 0;

volatile long a = 0;                    // a --> trip a
volatile long b = 0;                    // b --> trip b
volatile unsigned long c = 0;           // c --> odo

const float rap  = 9.0 / 37.0;          // 11.0/43.0 --> 43 giri albero = 11 giri ruota  rapporto coppie coniche differenziale sj410
const float circ = 2.1;                 // [m]
const float dist = circ * rap;          // PER VERIFICARE: misurare spazio noto e visualizzare la variabile a ---> dist = spazio/a

const int azzeraDelay = 250;


void contatore() {
  if (digitalRead(switch_3) == LOW) {      // marcia avanti
    a++;
    b++;
  }
  if (digitalRead(switch_3) == HIGH) {     // marcia indietro
    a--;
    b--;
  }
  c++;
}


void setup() {
  
  //Serial.begin(9600);
  
  pinMode(switch_1, INPUT_PULLUP);
  pinMode(switch_3, INPUT_PULLUP);
  pinMode(switch_4, INPUT_PULLUP);
  pinMode(azzera, INPUT_PULLUP);

  display1.setBrightness(7, true);
  display2.setBrightness(7, true);

  attachInterrupt(0, contatore, RISING);             // interrupt 0 = pin D2   interrupt 1 = pin D3
}


void loop() {

  trip_a = a * dist;                                 // [m]
  trip_b = b * dist;                                 // [m]
  odo = c * dist / 1000;                             // [km]

  t_parz_a = (millis() - t0_a) / 1000;               // [s]
  t_parz_b = (millis() - t0_b) / 1000;               // [s]
  t_tot = millis() / 1000;                           // [s]

  //Serial.println(a);

  if (digitalRead(switch_1) == LOW) {                             // visualizza le distanze su schermo 1 e 2
    display2.showNumberDec(odo);

    if (digitalRead(switch_4) == LOW) {                           // visualizza trip_a su schermo 1
      display1.showNumberDec(trip_a);
    }

    if (digitalRead(switch_4) == HIGH) {                          // visualizza trip_b su schermo 1
      display1.showNumberDec(trip_b);
    }
  }

  if (digitalRead(switch_1) == HIGH) {                            // visualizza i tempi su schermo 1 e 2

    int ore_tot = t_tot / 3600;
    int minuti_tot = t_tot % 3600 / 60;
    int disp_tot = ore_tot * 100 + minuti_tot;

    int minuti_a = t_parz_a / 60;
    int secondi_a = t_parz_a % 60;
    int disp_a = minuti_a * 100 + secondi_a;

    int minuti_b = t_parz_b / 60;
    int secondi_b = t_parz_b % 60;
    int disp_b = minuti_b * 100 + secondi_b;

    if (millis() - t_disp >= 1000) {

      t_disp = millis();

      display2.showNumberDecEx(disp_tot, 0b11100000, true);

      if (digitalRead(switch_4) == LOW) {                         // visualizza t_parz_a su schermo 1
        display1.showNumberDecEx(disp_a, 0b11100000, true);
      }

      if (digitalRead(switch_4) == HIGH) {                        // visualizza t_parz_b su schermo 1
        display1.showNumberDecEx(disp_b, 0b11100000, true);
      }
    }
  }

  if (digitalRead(azzera) == LOW) {

    delay(azzeraDelay);

    if (digitalRead(azzera) == LOW && digitalRead(switch_1) == LOW && digitalRead(switch_4) == LOW) {
      a = 0;
    }

    if (digitalRead(azzera) == LOW && digitalRead(switch_1) == LOW && digitalRead(switch_4) == HIGH) {
      b = 0;
    }

    if (digitalRead(azzera) == LOW && digitalRead(switch_1) == HIGH && digitalRead(switch_4) == LOW) {
      t0_a = millis();
    }

    if (digitalRead(azzera) == LOW && digitalRead(switch_1) == HIGH && digitalRead(switch_4) == HIGH) {
      t0_b = millis();
    }
  }

}

Ancora una volta grazie.