Ancora sugli Array . Vettore che punta direttamente ad una variabile.

E' possibile fare in modo che un vettore punti ad una variabile anzichè ad un valore?

Ho trovato molte soluzioni alquanto malsane per risolvere il problema e non posso credere che non ce ne siano di più eleganti.

int bottone0=12,bottone1=7, bottone2=3, bottone3=9, bottone4=5;

int pin[50]={bottone0,bottone1,bottone2,bottone3,bottone4};

int x = pin[2];  in questo caso x contiene quello che contiene bottone2, cioè

in questo caso x contiene quello che contiene bottone2, cioè 3
ma se volessi aggiornare i valori contenuti aggiornando le variabili ? cioè, secambio il contenuto di bottone4 vorrei che cambiasse anche pin[4], o meglio, vorrei che pin[4] leggesse direttamente all'interno della variabile.

attualmente la soluzione più elegante che ho trovato è questa:

int provvisorio[50]{bottone0,bottone1,bottone2,bottone3,bottone4};

for (int x=0;x<50;x++){pin[x]=provvisori[x]; }

il tutto incapsulato in una funzione da richiamare all'occorenza. Ma non posso credere che non esista un modo più diretto.

Inutile dire che non è bello aggiornare tutto a brutto cane quando ne cambia solo una....

Non capisco il senso di quello che vuoi fare. Cioé, dove useresti

pin[x]

non puoi usare direttamente

provvisori[x]

?

EDIT: Ho capito, credo che quanto segue faccia al caso tuo: modifica direttamente il vettore insomma, non c'è bisogno di avere variabili a parte.

Inoltre, questo:

int pin[50]={bottone0,bottone1,bottone2,bottone3,bottone4};

Puoi scriverlo direttamente:

int pin[50]={12, 7, 3, 9, 5};

Colpa mia, mi sono spiegato male.

Vi ringrazio per le risposte ma non ci siamo capiti.

In un programma con centinaia di variabili mi risulta impossibile ricordare a cosa corrisponde

Variabile[137] , quindi preferisco scrivere;

if ( LivelloVasca1 ) { Serial.println("Vasca n1 piena") pompa1=0;}

pompa1 corrisponde ad una posizione in Variabile[ ] così come LivelloVasca1, ma se scrivessi

if ( Variabile[63]) { Serial.println("Vasca n1 piena") Variabile[9]=0;} non riuscirei a leggere il mio stesso programma.

Al momento col mio metodo funziona ma spreco molto tempo che il processore potrebbe usare meglio, non so, per andare al cinema o bersi una birra.

Ci sono diversi metodi per aggirare il problema:

  1. Usare un enum per dare dei nomi agli indici, tipo:
enum {
 VASCA1 = 137
};


if (array[VASCA1])
...
  1. Usare un puntatore o, meglio, una reference:
int& livelloVasca = array[137];

Tuttavia, la situazione proposta mi fa pensare che tu stia usando un array in maniera poco opportuna... E non mi è nemmeno troppo chiaro come questa seconda situazione si leghi alla prima.

Perché vuoi per forza usare array dove non ha vantaggi?

Ciao Uwe

Grazie ancora per le risposte, non ho ancora provato come funzionano ma se ho capito bene entrambi i modi raggiungono lo scopo, cioè rendere leggibile il programma a me oggi mentre lo scrivo oppure domani quando dovrò fare una modifica.

Perchè voglio usare a tutti i costi gli array? in questo caso specifico mi viene comodo avere una lista di valori ordinati in questo modo:

const int          pin [30] {                                 }
const String      nome [30] { "numero 1",....."numero 16",... }
int         ValAttuale [30] {                                 }
boolean  ValPrecedente [30] {                                 }
int      ValDesiderato [30] {                                 }

In questo modo se voglio conoscere qualcosa dell'elemento al quale ho dato il nome " numero 1 " so già che quel qualcosa si trova nella stessa posizione. Quindi se nel programma mi serve il pin vado a richiamare l'array dei pin, se mi serve il valore dell'ultima lettura vado a richiamare l'array "ValAttuale" e così via. ValDesiderato ormai non serve più perchè posso usare int& quando dichiaro le variabili e scrivere direttamente nel contenitore giusto senza passaggi strani.

Continuo a non capire il nesso tra i tuoi tre post, ma vabbeh. Leggi qua, vah: Arduino Playground - Struct Resource

PS: Occhio che la RAM è preziosa...

SukkoPera:
Continuo a non capire il nesso tra i tuoi tre post, ma vabbeh. Leggi qua, vah: Arduino Playground - HomePage

PS: Occhio che la RAM è preziosa...

Ho aggiornato il messaggio precedente, mi ero perso un pezzo.

Ora si capisce un po' di più, ma la soluzione a tutto sto casino è l'uso di una struct, come da messaggio precedente, unita alla proposta degli enum per gli indici.

Ribadisco anche che la RAM è preziosa, usa una variabile byte per i pin, un int è inutilmente grande. Se poi al posto delle String potessi usare degli array di char... :slight_smile:

Ciao Rob, l'array è una struttura nata per matrici di dati, viene da se che il mnemonico è il nome dell'array, non i membri che lo compongono.

