Creare ciclo FOR per riempire un ARRAY

Ciao a tutti,
avrei bisogno un'aiutino :P:
Ho fatto questo programma per fare un set reset di 16 uscite attraverso 16 pulsanti (praticamente devo far funzionare 16 relè come se fossero passo-passo.
Prendendo spunto dagli esempi ho iniziato a mettere giù il codice per un ingresso e un'uscita, l'ho provato e tutto funziona bene, adesso dovrei fare la stessa cosa per gli altri 15ingressi/uscite ma non volevo scrivere 10 km di codice, così pensavo di fare un ciclo FOR dove scansionare i 16 pulsanti e attivare/disattivale le uscite corrispondenti. Mi sono un po' perso sui Reference di arduino.cc tra ARRAY e cicli FOR ... qualcuno è in grado di aiutarmi ?!

Questo è il codice per una coppia pulsante/relè:

const int Ingresso = 22;
const int Uscita = 23;

int ContaIngressi = 0;
int StatoPulsante = 0;
int UlsimoStatoPulsante = 0;

void setup() {
pinMode(Ingresso, INPUT);
digitalWrite(Ingresso, HIGH);
}

void loop() {
StatoPulsante = digitalRead(Ingresso);
delay(50);
if (StatoPulsante != UlsimoStatoPulsante) {
if (StatoPulsante == HIGH) {
ContaIngressi++;
}
}
UlsimoStatoPulsante = StatoPulsante;
}
if (ContaIngressi % 2 == 0) {
digitalWrite(Uscita, HIGH);
} else {
digitalWrite(Uscita, LOW);
}
}

Mi sapete dire come devo modificare il codice ? GRAZIE !

Ah dimenticavo di dirvi che uso un Arduino Mega e che ingressi e uscite non sono consecutivi:
Ingressi: 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52
Uscite: 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53

ho notato un paio di cose:
nel setup

digitalWrite(Ingresso, HIGH);

non ha senso perchè prima l'hai dichiarato come input, si inizializzano solo le uscite.
Manca anche la dichiarazione dell'uscita (pinMode(Uscita, OUTPUT);).

con array e ciclo for le tue variabili ContaIngressi, StatoPulsante e UltimoStatoPulsante diventano vettori e per ogni ciclo scandito dal for esegui l'operazione da te descritta.

Attento ad usare i delay perchè in questo caso l'ultimo pulsante/relè verrebbe scansionato dopo 16*50 millisecondi. Prova ad usare la funzione millis.

digitalWrite(Ingresso, HIGH) serve per abilitare la resistenza di pull-up interna, in questo modo posso usare un normalissimo pulsante per mandare il GND all'ingresso senza usare la resistenza collegata a positivo.

Per la dichiarazione dell'uscita hai ragione, non so come fa a funzionare ma ti assicuro che va ! Il mio programma è praticamente identico al programma StateChangeDetection presente negli Example del programma Arduino ho solo cambiato alcune cose ma la dichiarazione dell'Output manca anche li.

Quindi alla fine dovrei creare 3 array (ContaIngressi, StatoPulsante e UltimoStatoPulsante) e fare un ciclo che contenga tutto il Void Loop attuale giusto ? E per il mills come faccio ?

ecco un abbozzo di codice, ho commentato i punti piu' importanti:
dovrebbe funzionare.

ATTENZIONE
nel precedente codice usavi i piedini come input per dare energia alle uscite: con la resistenza di pull-up significa che li facevi comportare come uscite con in serie delle resistenze da 20Kohm.
Ora le ho configurate come uscite vere, devi assicurarti che non si creino cortocircuiti, se piloti un rele' devi mettere una resistenza in serie da almeno 200 ohm, se metti un led assicurati di metterci una resistenza piu' grande, altrimenti bruci sia l'arduino che il led

const int Ingresso = 22; //primo ingresso
const int Uscita = 23; //prima uscita

int ContaIngressi[16] = {0};
int StatoPulsante = 0;
int UlsimoStatoPulsante[16]; //stato pulsanti, ora e' un array

int i; // contatore
void setup() {
for(i=0;i<16;i++){
pinMode(Ingresso+2i, INPUT); //inutile, i piedini sono predefiniti come ingresso
digitalWrite(Ingresso+2
i, HIGH);
pinMode(Uscita+2i, OUTPUT);
digitalWrite(Ingresso+2
i, LOW);
}
}

void loop() {
for(i=0;i<16;i++){
UlsimoStatoPulsante = digitalRead(Ingresso+2*i);

  • }*
  • delay(50);*
  • for(i=0;i<16;i++){*
    _ StatoPulsante = digitalRead(Ingresso+2i);_
    _ if (StatoPulsante == HIGH && UlsimoStatoPulsante == LOW){_
    _ ContaIngressi++;
    if(ContaIngressi % 2 )
    digitalWrite(Uscita+2i,HIGH);

    * else*
    digitalWrite(Uscita+2i,LOW);
    }
    }
    //se necessario aggiorni automaticamente lo stato dei pin, per codici piu' complessi*

    * //puoi usare la funzione millis();
    }
    [/quote]*_

