Arcade Button - Info su pullup/pulldown e connessione con arduino

Ciao a tutti,
vorrei capire come collegare nella maniera corretta un pulsante (di quelli arcade a 2 sole uscite) all'arduino micro.

In rete leggo che vi è la necessità di usare una resistenza, mentre altri usano il pullup interno di arduino.

Purtroppo a me ancora non mi è chiaro il concetto di pullup/pulldown (e magari se mi aiutate a comprendere, vi ringrazio vivamente).

Ho seguito un tutorial ed ho collegato il tutto in questa maniera.

1 piedino alla porta 2
1 piedino alla GND

Ho usato poi questo codice:

int button = 2;

void setup() {
  // put your setup code here, to run once:
  pinMode(button, INPUT);
  digitalWrite(button, HIGH); //activate arduino internal pull up
  Serial.begin(9600);
  
}

void loop() {
  // put your main code here, to run repeatedly:
  if (digitalRead(button)==LOW){
    Serial.println("Button is pressed");
  }
  delay(100);

}

A monitor vedo il messaggio ogni volta che premo il tasto, però mi da la sensazione che non sia ben "sincronizzato".

Nel senso... a volte premo e non succede nulla. Se tengo premuto un po di piu compare il messaggio.

Sbaglio qualcosa?

Il tuo codice è corretto, hai attivato la pullup interna, anche se puoi farlo con un unica istruzione con l'attuale ide usando INPUT_PULLUP quando usi la funzione pinMode (ti elimina l'esigenza di fare la digitalWrite)
Il fatto che non ti sembra sincronizzato può dipendere da quel delay, prova a eliminarlo.
In ogni caso di seguito proverò a spiegarti la pullup/down e anche ti annuncio che per fare un bel lavoro dovrai usare un debounce (meglio se hardware)

Quando metti un pin in modalità INPUT questo viene settato in alta impedenza quindi potrebbe captare disturbi radio che potrebbero indurre la MCU a rilevare questi disturbi come uno stato alto o basso anche in assenza di una rele pressione del pulsante.
Per ovviare a questo occorre dare un riferimento preciso al pin di input e lo si può fare fornendo un riferimento alto (pullup) o basso (pulldown).
Si realizza con una resistenza con un valore elevato (Es. 10K) in modo che in assenza di pressione del pulsante attraverso di essa scorra una debole corrente, sufficiente a far rilevare con certezza l'esatto stato (alto o basso). Quando premi il pulsante scorrerà molta più corrente attraverso di esso facendo rilevare la pressione e quindi il relativo stato del pin.
Se opti per una resistenza di pullup (interna od esterna che sia) il pin normalmente verrà visto con stato alto (HIGH), il pulsante dovrai connetterlo a GND e la sua pressione porterà il pin a stato basso (LOW).
Viceversa se opti per lla resistenza di pulldown il pin verrà visto normalmente basso (LOW) e il pulsante dovrai collegarlo a +5V, la sua pressione farà si che il pin verrà rileavto con stato alto (HIGH).

Finita la teoria pura occorre sapere che un pulsante reale non si comporta come uno ideale, ovvero quando lo premi non entra immediatamente in conduzione ma per via di come è costruito la parte metallica che pone in essere il collegamento può far arrivare al pin un certo numero di impulsi che il tuo programma interpreterebbe come pressioni ripetute.
Ovviamente questo è un comportamento indesiderato percui occorre evitarlo, per farlo ci sono due sistemi, quello software (il più delle volte sconsigliabile) e quello hardware (solitamente consigliato).
Il debounce hardware prevede l'uso di una resistenza e di un condensatore, se opti per la resistenza di pullup dovrai mettere il condensatore (solitamente 100nF vanno bene) tra il pin e GND e la resistenza tra pin e pulsante, il pulsante lo colleghi anch'esso a GND.
In questo modo quando il pulsante viene premuto, gli inevitabili rimbalzi vengono soppressi dal condensatore (che si deve caricare prima che il pin possa cambiare di stato) e solo se il pulsante viene tenuto premuto per un certo lasso di tempo (pochi millisecondi) il pin assumerà lo stato desiderato (LOW nel nostro caso)

Esistono poi metodi più raffinati di debounce qui un esempio quando occorra un debounce veramente efficiente, esistono anche integrati dedicati allo scopo (nel grafico dell'immagine dell'ultimolink puoi vedere i rimbalzi che spiegavo prima che avvengono alla pressione del pulsante), ma normamente resistenza e condensatori fanno il loro sporco lavoro.

fabpolli:
Il tuo codice è corretto, hai attivato la pullup interna, anche se puoi farlo con un unica istruzione con l'attuale ide usando INPUT_PULLUP quando usi la funzione pinMode (ti elimina l'esigenza di fare la digitalWrite)
Il fatto che non ti sembra sincronizzato può dipendere da quel delay, prova a eliminarlo.
In ogni caso di seguito proverò a spiegarti la pullup/down e anche ti annuncio che per fare un bel lavoro dovrai usare un debounce (meglio se hardware)

Ciao, ti ringrazio per il chiarimento sulla parte di pullup/pulldown. Se provo a rimuovere il delay, non c'è il rischio di avere messaggi ripetuti?

La mia impressione è questa, lanciato lo sketch (quindi ancora nessuna pressione) e premendo il pulsante rapidamente a video non vedo nulla.
Se tengo premuto un po, allora compare il messaggio.

E' come se ci volesse del tempo per passare dallo stato di HIGH a LOW.

Consiglio generale, allenati a far fare le cose alla MCU sempre senza l'uso della funzione delay a meno che tu non abbia necessità di far attendere senza far null'altro, ma sono casi molto limitati, altrimenti rischi di dover cambiare tutta la struttura di un programma quando ti rendi conto che dopo aver premuto il pulsante devi far dell'altro.
A tal scopo per capire le basi con cui si usa millis() consiglio prima la lettura di QUESTO post esplicativo, dopo di che lo studio di come si usa la funzione millis(), prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina ... alla fine il tutto dovrebbe essere più chiaro :slight_smile:

Per il tuo caso specifico, sei tu che una colta premuto il pulsante dovrai memorizzare in una variabile il fatto che il pulsante è stato premuto, fare ciò che vuoi (Nel tuo caso stampare su monitor seriale) e poi ai successivi giri di loop verificare che se il pulsante è ancora premuto ma hai già fatto ciò che devi non fare nulla, altrimenti se il pulsante è stato rilasciato allora azzeri la varibile di controllo e aspetti che il pulsante venga premuto di nuovo.
Per il ritardo, che arduino usi? Perché il ritardo che dici di rilevare potrebbe essere il bootloader che sta verificando se stai cercando di caricare un nuovo sketch e pertanto non è ancora nel loop e quindi non "sente" la pressione del pulsante. Oppure potrebbe essere l'inizializzazione della seriale. Metti come ultima istruzione nel setup una bella println su serial monitor con una roba del tipo "Setup terminato", quando vedi la scritta allora prova a premere il pulsante

Cerco di spiegar bene cosa devo fare.

Al momento mi stavo allenando con un arduino nano, nell'attesa che mi arrivi l'arduino leonardo.
Vorrei costruirmi uno switch per OBS. Una pulsantiera dove posso avviare e stoppare uno streaming, switchare da una scena all'altra.

OBS ha la possibilità di usare le keymap per far tutto.

Quindi devo creare una pulsantiera che invii fondamentalmente delle keymap a OBS.

Il nano se non ricordo male ha un sacco di ritardo in avvio con la seriale collegata (un po' come la mini).
Nell'attesa che ti arrivi la Leonardo fa come ti ho detto, metti il messaggio alla fine del setup e fai in modo che quando premi il pulsante ti venga stampata una sola volta "Button is pressed" senza usare il delay ma con una variabile (anche detta flag) che ti permetta di arrivare a questo risultato.
Non trascurare la parte di debounce che altrimenti non ne esci vincitore, se non hai un condensatore da 100nF mettine anche uno con capacità maggiore più la aumenti più dovrai tener premuto prima di vedere la scritta

nel kit ho 2 tipi di condensatori marchiati 103 e 104

Usa il 104, per praticità tua ti metto questo link

Grazie!
Un' ultimissima cosa.

La micro e la leonardo hanno il pullup interno?
Forse per il mio progetto non è necessario evitare le ripetizioni del caratteri (basti che ne arrivi 1 mappato correttamente, mentre discorso diverso se creassi una midibox).

Non so se la leonardo ha le pullup interne, non l'ho mai usata.
A naso credo tu debba comunque eliminare le ripetizioni perché se ti invio a o aaaaaaaaaaaaaaaaaaaaaaa la cosa cambia credo...

fabpolli:
Non so se la leonardo ha le pullup interne, non l'ho mai usata.
A naso credo tu debba comunque eliminare le ripetizioni perché se ti invio a o aaaaaaaaaaaaaaaaaaaaaaa la cosa cambia credo...

Giusta osservazione! Da provare appena arriva!

Lo ripeto l'ultima volta, non serve che aspetti che ti arrivi la leonardo per codificare l'algoritmo che ti servirà (perché ti servirà credimi) lo puoi già fare ora con il nano, capisco che sperare che magicamente la Leonardo non soffra del problema è meglio di sbattersi per risolverlo ma è solo un rimandare l'inevitabile :wink:

No, forse non ci siamo intesi. La leonardo mi serve per il la codifica della tastiera. Cosa che l'ATMega della nano/uno non fa. Intanto si, posso ora provare il condensatore.

Si il condensatore ok, mettilo ma dovrai per forza di cose cambiare anche la parte dello sketch per eliminare il delay