Stefano

Ho fatto i compiti.

SukkoPera:
Ora si capisce un po' di più, ma la soluzione a tutto sto casino è l'uso di una struct, [...]

Concordo, il fatto è che prima non conoscevo neanche la parola struct...

Bene, ora vediamo se la mia soluzione piace:

typedef struct{
  char nome[20];                              
  const byte n;
  boolean p;
  boolean a;
  boolean v;
  }inout;

Inout Primo={"Primo",51,0,0,0 }, Secondo={"Secondo",36,0,0,0 }; // e così via

Decisamente meglio. Ora impara anche a usare maiuscole e minuscole secondo le convenzioni e poi ci siamo quasi ;).

PS: In C++ basta struct InOut, senza typedef.

PS2: Puoi fare un vettore di struct!

Fare un vettore è una possibilità, che può avere senso oppure no. Io non ho ancora capito se nel tuo contesto ce l'abbia o meno, comunque questa è la sintassi:

struct InOut {
  const char *nome;    // Se il nome è fisso questo ti fa rispamiare RAM
  const byte n;
  boolean p;
  boolean a;
  boolean v;
};

#define N_ELEM 2

InOut array[N_ELEM] = {
  {"Primo",51,0,0,0},
  {"Secondo",36,0,0,0}
};

Il codice poi sarebbe, se capisco bene:

 for(int x=0; x<40; x++) {
    if (array[x].p != array[x].a) {
            Serial.print ("il valore di ");
            Serial.print (array[x].nome);
            Serial.print (" adesso e' ");
            Serial.println (array[x].a);

            array[x].p = array[x].a;
    }//fine if
} // fine for

In questi giorni ho ripreso in mano un progetto, e cercando informazioni in rete cosa trovo? La mia discussione naturalmente!
Quindi, prima di aprirne una nuova riguardante il progetto, ho pensato di completare questa e poter finalmente vedere la scritta [solved] a fianco del titolo.

const int Itot=8; //totale ingressi
const int Utot=8; //totale Uscite

typedef struct {  
  const char nome;   // Nome del contatto
  const byte pin;    // Pin di arduino 
  boolean att;       // Stato attuale
  boolean pre;       // Stato precedente
  boolean nex;       // Stato voluto
  } InOut;

 //--- Variabile---Nome etichetta---Pin Ardu---         
 InOut    I1         = { "I1",         6 , 0 , 0 , 0 },  
          I2         = { "I2",         7 , 1 , 0 , 1 },  
          I3         = { "I3",         8 , 0 , 1 , 1 },  
          I4         = { "I4",         9 , 0 , 1 , 0 },  
          I5         = { "I5",        10 , 1 , 1 , 0 },  
          I6         = { "I6",        11 , 1 , 0 , 0 },  
          I7         = { "I7",        12 , 1 , 0 , 0 },  
          I8         = { "I8",        13 , 0 , 0 , 1 }; 

InOut ArrayIn[Itot] { I1,I2,I3,I4,I5,I6,I7,I8 };// Array di ingressi


 //--- Variabile---Nome etichetta----Pin Ardu---                         
InOut     U1          = { "U1",         A1 , 0 , 0 , 1 }, 
          U2          = { "U2",         A2 , 0 , 1 , 0 }, 
          U3          = { "U3",         A3 , 0 , 0 , 1 }, 
          U4          = { "U4",         A4 , 1 , 0 , 1 }, 
          U5          = { "U5",         A5 , 0 , 1 , 0 }, 
          U6          = { "U6",         A6 , 0 , 1 , 0 }, 
          U7          = { "U7",         A7 , 0 , 1 , 0 }, 
          U8          = { "U8",         A8 , 0 , 0 , 1 }; 

 InOut ArrayOut[Utot] { U1,U2,U3,U4,U5,U6,U7,U8 };// Array di uscite

Questo è il codice definitivo, salvo vostri suggerimenti.
In questo modo posso leggere uno ad uno lo stato dei pin e memorizzarlo, in un semplice ciclo for:

void AggIngressi (){ for (int s=0; s<Itot; s++) { ArrayIn[s].att = digitalRead (ArrayIn[s].pin);   } }

Oppure posso impostare le uscite al valore desiderato:

void AggOut (){ for (int s=0; s<Itot; s++) { digitalWrite ( ArrayIn[s].pin , ArrayIn[s].nex ); } }

Lo scopo di tutto questo è separare il programma vero e proprio da tutto quello che ci gira intorno.
Questo mi verrà utile, o almeno credo che mi verra uile, quando dovrò scrivere programmi molto lunghi con un gran numero di ingressi e uscite.

Un altro modo è questo:

int   a=1, b=2, c=3, d=4, e=5;

int*  arr[5]{&a,&b,&c,&d,&e};

in questo modo leggo e scrivo direttamente nella variabile, e non nell'array, il quale contiene gli indirizzi e non i valori.

In questo modo posso leggere o scrivere nelle variabili utilizzando un ciclo for.

for (int x=0;x<5;x++){ *arr[x] = Quello che voglio } [\code]