Assegnare valori ad un array

Salve a tutti,

vorrei poter dichiarare i valori di un array tramite tastierino numerico collegato al convertitore AD. Il problema del codice qui sotto (che comprende l'inserimento solo del valore 1 per ora) è che il valore non viene solo assegnato alla prima cifra dell'array ma anche alla seconda 'in cascata' non appena premo l'1. Le mie intenzioni erano quelle di usare la variabile cifrcod ed aumentarla ad ogni nuovo inserimento fino a che non ho inserito tutti i valori dell'array.

A parole la mia idea era: quando cifrcod è 0 e viene premuto 1 assegna alla prima cifra dell'array il valore 1 e aumenta cifrcod di 1. Quando cifrcod è 1 e viene premuto 1 assegna alla seconda cifra dell'array il valore 1.

Spero di essermi fatto capire.
Grazie

int codice[4];
int cifrcod = 0;
int tast = 0;

void setup()
{
}

void loop()
{
tast = analogRead(0);

if (cifrcod == 0)
{
if (tast > 5 && tast < 64)
{
lcd.print("1");
codice[0] = 1;
cifrcod = cifrcod + 1;
}
}

if (cifrcod == 1)
{
if (tast > 5 && tast < 64)
{
lcd.print("1");
codice[1] = 1;
cifrcod = cifrcod + 1;
}
}

}

una analogRead dura 200microsecodi. quindi col tuo codice ogni 200microsecondi circa assegni il valore.

Una buona soluzione è dire: passa alla cella successiva SOLO quando il tasto viene rilasciato O viene premuto un tasto diverso. Ovviamente, per sapere che il tasto è stato rilasciato o cambiato, devi conoscere lo stato del tasto all'analogRead precedente.

un'altra soluzione, più semplice ma più brutta, è usare un delay. in questo modo gestisci la pressione prolungata del tasto come un inserimento multiplo, ma niente tasto cambiato

La cosa ideale, o meglio simile a quella che si usa sui PC, è unire le due soluzioni precedenti, tra l'altro noterai che esiste un delay dopodichè l'inserimento multiplo usa un delay per l'inserimento di lettera multipla molto più breve.

insomma, happy coding

Ho già provato ad usare il delay (e l'ho inserito ovunque!) ma il risultato non cambia, l'inserimento del valore viene solo posticipato.

Il problema non deriva dalla pressione del tasto prolungata ma dal fatto che le due condizioni cifrcod==0 e cifrcod==1 vengono eseguite in rapida successione.

fer forza, quando esci dall'if di cifrcod == 0 entri direttametne nell'if del cifrcod == 1... se invece metti l'if del cifrcod==1 nell'else dello 0 sei a posto

Ok con l'else dovrebbe funzionare ma come faccio per gli altri valori dell'array? Si possono mettere più else per un solo if e annidare all'interno degli else altri if?

omaroski:
Ok con l'else dovrebbe funzionare ma come faccio per gli altri valori dell'array? Si possono mettere più else per un solo if e annidare all'interno degli else altri if?

un case when non ti piace?

no, ci sono 3 soluzioni:

  1. dato che sei già nella else del primo if, ti annidi all'interno della else del secondo if
    però l'identazione poi viene da schifo
  2. usi la clausola else if(), che è identica alla soluzione precedente, ma con l'identazione fatta bene
  3. (la migliore IMHO) usi una switch case (ricordati dei break;), se non sai cosè google che ne vale la pena, anche per fare i menù è comodissima.

lesto:
(la migliore IMHO) usi una switch case (ricordati dei break;), se non sai cosè google che ne vale la pena, anche per fare i menù è comodissima.

--> http://programmazione.html.it/guide/lezione/1165/le-istruzioni-switch/
--> http://programmazione.html.it/guide/lezione/1097/controlli-condizionali-switch-e-operatori-ternari/

Certo che so cos'è lo switch case ma non riesco mai a ricordarmi la sintassi.

Comunque, codice diverso stesso risultato, eccolo:

switch (cifrcod)
{
case 0:
if (tast > 5 && tast < 64)
{
lcd.print("1");
codice[0] = 1;
cifrcod = cifrcod + 1;
}
break;

case 1:
if (tast > 5 && tast < 64)
{
lcd.print("1");
codice[1] = 1;
cifrcod = cifrcod + 1;
break;
}
}

p.s con l'else neanche funziona...

Ricordo che mi sono fermato ai primi due valori dell'array ma in realtà ne dovrebbe contenere quattro, per semplicità sto provando con due soli dato che non riesco a superare questa parte.

Altro switch case con switch case annidato, indovinate un pò? Non funziona! :grin:
Ora non riesco neanche ad inserire i valori. :cold_sweat:

switch (cifrcod)
{
case 0:
switch (tast)
{
case 28 || 29 || 30:
lcd.print("1");
codice[0] = 1;
cifrcod = cifrcod + 1;
break;
}
break;

case 1:
switch (tast)
{
case 28 || 29 || 30:
lcd.print("1");
codice[1] = 1;
cifrcod = cifrcod + 1;
break;
}
}

ma esattamente, cosa fa anzichè funzionare? puoi postare il codice completo?

il fatto che tu abbia risolto gli else non ha risolto i problemi di timing di cui ti parlavo nei primi post.

Per ora la funzione è tutta qui. Dichiarare un array di 4 cifre intere tramite l'ausilio di un tastierino numerico esterno collegato agli ingressi del convertitore A/D.

In realtà come ti ho spiegato il problema del timing è secondario e più facilmente risolvibile in quanto il problema principale riguarda la priorità con la quale vengono eseguite le due istruzioni relative all'assegnazione dei valori all'array. Quindi non appena premo 1 questo valore viene memorizzato nella prima e seconda posizione dell'array pressoché istantaneamente, ovviamente io voglio inserire una cifra ad ogni pressione singola del tasto.

Il codice è pressoché completo, c'è l'inizializzazione delle variabili, l'apertura della comunicazione seriale, l'inserimento della librearia lcd e le stampe a monitor degli stati di alcune variabili.

Sarà una stupidaggine quello che dico, ma il pezzo di codice lo organizzerei in modo diverso....

prima verifichi se c'è una condizione di "nuovo tasto premuto" ( utilizzando dei booleani che rilevano se un tasto premuto poi è stato rilasciato: dai valori presumo che sia un tastierino con delle resistenze, quindi prima di tutto leggi se il valore di tast è quello di un tastierino senza niente premuto, e finchè non lo ottieni non soddisfi la condizione).
Poi lo identifichi per il valore che leggi dall'analog( utilizzando uno switch con il valore tast o forse meglio una serie di if).
Poi assegni il valore all'elemento dell'array( che tieni in memoria con cifrcod).

Non so se mi son spiegato bene....
più o meno:

if(nuovo_tasto){
nuovo_tasto=false;
int value=-1; //l'ho inizializzato a -1 per poter anche riconoscere i casi in cui premi dei caratteri che non ti servono->#,* o non premuto
if(tast>0&&tast<10) value=0;
...
if(...) value=9;
if(value>0&&cfrcod<4){
      codice[cfrcod]=value; 
      cfrcod++;
   }
}

{
else{
nuovo_tasto=controlla_se_il_tastierino_non_è_premuto();
}

Non ho l'arduino dietro per provarci, però stasera ci provo al massimo....

omaroski:
Per ora la funzione è tutta qui. Dichiarare un array di 4 cifre intere tramite l'ausilio di un tastierino numerico esterno collegato agli ingressi del convertitore A/D.

In realtà come ti ho spiegato il problema del timing è secondario e più facilmente risolvibile in quanto il problema principale riguarda la priorità con la quale vengono eseguite le due istruzioni relative all'assegnazione dei valori all'array. Quindi non appena premo 1 questo valore viene memorizzato nella prima e seconda posizione dell'array pressoché istantaneamente, ovviamente io voglio inserire una cifra ad ogni pressione singola del tasto.

Il codice è pressoché completo, c'è l'inizializzazione delle variabili, l'apertura della comunicazione seriale, l'inserimento della librearia lcd e le stampe a monitor degli stati di alcune variabili.

appunto, tu vuoi risolvere il probvlema del timing. the tu lo risolva mettendo un delay o rilevando che il tasto premuto è cambiato, stai inserendo nel programma una temporizzazione per venire incontro ai miserabili riflessi di noi esseri umani.
Studiati qualche codice sul debounce dei pulsanti, non è esattamente la stessa cosa ma ti fa capire come il tuo problema sia presente un pò sempre quando si ha a che fare con input diretti da esseri umani :slight_smile: