Contapunti automatico per biliardino

ciao ragazzi, poco tempo fà ho chiesto nel forum come fare per creare un sensore ir… alla fine l’ho realizzato con un fototransistor e un diodo led dall’altra parte…ho realizzato questo sketch che mi permette di visualizzare su uno schermo il punteggio. oltre a i sensori ho messo anche i pulsanti xke in caso si sbaglia si puo aumentare o diminuire il punteggio manualmente. il tutto funziona…quando passa la palla segna correttamente il punteggio ma a volte succede che passa la palla ma nn segna il punto…nn lo fa spesso xo qualche volta si…ed è fastidioso. quando passa la pallina, controllando con la seriale, effettivamente c’è un notevole abbassamento del segnale, quindi funziona bene, però nn capisco perche a volte nn lo segna…ora vi mostro lo skech…dateci un occhiata per favore…grazieee :slight_smile:

/*
lcd piedini:
RS = 6     PIN7
ENABLE = 8 PIN6
D4 = 13    PIN5
D5 = 14    PIN4
D6 = 15    PIN3
D7 = 16    PIN2
R/W = 7    PIN2
+ = 4
- = 3
VO = 5  PIN +

*/
int count = 0;
int count1 = 0;
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

int sensore1 = 0;
int sensore2 = 1;

unsigned long interval1 = 200;  //Intervallo di tempoLED spento
unsigned long interval2 = 200;  //Intervallo di tempoLED acceso
int value = LOW;  //Valore precedente del LED
long previousMills = 0;  //Memorizza l'ultima volta che il led è stato aggiornato

void setup() {  
    pinMode(13, INPUT);    
    pinMode(12, INPUT);
    pinMode(11, INPUT);
    pinMode(10, INPUT);
    pinMode(9, INPUT);
    pinMode(sensore1,INPUT);
    pinMode(sensore2,INPUT);
     previousMills = millis();
    Serial.begin(9600);
      lcd.begin(16,2);             
   }


void loop() {
    int statoBottone = digitalRead(13); 
    int statoBottone1 = digitalRead(12);   
    int statoBottone2 = digitalRead(11);  
    int statoBottone3 = digitalRead(10);      
    int statoReset = digitalRead(9);
    int valoresensore1 = analogRead(sensore1);
    int valoresensore2 = analogRead(sensore2);

Serial.println(valoresensore1);
  if ((millis() -  previousMills > interval2) &&  value == LOW ){ 
         previousMills = millis();  
        value = HIGH;
        lcd.clear();                  
     }
    if ((millis() -  previousMills > interval1) &&  value == HIGH ){ 
        value = LOW;
        lcd.clear();                  
     }

  lcd.setCursor(0,0);          
  lcd.print("Punteggio:");
  lcd.print("(");
  lcd.print(count);  
  lcd.print("-");  
  lcd.print(count1); 
  lcd.print(")");


    if (valoresensore1 < 4){ Gino();}
    if (valoresensore2 < 9){ Gino1();}
    if (statoBottone == 1) { Blocca(); } 
    if (statoBottone1 == 1) { Blocca1(); }
    if (statoBottone2 == 1) { Blocca2(); }
    if (statoBottone3 == 1) { Blocca3(); } 
    
    if (statoReset == 1) {
        count = 0;
        count1 = 0;
    }
    
    if ( count == 11){
      lcd.setCursor(0,1);
      lcd.print("<=== BLU WINNER!");
      delay(3000);
        count = 0;
        count1 = 0;
    }  if ( count1 == 11){
      lcd.setCursor(0,1);
      lcd.print("RED WINNER! ===>");
       delay(3000);
        count = 0;
        count1 = 0;
    }  if ((count == 0) && (count1 == 0)){
      lcd.setCursor(0,1);
      lcd.print("BUONA PARTITA!!");
    }  if (count < 0){
        count = 0;
    } if(count1 < 0){
        count1 = 0;
    }
}
// conteggio 1 in avanti con pulsante

void Blocca() {  
        int statoBottone = digitalRead(13);  //statoBottone legge il valore digitale dal pin 8
      int statoReset = digitalRead(9);  
        if (statoBottone == 0){
        count++;
        loop();
        }} 

