Problema con un progetto

Buongiorno
Sto facendo un progetto con una scheda Arduino Uno R3 che deve gestire una gara di riflessi tra due concorrenti, A e B che utilizzano un pulsante e un LED rosso per ogni concorrente, un pulsante di start con un LED verde, un buzzer e uno schermo LCD.
Il funzionamento del circuito è:

  • Il LED verde si accende
  • Quando si preme il pulsante di start il LED verde si spegne per un tempo di durata casuale (3 - 8 secondi)
  • Al termine del tempo suona il buzzer e si riaccende il LED verde
  • Il primo concorrente che preme il proprio pulsante vince: il suo LED lampeggia e il buzzer suona sincrono col LED per 5 volte
  • Se alla fine del tempo casuale uno dei due concorrenti sta già premendo il pulsante, vince l'altro, se ha premuto correttamente
  • Quando uno dei due concorrenti raggiunge 5 punti, lampeggiano 10 volte il display e il LED e il buzzer alterna due note

Lo schermo LCD serve per far vedere il punteggio dei due concorrenti e far vedere chi ha vinto.

Ho scritto lo sketch e ho costruito il circuito sulla Bread Board stando attento ai collegamenti, ma durate l'esecuzione del programma c'è un problema

  • Premo il pulsante di start
  • Non fa quasi tempo a riaccendersi il LED verde che in automatico assegna il punto al concorrente B

Ho provato a cambiare il pulsante e i cavi verificando che tutto funzionasse ma il problema è rimasto; facendo una simulazione su un programma e rifacendo gli stessi collegamenti tutto funzionava.
Quindi non saprei cosa fare

grazie, buona giornata

#include <LiquidCrystal.h>
LiquidCrystal lcd(12 ,11 ,5 ,4 ,3 ,2 );

const int pinPulsA = 0;
const int pinPulsB = 6;
const int pinPuls_Start = 13;
const int pinLedA = 8;
const int pinLedB = 10;
const int pinLed_Start = 9;
const int buzzer = 7;
const int maxPunti = 5;

bool pulsA;
bool pulsB;
bool puls_Start;
int puntiA;
int puntiB;
int nota;

void setup() {
lcd.begin(16, 2);
pinMode(pinPulsA, INPUT_PULLUP);
pinMode(pinPulsB, INPUT_PULLUP);
pinMode(pinPuls_Start, INPUT_PULLUP);
pinMode(pinLedA, OUTPUT);
pinMode(pinLedB, OUTPUT);
pinMode(pinLed_Start, OUTPUT);
pinMode(buzzer, OUTPUT);

randomSeed(analogRead(0));

lcd.setCursor(0, 0);
lcd.print("Winner");
lcd.setCursor(9, 0);
lcd.print("A=");
lcd.setCursor(9, 1);
lcd.print("B=");

}

void loop() {

digitalWrite(pinLed_Start, HIGH);

do {

  puls_Start = digitalRead(pinPuls_Start);
} while (puls_Start == 1);

digitalWrite(pinLed_Start, LOW);
delay(random(3000, 8000));
pulsA = digitalRead(pinPulsA);
pulsB = digitalRead(pinPulsB); 
tone(buzzer, 262);
digitalWrite(pinLed_Start, HIGH);

if(pulsA == 0 || pulsB == 0) {
  if(pulsA == 0 && pulsB == 1) vincitore(pinLedB);
  if(pulsA == 1 && pulsB == 0) vincitore(pinLedA);
  if(pulsA == 0 && pulsB == 0) {
    lcd.setCursor(2, 1);
    lcd.print("NULL");
    delay(4000);
    lcd.setCursor(2, 1);
    lcd.print("    ");
  }
}

else {
  do {

   pulsA = digitalRead(pinPulsA);
   pulsB = digitalRead(pinPulsB);
  } while(pulsA && pulsB);

  if(pulsA == 0) vincitore(pinLedA);
  if(pulsB == 0) vincitore(pinLedB);

}

noTone(buzzer);
}

void vincitore(int winner) {

  digitalWrite(pinLed_Start, LOW);

  if(winner==pinLedA) {
    lcd.setCursor(3, 1);
    lcd.print("A");
    puntiA++;
    nota=440;
  }

  if(winner==pinLedB) {
    lcd.setCursor(3, 1);
    lcd.print("B");
    puntiB++;
    nota=587;
  }

  lcd.setCursor(11, 0);
  lcd.print(puntiA);
  lcd.setCursor(11, 1);
  lcd.print(puntiB);

  if(puntiA == maxPunti || puntiB == maxPunti) {
    
    for(int cont = 1; cont<=10; cont++) {
      tone(buzzer, 587);
      digitalWrite(winner, HIGH);
      lcd.noDisplay();
      delay(500);
      tone(buzzer, 440);
      digitalWrite(winner, LOW);
      lcd.display();
      delay(500);
    }

    lcd.setCursor(3, 1);
    lcd.print(" ");
    lcd.setCursor(11, 0);
    lcd.print("0");
    lcd.setCursor(11, 1);
    lcd.print("0");
    puntiA = 0;
    puntiB = 0;
  }

  else {
    for(int cont = 1; cont<=5; cont++) {
      tone(buzzer, nota);
      digitalWrite(winner, HIGH);
      delay(500);
      noTone(buzzer);
      digitalWrite(winner, LOW);
      delay(500);
    }
  }
}

Ho cominciato a pensare che fosse un problema di Arduino.
Spero che qualcuno possa aiutarmi, grazie