nel precedente codice usavi i piedini come input per dare energia alle uscite: con la resistenza di pull-up significa che li facevi comportare come uscite con in serie delle resistenze da 20Kohm.

Non capisco cosa intendi per "dare energia alle uscite". Io ho seguito questo http://www.arduino.cc/en/Tutorial/DigitalPins e da quanto ho capito in questo modo posso evitare di mettere la resistenza di pull-up sul +5V perchè lo fa già l'Atmega, infatti con il programma che avevo scritto ogni volta che porto sull'ingresso il GND, l'uscita cambia di stato.

Comunque ti spiego anche come è fatto il circuito per capirci meglio:
I pulsanti normalmente aperti sono collegati tra il GND e gli ingressi.
Le uscite sono collegate ad un ULM2003 (array di 7 transistor Darlington NPN) che mi pilota i Relè

quella configurazione e' corretta per gli ingressi, cioe' quelli su cui e' collegato il pulsante, infatti ho lasciato la configurazione INPUT-HIGH su quelli.

La modifica l'ho fatta sulle uscite, ossia quelle che vanno all'integrato.
L'arduino all'avvio configura automaticamente tutti i piedini come input, quindi gli OUTPUT vanno settati a mano.

quell'integrato richiede i piedini configurati come OUTPUT, in quanto possiede gia' le resistenze interne.

tu pilotavi l'integrato usando i piedini configurati come input, cio' significa che davano 5v con resistenza oppure un valore che non si puo' conoscere in anticipo.

se li configuri come output ti danno 5v oppure 0v, questo ti permette di usare l'integrato come interruttore dei rele' e prevedere con sicurezza il comportamento del circuito.

Ok, ora è chiaro. Dunque ricapitolado:

Input - Low > Ingresso senza resistenze di pull-up interne
Input - High > Ingresso con resistenze di pull-up interne
Output - Low > Sul piedino è presente il GND (oppure è ad alta impedenza ?)
Output - High > Sul piedino è presente il +5V

Non ho ancora avuto tempo di provare il codiche che mi hai posato ... appena provo ti faccio sapere ! X adesso grazie !

matteo c'è qualcosa che non va perchè ho provato a caricare il codice che mi hai posato ma ha un comportamento strano:

Appena inserisco un pezzettino di filo nell'ingresso (10 cm) l'uscita comincia a andare alta, bassa, alta, bassa in continuazione. E' come se fa un effetto antenna perchè se allontano la mano non lo fa più. Smette di oscillare anche se porto l'ingresso a +5V o a GND. Sembra quasi che non sia configurato il pull-up interno.

Ho fatto una prova mettendo una resistenza di pull-DOWN tra l'ingresso e il GND e così funziona! Devo proprio mettere le resistenze ?!? allora a cosa servono quelle interne ?

fai l'esperimento a circuito montato,
ossia collega il pulsante a gnd e all'ingresso.
poi premi il pulsante.

e' possibile che il tuo dito si comporti come un condensatore, quindi non toccare i fili direttamente.

fammi sapere, perche' altrimenti occorre aggiungere un codice antirimbalzo.

con che frequenza oscilla?
si accende due volte al secondo? troppo veloce per contare?

Ora non posso provare a montare il pulsante, appena posso faccio la prova e ti faccio sapere. Comunque la frequenza di lampeggio è circa 2Hz (guardando i relè). Sembra si un effetto condensatore perchè quando attacco il filo inizia a lampeggiare. Smette di lampeggiare quando collego l'altro capo del filo al GND o al + 5V oppure se allontano le le dita almeno 10 cm dal filo !!!

scusami, ho trovato l'errore
sostituisci questo:
[edit] for(i=0;i<16;i++){
pinMode(Ingresso+2i, INPUT); //inutile, i piedini sono predefiniti come ingresso
digitalWrite(Ingresso+2
i, HIGH);
pinMode(Uscita+2i, OUTPUT);
digitalWrite(Ingresso+2
i, LOW);
}[/edit]


con questo:

for(i=0;i<16;i++){
pinMode(Ingresso+2i, INPUT); //inutile, i piedini sono predefiniti come ingresso
digitalWrite(Ingresso+2
i, HIGH);
pinMode(Uscita+2i, OUTPUT);
digitalWrite(Uscita+2
i, LOW); //ecco l'errore
}

Ok ! Era proprio quello l'errore ! Mettendo digitalWrite(Ingresso+2*i, LOW) veniva tolta la resistenza di pull-up interna all'ingresso !

Non l'avevo notato ... ci sarei potuto arrivare !!!

Grazie 1000 dell'aiuto !

Alla prossima !