// conteggio 1 indietro con pulsante

void Blocca1() {  
        int statoBottone1 = digitalRead(12);  //statoBottone legge il valore digitale dal pin 8
      int statoReset = digitalRead(9);  
        if (statoBottone1 == 0){
        count--;
        loop();
        } }
      
// conteggio 2 in avanti con pulsante      
        
void Blocca2() {  
        int statoBottone2 = digitalRead(11);  //statoBottone legge il valore digitale dal pin 8
      int statoReset = digitalRead(9);  
        if (statoBottone2 == 0){
        count1++;
        loop();
        }} 

// conteggio 2 indietro con pulsante

void Blocca3() {  
        int statoBottone3 = digitalRead(10);  //statoBottone legge il valore digitale dal pin 8
      int statoReset = digitalRead(9);  
        if (statoBottone3 == 0){
        count1--;
        loop();
        } }

// implementazione conteggio 1 e 2 con sensore infrarosso        
        
        void Gino() {  
        int valoresensore1 = analogRead(sensore1);  //statoBottone legge il valore digitale dal pin 8
      int statoReset = digitalRead(9);  
        if (valoresensore1 > 4){
        count++;
        loop();
        }} 
        void Gino1() {  
        int valoresensore2 = analogRead(sensore2);  //statoBottone legge il valore digitale dal pin 8
      int statoReset = digitalRead(9);  
        if (valoresensore2 > 9){
        count1++;
        loop();
        }}

L'unico dubbio che mi viene è dato dalla presenza dei delay (ma ho dato un'occhiata al volo...); durante l'esecuzione di un delay(3000) per 3 secondi il processore non lavora più e non accetta alcun comando, quindi se l'interruzione avviene durante quel periodo ovviamente viene ignorata. Prova a pensare se può essere quello il problema; se hai il dubbio simula un punto ogni 4 secondi, non dovresti perderne nemmeno uno.

IDE?

Le istruzioni lcd passano attraverso una libreria che possono avere piccoli dalay, perchè non scrivi sul display solo ad avvenuto cambiamento? potresti togliere i print LCD dal loop, anche il serial.print fa perdere un po' di tempo, fai delle prove con
//Serial.begin(9600); anche se nel 1.0 è stato migliorato

sostituisci gli int con byte se sai che le cifre non superano i valori 255, sempre più veloce scrivere in mem 1 byte che 2 byte
quei 2 delay 3000 entrano solo quando la partita è finita e il counter arriva a 11 quindi non è dannoso al loop

Comunque io metterei nel loop solo i controlli dei sensori e in base all'evento salto alla funzione che mi serve

ciao

L' altra possibilitá é che la luce ambientale disturba il sensore.

Questo si puó ovviare usando un segnale modulato e un ricevitore tipo quello del telecomando che fa la demodulazione. I sensori sono per esempio quelli della serie TSOPxxyy dove le cifre yy sono la frequenza in kHz per la quale é dimensionato il filtro interno.

Ciao Uwe

Il funzionamento del codice non mi è chiaro.
Perché richiami la funzione loop() dalle sotto funzioni? Inneschi dei cicli da cui non esci più.
Mi sa tanto di "Goto" di Basichiana memoria.

Quale esempio?
Ciao Uwe

Ciao io sarei partito in modo un po diverso. Invece di utilizzare i pulsanti su ingressi digitali li avrei collegati ad un solo ingresso analogico con un partitore resistivo ora non ho idea di come inviarti un disegno ma se hai interesse ci possiamo provare e,la stessa cosa si potrebbe fare con i sensori,detto questo farei una voce esterna al loop dedicata al display ed ogni volta che ci sarà una variazione del punteggio,tramite il loop gli dai un clearDisplay e gli comunichi i nuovi dati da scrivere.In questo modo non devi avere nessun delay nel loop di conseguenza non dovresti perdere nessuna variazione dei pulsanti o dei sensori .E' buttata giù a spanne ma ho usato un sistema simile per comandare display controllo toni e volume con dei vari menù per un finale integrato che feci qualche mese fa ed era risultato ben funzionante.