Non trovo errori nel codice. Però evita di usare i pin 0 e 1 che fanno
capo alla seriale. Da questi pin arriva lo sketch quando premi "upload". Ad esempio pinPulsA è il pin 0, usane un altro.

A seguire ti lascio due link di applicazioni simili sul simulatore online wokwi.

Ciao.

È quello l'errore
La seriale ttl è attiva bassa, risulta pulsante sempre premuto

Per lo op
Poi ci sono altri problemi nella logica
Quel programma andrà molto riparato per farlo andare
Riscrivilo semplificando e facendogli fare il minimo indispensabile
Ad aggiungere orpelli ci penserai dopo averlo fatto andare

Ringrazio tutti per le risposte.

@clarksavagejr mi potresti spiegare meglio cosa potrei cambiare e come migliorare lo Sketch? (Scusami ma non ho capito bene dalla tua scorsa risposta)

Sono un principiante e vorrei capire bene come strutturare gli skecht e renderli più semplici possibili😀

Grazie

Mi potresti spiegare meglio cosa intendi?

Come ha giustamente detto @clarksavagejr tu usi il pin 0, che va ignorato perché non solo può dare problemi per i livelli, ma è anche utile per l'output seriale:

const int pinPulsA = 0;

Dato che hai usato tutti i pin digitali (soprattutto per colpa dell'LCD, ti consiglio di usare sempre quelli con interfaccia I2C, che richiedono solo 2 pin) devi rimapparli, usando anche i pin analogici come digitali, ad esempio usandoli per i led così:

const int pinPulsA = 14; // ossia A0
const int pinPulsB = 15; // ossia A1

I pin A0...A5 non sono "analogici"! Sono degli ingressi che, oltre che poter essere usati come gli altri, possono anche essere collegati al convertitore analogico-digitale (automaticamente, tramite lo stesso analogRead) e usati per misurare segnali analogici.

Ma stai facendo questa precisazione per qualche motivo personale (ed in tal caso ti invito ad evitarlo), o veramente non ritieni A0...A5 che si possano chamare "pin analogici" (che, come ho detto anche io, si possono usare anche come digitali)?

Se pensi che non siano "analogici" e ne sai di più di tutti, protesta anche con il sito Arduino, visto che li definisce così:

@Datman:

Ti invito ad evitare inutili puntualizzazioni tipo quest'ultima che innescano solo polemiche e non servono a nulla. Grazie.

Guglielmo

Va bene. Hai ragione: perdo troppo tempo inutilmente su questo forum.

Ciao, ringrazio tutti nuovamente per le risposte.

Ho cambiato il pin del pulsante A spostandolo da 0 a 7, e ho spostato il pin del buzzer da 7 a 15 (A1) e funziona tutto correttamente.

Quindi, solo per capire bene, anche se non utilizzo il monitor seriale, quando l'utilizzo dei pin 0 e 1 possono dare fastidio ad Arduino?

Occhio alla coerenza:

// nota 1
if(pulsA == 0 || pulsB == 0) {
  if(pulsA == 0 && pulsB == 1) vincitore(pinLedB);
  if(pulsA == 1 && pulsB == 0) vincitore(pinLedA);

Se preme A vince B?
Mentre qui è corretto:

  if(pulsA == 0) vincitore(pinLedA);
  if(pulsB == 0) vincitore(pinLedB);

}

Il codice alla nota 1 viene eseguito una sola volta, perché poi entra nel do while.

In effetti non inizializzando la seriale dovresti in teoria potere usare anche i pin 0 e 1. Per di più nel setup() hai configurato i pin con le pull-up, quindi dovrebbe funzionare anche come l'avevi scritto.

Aspettiamo riposta dagli esperti.

Ciao
la parte dello sketch che hai preso nella nota 1 è relativa a "se A o B premono il pulsante prima della riaccensione del LED start allora il punto va all'avversario"

Infatti, non capisco :grinning_face::grinning_face_with_smiling_eyes:

Attendo risposte, grazie

Ok, diciamo "prima" poiché viene eseguito subito dopo che pinLed_Start diventa HIGH. Però funziona, poiché è impensabile che un giocatore sia cosi abile da premere 10us dopo l'accensione del led, anche se può comunque accadere.

Ora però i conti tornano, il codice alla nota 1 è il responsabile del comportamento che ha esposto, cioè viene assegnato punto a B perché pulsA vale false (0).

Osservando lo schema della UNO rev3 si vede poco, cioè il pin PD0 del ATmega328 è connesso al pin PD3 del ATmega16U2 tramite una resistenza da 1000 ohm. Ora l'unica spiegazione è che il PD3 del ATmega16U2 è low e la pull-up è 50Kohm valore insufficiente per tirare su il pin.

Ciao.

La seriale è comunque molto utile, soprattutto per poter fare debug del codice quindi in genere è meglio lasciarla libera (ossia evitare di collegare qualcosa ai pin D0 e D1). Ma si può usare anche per controllare il funzionamento dando comandi, o per ricevere sul PC informazioni, in questo caso su chi ha premuto prima il pulsante (e con un apposito programmino che interagisce con la seriale puoi farci tante cose).

Io feci una cosa simile, facendo un "retrofit" del vecchio gioco "Quizzettone", chiamandolo "Quizzettino" (il suffisso "ino" in genere si usa per i progetti che utilizzano Arduino) vedi questo Instructable, magari ti può essere utile quantomeno come spunto anche per il codice: