Aumentare ingressi e uscite di Arduino (era: A fistful of button)

Ovvero "Per un pugno di bottoni", musiche uestern grazie... Come abbiamo fatto per il seed del generatore di numeri casuali, perché non mettiamo qui le nostre idee (alternative, mi raccomando) per leggere il massimo numero di pulsanti e potenziometri con il minimo consumo di risorse? Ovvio che qualcosa serve di usare, di volta in volta multiplexer, anche fantasiosi, oppure pin digitali, oppure.... Dai, apriamo le danze con 103 bottoni, anche (parzialmente) contemporanei con 2 pin digitali (e una tastiera PS/2)

Per il socio (maubarzi) grazie per i complimenti dall'altra parte, ricambiati

Vediamo di mettere un paio di regole al "giochino"
in questa "palestra di ardimento" vorremmo proporre e discutere idee "non convenzionali" per aumentare il numero di ingressi di Arduino, siano essi analogici o digitali, e magari anche il numero delle uscite
Cominciamo subito col dire che shift-register e multiplexer "non" valgono, dato che sarebbe come "sparare sulla Croce Rossa", almeno non valgono se usati "tal quale", se ci si mette un po' di ingegno magari...
Di recente ho proposto di "multiplare" dei potenziometri non dal lato "segnale" con un multiplexer analogico, ma dal lato alimentazione con uno shift register e/o con alcune uscite di Arduino, una cosa del genere intendo:
analogmulti.png
Comunque, vorrei dire che non siamo qui a giocare a chi ne mette di più, ma a cercare idee nuove

Edit del settembre 2020

Qui un'applicazione reale

Grazie al 'socio' maubarzi che ha scelto i diodi e a Difinov che ha provato adesso sappiamo per certo che la soluzione proposta è valida

analogmulti.png

Ciao Standardoil, è vero che ingressi ed uscite non bastano mai... Penso che per raddoppiarli, triplicarli ecc la soluzione più conveniente, come costo ingombri e complessità realizzativa, sia quella di moltiplicare il numero di Arduini e di collegarli tramite I2C. Ormai i Nano cinesi hanno dei prezzi così bassi da rendere altre soluzioni poco convenienti sotto molti aspetti.

Beh, ma questo è proprio sparare alla grande, sulla povera Croce Rossa
che poi in linea di principio io sono d’accordo con te, anzi
io approfitterei della disponibilità di schede arduino “remote” per distribuire “l’intelligenza” del programma
in effetti se cerchi uno dei miei primi trhead (si scriverà cosi?.. boh) era nell’argomento, se cerchi “era stagione di pin remoti” e “alla fiera degli array” trovi qualcosa di simile a quello che dici tu
ma secondo me c’è ancora spazio per soluzioni ingegnose con “poco microprocessore e tanta inventiva”

Allora, io dico la mia anche se non mi occupo di hardware. Premesse: Ho una UNO sto parlando SOLO di tasti NON esiste la possibilità di pressione contemporanea di tasti

Tutto cominciò con la banale idea di mettere i tasti in "tabella" (N uscite comandate una alla volta ed N ingressi da leggere). Con i 18 pin di Arduino si può così fare una 9*9=81 tasti, e non dovrebbero esserci problemi di correnti, tensioni e cose varie. Poi mi sono ricordato che esiste un modo per far leggere più di un tasto ad un pin analogico associando a ciascun tasto una resistenza differente e leggere il valore analogico corrispondente al tasto premuto (mi pare si possa fare, anche se non so come). Ecco ora l'idea: la tastiera non è una 9*9, ma una 12 (uscite digitali a 5V)*6(ingressi analogici)=72 tasti, che sono meno di prima. Usando, però, gli ingressi analogici è possibile leggerne il valore analogico (ovvietà), quindi io posso sostituire ogni tasto con un insieme di 5 tasti associati a resistenze, così: il primo nessuna (5V) il secondo una con caduta di tensione di 1V circa (4V) il terzo con caduta di tensione di 2V (3V), indovinate gli altri due. Così facendo ho quintuplicato i tasti (72*5=360) mantenendo una "distanza" di 1V tra l'uno e l'altro, accettabile, spero, per compensare alterazioni nell'alimentazione.

Può funzionare?

Direi di si E siamo a due una divisione di 1 volt su 5 più o meno corrisponde al collegamento classico di 5 bottoni su un analogico

allora, prima sparo la minchiata folcloristica e poi quella seria ... è da questa mattina che la prima ce l'ho in canna ma ho paura a postare, ora ho la scusa della seconda per non sprecare un intero post :wink:

Problema degli N potenziometri da leggere:
Se all'uscita da leggere ci metto una opportuna resistenza che si scalda in modo proporzionale al passaggio della corrente, mi basta una telecamera IR per inquadrare tutti i miei potenziometri e analizzare i relativi pixer per vederne la temperatura :fearful:
Servirebbero resistenze che scaldano in proporzione e una telecamera infrarossa adeguata.
Mi rivolgo alla nasa?

Proposta più seria che modifica questa:
analogmulti.png
Se invece dei pin diretti, e quindi limitati, ci metto in mezzo uno o più shift register in cascata posso rendere il numero di aggeggi da leggere pressochè illimitato.
Ad ogni ciclo basta che scelgo il trabiccolo da leggere e lo alimento con questo marchingegno :stuck_out_tongue:
Ora, senza il punto di partenza non mi sarebbe mai venuta in mente questa soluzione, per cui divido volentieri odori e oneri, una volta arrivati a Stoccolma :wink:

EDIT:
Azz. rileggendo bene il post iniziale l'idea dello shift register era già uscita fuori, quindi mi sa che il giro a Stoccolma salta :frowning:

La facciamo finita con "post" che nulla hanno a che vedere con l'argomento del thread? ... per le "chiecchiere" e le "battute" c'è lo spam-bar, ve l'ho già detto ...

Thread ripulito.

Guglielmo

Standardoil: Cominciamo subito col dire che shift-register e multiplexer "non" valgono ... Di recente ho proposto di "multiplare" dei potenziometri non dal lato "segnale" con un multiplexer analogico, ma dal lato alimentazione con uno shift register e/o con alcune uscite di Arduino

Mi perplimo. ;) Si possono usare o non si possono usare shift register?

una cosa del genere intendo:

Magari se ce l'hai anche ad una risoluzione maggiore di 140x100 pixel si riesce a leggere qualcosina... ;)

Per la tua perplessità Per intanto non è che lo avevo proposto in questa discussione, ma in un'altra, lo shift register Poi lo shift register era una delle possibilità, non l'unica In terzo proponevo l'uso di uno shift register per una misura analogica, non è che sia il suo uso canonico, Sarebbe stato sparare sulla croce rossa se avessi proposto multiplexer cmos, non uscite digitali come ho fatto

Per l'immagine Stasera provo a farla più grande Uso fidocad e a che male, scusa

Come ti trovi con Fidocad? Non l'ho mai provato

Trovo fidocad utilissimo per realizzare rapidamente dei piccoli schemi. Addirittura, in alcuni forum esiste la possibilità di incorporare il codice di fidocad per mettere gli schemi nei messaggi (ho dimenticato in quali forum... ma vi assicuro che esistono).

paulus1969:
(ho dimenticato in quali forum… ma vi assicuro che esistono).

Uno è ElectroYou :wink:

Non solo, ma se si vogliono solo visualizzare gli schemi basta incollare il sorgente (come l'esempio seguente)

[FIDOCAD]
FJC C 3.0
FJC B 0.5
MC 50 45 0 0 045
MC 50 35 3 0 010
MC 50 35 0 0 115

nel visualizzatore online: http://pot.potorti.it/fidocad/... in fondo era nato per scambiare schemi sotto forma di testo in usenet.

E poi è immediato crearsi componenti aggiuntivi non presenti nelle librerie standard.

Silente: ..... Ecco ora l'idea: la tastiera non è una 9*9, ma una 12 (uscite digitali a 5V)*6(ingressi analogici)=72 tasti, che sono meno di prima. Usando, però, gli ingressi analogici è possibile leggerne il valore analogico (ovvietà), quindi io posso sostituire ogni tasto con un insieme di 5 tasti associati a resistenze, così: il primo nessuna (5V) il secondo una con caduta di tensione di 1V circa (4V) il terzo con caduta di tensione di 2V (3V), indovinate gli altri due. Così facendo ho quintuplicato i tasti (72*5=360) mantenendo una "distanza" di 1V tra l'uno e l'altro, accettabile, spero, per compensare alterazioni nell'alimentazione. ....

Fino a 72 tasti ci sono arrivato, ma non ho capito come hai fatto a moltiplicarli di nuovo per 5...

Perché ho pensato di creare una tastiera strana: ha 12 righe (pin digitali) e 6 colonne (pin “analogici”). Questo permette di collegare 72 pulsanti. Il gioco con il quale moltiplico per 5 questo valore è che non collego direttamente i tasti singoli, ma al loro posto un insieme fisso: 5 tasti e 4 resistenze in parallelo, si che ogni tasto, tranne 1, abbia la sua resistenza. Le resistenze hanno valori diversi, che causano cadute di tensione differenti, ovvero letture analogiche differenti. Vedi foto (se riesco a metterla in qualche modo). Il problema: un circuito troppo complicato, anche se teoricamente fattibile (spero)

Silente: 5 tasti e 4 resistenze in parallelo, si che ogni tasto, tranne 1, abbia la sua resistenza. Le resistenze hanno valori diversi, che causano cadute di tensione differenti, ovvero letture analogiche differenti.

Però andrebbe anche una R pull-down sull'ingresso analogico in modo da fare da partitore di tensione con le altre.

Un'alternativa si era discussa qui e qui e qui (il vantaggio è che le resistenze hanno sempre gli stessi valori indipendentemente dal numero di suddivisioni/pulsanti e si legge comodamente con map).

Credo che se invece del multiplexing implementi il charlieplexing, con i soli 6 pin analogici puoi leggere 150 pulsanti (30 gruppi da 5).... o anche di più se i gruppi sono formati da più suddivisioni.

Si, certo, è così. E lo faccio regolarmente con i 5 tasti che uso sulle mie schede... Sono proprio 360 tasti

Chissà perché mi ero perso.... Sarà l'età!

per chi mi ha chiesto:
immagine a risoluzione maggiore, scusatemi sto imparando adesso fidocad


per fidocad, come mi trovo?
mah, è l'unico che sono riuscito ad usare.....
imparero'..
cosa consigliate per un neofita che usa ubuntu?
(semplice da usare, mi raccomando)

aggiungo qualcosa:
metodo assolutamente standard, l'unica modifica sono dei diodi per permettere la pressione contemporanea di più tasti e delle resistenza di pull-down per evitare eventuali disturbi o segnali spurii
si tratta della classica scansione riga-colonna, lo schema base è questo:


si possono usare dei comuni diodi 1n4148, e resistenze da 2k2 o anche 4k7
facilmente espandibile aggiungendo righe e/o colonne
siccome l'hardware è semplice e ben conosciuto ho messo un po' di fantasia nel software
per prima cosa si crea un array di piedini di righe (output) e uno di piedini di colonne (input), e da quelli le due "costanti" RIGHE e COLONNE

byte righe[]={2,3,4,5,6}; // i numeri sono pienamente inventati, userete quelli che collegherete
byte colonne[]={7,8,9,10,11}; // idem
#define RIGHE sizeof(righe)/sizeof(righe[0])
#define COLONNE sizeof(colonne)/sizeof(colonne[0])

come vedete si può usare una matrice con qualunque numero di righe e/o colonne (anche se la buona regola consiglia che questi due numeri siano uguali o almeno poco differenti)
poi quando serve si usa una semplice funzione bool che restituisce 1 se il tasto è premuto, 0 se no (o se il tasto non esiste)

if (premuto(riga,colonna))
{
    // quello che devo fare se il tasto è premuto
{

la funzione premuto è semplice semplice:

bool premuto(byte riga, byte colonna)
{
   static bool primaesecuzione=0;
   if (!primaesecuzione)
   {
      // solo la prima volta che si esegue la funzione
      primaesecuzione=1;
      // inizializzo le righe
      for (byte i=0; i<RIGHE;i++)
      {
         pinMode(righe[i], OUTPUT);
         digitalWrite(righe[i], LOW);
      }
      // inizializzo le colonne
      for (byte i=0; i<COLONNE, i++)
      {
         pinMode(colonne[i], INPUT);
         digitalWrite(colonne[i], LOW);
      }
   }
   // OK l'inizializzazione è certamente fatta
   // escludiamo i casi errati
   if (riga>RIGHE)
   {
      return 0;
   }
   if (colonna>COLONNE)
   {
      return 0;
   }
   // ok, non è caso errato
   // alzo la riga
   digitalWrite(riga, HIGH);
   // leggo la colonna
   bool tmp=digitalRead(colonna);
   // abbasso la riga
   digitalWrite(riga, LOW);
   // risultato ottenuto
   return tmp;
}

che basta copiarla dentro al programma e siamo a posto, per sicurezza le faccio fare anche l'inizializzazione, così l'utilizzatore non ha bisogno di fare nulla di più che scrivere i piedini nelle prime due righe e usare dritta dritta la funzione
se servisse si può anche aggiungere una versione che accetta il "numero" del tasto da 0 a N-1, dove naturalmente N è il prodotto di righe e colonne

bool premuto(byte numtasto)
{
// versione che accetta il "numero" del tasto premuto
return premuto(numtasto/COLONNE, numtasto%COLONNE);
}

PS qualcuno mi sa dire se in C++ l'overload delle funzioni funziona anche così?
chè non sono sicurissimo....