Commutatore 6 posizioni

Dovrei dare diverse impostazioni ad un mio circuito con il nano.
Come è meglio collegare il commutatore ?
Avevo pensato di usare più uscite digitali ma per metterle a 0 tutte tranne una ocme posso fare? va bene anche il contrario ovviamente.
Non ho provato per non far casini e perdere tempo inutilmente :slight_smile:
Perchè non credo si possano lasciarle semplicemente scollegate dopo la commutazione?

Buonasera,
essendo il tuo primo post, nel rispetto del regolamento (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Qui una serie di link utili, NON necessariamente inerenti alla tua domanda:
- serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections
- pinout delle varie schede by xxxPighi: Pinout
- link generali utili: Link Utili

ciao gbb01 e grazie per i link utili :slight_smile:

Basta mettere un pull-up o un pull-down, cioè una resistenza verso il positivo o verso massa. Le resistenze di pull-up sono già presenti su ogni ingresso dell'ATmega328. Devi solo attivarle. Ad esempio:
pinMode(0,INPUT); // Imposta come ingresso.
pinMode(0,INPUT_PULLUP); //Attiva la resistenza di pull-up.

grazie Datman era quello che cercavo :slight_smile:

Prego, Tonio! :slight_smile:

tonioB:
Dovrei dare diverse impostazioni ad un mio circuito con il nano.
Come è meglio collegare il commutatore ?
Avevo pensato di usare più uscite digitali ma per metterle a 0 tutte tranne una ocme posso fare? va bene anche il contrario ovviamente.

Parli di "commutatore" quindi di un input verso Arduino, poi di "uscite digitali" per cui i termini generano un poco di confusione... :wink:

Se parliamo di un commutatore a 6 posizioni e tu vuoi leggere in quale posizione si trova, puoi usare 6 ingressi digitali come ti è stato consigliato, ma la cosa secondo me più semplice/efficace è usare un partitore resistivo ed UN ingresso ANALOGICO. Niente "uscite digitali" :wink: ma in questo caso sono ingressi.

Io per un mio progetto relativo ad un pannello per Flight Simulator ho realizzato un circuitino semplice per leggere lo stato di alcuni commutatori, in questo caso a 4 posizioni ma il concetto si può estendere anche a 6 (non consiglierei di più). Lo schema nel mio caso è questo:

Quindi nel codice ho creato una funzione che mi converte il valore letto dal pin ("cur") nel valore corrispondente alla posizione del commutatore (per me da 0 a 3):

int Analog2Rotary(int cur) {
    if (cur < 200)  // Posizione 0 (GND)
      return 0;
    else if (cur < 500)  // Posizione 1 (OFF)
      return 1;
    else if (cur < 900)  // Posizione 2 (CONT)
      return 2;
    else  // Posizione 3 (FLT)
      return 3;
}

Tu devi solo espandere il partitore aggiungendo 2 resistenze e cambiando quindi i valori delle if() aggiungendo due nuovi casi e restituire quindi un intero tra 0 e 5.

Grazie, in futuro se mi mancheranno i pin (vero ho usato un termine sbagliato) digitali userò il tuo circuito.
Ovvio che il circuito che mi hai suggerito è sicuramente più valido in quanto fa uso solo di un pin.

Prego. Non solo, ma con una sola lettura ho la posizione del commutatore, nell'altro caso invece devo fare 6 letture e 6 "if()"... :wink:

Vero, è più veloce.

Bello il tuo progetto, ottimo lavoro :slight_smile:

Però è una lettura analogica, più lenta di una digitale, tanto più rispetto a un PIN che legge molti ingressi contemporaneamente! :slight_smile:

Datman:
Però è una lettura analogica, più lenta di una digitale, tanto più rispetto a un PIN che legge molti ingressi contemporaneamente! :slight_smile:

Vero, analogRead() è più lento del digitalRead().
Però parliamo di 100 microsecondi per lettura analogica, e diciamo che non credo che si debba leggere lo stato di quel commutatore 10.000 volte al secondo :wink:

E poi non credo sia molto più lento fare 1 analogRead() invece di 6 digitalRead() non ti pare? :smiley:

Nel mio caso poi mi ha permesso di realizzare tutto il pannello usando un Nano, il che non è poco :wink:

docdoc:
Prego. Non solo, ma con una sola lettura ho la posizione del commutatore,

Con il sistema del partitore su ingresso analogico non hai la posizione del commutatore, hai un valore in count ADC, per giunta soggetto a variazioni di +/- 1 count nella migliore delle ipotesi, che dovrai comunque convertire in un qualcosa da fare, pertanto sempre sei if, o una switch devi usare, per giunta tenendo conto dell'isteresi.
Con i sei ingressi digitali anche in questo caso non devi fare sei digitalRead, ti basta leggere l'intero port dove è collegato il commutatore e verificare qual'è il bit a zero o uno, dipende se usi le pullpup o le pulldown, alla fine le operazioni da fare sono le stesse, per contro impegni sei pin invece di 1.

docdoc:
E poi non credo sia molto più lento fare 1 analogRead() invece di 6 digitalRead() non ti pare? :smiley:

A parte che non devi fare sei digital read, in tutti i casi anche se le fai al massimo richiedono 10-12 us, ovvero 1/10 del tempo per acquisire un valore con l'ADC. :slight_smile:

Ma infatti con un commutatore è solo questione di numeri di pin disponibili.

Ma perchè dici che il partitore non ti da la posizione?
Una volta che conosci la tensione (ovviamente bisogna usare un partitore che non permetta qualche errore nella misurazione) sai anche la posizione.

tonioB:
sai anche la posizione.

No sai il valore di count del ADC, p.e. una cosa del tipo 110-218-308-415-502-622, inoltre non avrai mai la stessa lettura ogni volta che acquisisci, ottieni una cosa del tipo 109-110-111 nella migliore delle ipotesi.
Su un normale Arduino alimentato da USB è più facile che ottieni una cosa del tipo 105-108-112-115, il che ti obbliga a fare un confronto entro un range di valori , p.e. la lettura deve essere maggiore di 100 e minore di 120 per la posizione 1 del commutatore.

Ho capito cosa intendi, io non ho ancora provato e certi errori non li vedo subito.

Pensavo che se hai un range fino a 1023 non devi progettare un partitore con un range di misurazione molto stretto. Esempio con 10 commutazioni ti puoi permettere circa uno step di 0.5 volt, che corrisponde circa a step di 100 nella misurazione.

Ripeto, io non ho ancora provato nulla e di conseguenza posso dire una marea di stupidaggini:)

astrobeed:
Con il sistema del partitore su ingresso analogico non hai la posizione del commutatore, hai un valore in count ADC, per giunta soggetto a variazioni di +/- 1 count nella migliore delle ipotesi, che dovrai comunque convertire in un qualcosa da fare, pertanto sempre sei if, o una switch devi usare, per giunta tenendo conto dell'isteresi.

Ma astro, scusa, mi meraviglio di te: ma tu HAI visto la funzione che ho postato o parli in generale senza aver visto il codice? :slight_smile:
Certo che so che il valore letto da un analogico non è preciso e stabile al 100%, ma proprio per questo non ho mica proposto 1024 posizioni, e non uso mica "==" per confrontare! Prevedo solo 4 (nel mio caso) fasce di valori, che distinguo molto "grossolanamente" proprio per prevedere eventuali imprecisioni nella misura.
Dai, su, non facciamo i pignoli inutilmente... :smiley:

Infatti nella tuo codice fai 4 if, oppure 6 nel caso in oggetto, quindi non dire che fai solo una lettura e non fai sei if, come lasci intendere qui. :slight_smile:

 nell'altro caso invece devo fare 6 letture e 6 "if()"...

Allora suvvia, facciamo una mezza ricerca binaria :slight_smile:

byte readPos()
{
    int n = analogRead(INPUT_PIN);
    if(n < 512)
        if(n < 103)      return 0;  //0..102    su 0
        else if(n < 307) return 1;  //103..306  su centro 205
        else             return 2;  //307..511  su centro 409
    else
        if(n < 716)      return 3;  //512..715  su centro 614
        else if(n < 921) return 4;  //716..920  su centro 818
        else             return 5;  //921..1023 su 1023
}