Domandina semplice semplice sugli array

Mi scuso per la banalità delle mie richieste ma sto procedendo per piccoli passi.
Dunque, mi sono divertito a mettere sei led collegati sulle uscite D8-D13 con le relative resistenze e a scrivere un semplice sketch per farli accendere o spegnere singolarmente o a gruppi o tutti insieme. Ovviamente ho usato una serie infinita di digitalWrite HIGH - delay - digitalWrite LOW e così via. Ho trovato un tutorial dove proprio per evitare tutta questa sfilza di ripetizioni e per alleggerire il codice consiglia l’uso di array. Ho utilizzato questo codice :

/* Knight Rider 3
 * --------------
 *
 * This example concentrates on making the visuals fluid.
 *
 *
 * (cleft) 2005 K3, Malmo University
 * @author: David Cuartielles
 * @hardware: David Cuartielles, Aaron Hallborg
 */

int pinArray[] = {13, 12, 11, 10, 9, 8};
int count = 0;
int timer = 30;

void setup(){
  for (count=0;count<6;count++) {
    pinMode(pinArray[count], OUTPUT);
  }
}

void loop() {
  for (count=0;count<5;count++) {
   digitalWrite(pinArray[count], HIGH);
   delay(timer);
   digitalWrite(pinArray[count + 1], HIGH);
   delay(timer);
   digitalWrite(pinArray[count], LOW);
   delay(timer*2);
  }
  for (count=5;count>0;count--) {
   digitalWrite(pinArray[count], HIGH);
   delay(timer);
   digitalWrite(pinArray[count - 1], HIGH);
   delay(timer);
   digitalWrite(pinArray[count], LOW);
   delay(timer*2);
  }
}

Mi sono divertito a fare delle prove e fin quì tutto ok. Ma non sono riuscito a fare una cosa credo semplicissima…accendere tutti i led insieme e spegnerli tutti insieme…
Non ho trovato nelle reference cosa deve essere inserito tra le parentesi quadre. Dall’esempio ho visto che si può inserire una variabile, ma se io volessi assegnare contemporaneamente a tutti i PIN lo stesso valore utilizzando l’array come devo fare ? Mi scuso ancora per la banalità della richiesta…

Le domande semplici sono sempre le piú bastarde.

int pinArray[] = {13, 12, 11, 10, 9, 8};

equivale a

int pinArray[6]; 
pinArray[0] = 13;
pinArray[1] = 12;
pinArray[2] = 11;
pinArray[3] = 10;
pinArray[4] = 9;
pinArray[5] = 8;

Il primo elemento é zero!!! poi 1 2 ecc.

Nel esempio viene messo una “variabile” come indice del Array, che non é nient altro che un “nome per un valore numerico”.

for (count=0;count<6;count++) {
    pinMode(pinArray[count], OUTPUT);
  }

La variabile count spazia da 0,1 ,2, 3, 4, 5 .

Ciao Uwe

penso che basta fare un ciclo for senza mettere i delay che mettono in pausa il programma!
per accendere tutti i led:

for(int i = 0; i < 6;i++) {
     digitalWrite(pinArray[i],HIGH);
}

per spegnerli:

for(int j =0; j < 6;j++){
     digitalWrite(pinArray[j],LOW);
}

Non puoi accendere o spegnere più di un led con un ciclo for, proprio perchè esegue le operazioni relativamente per contatore, quindi non puoi =D

Uwe e Smasho ti hanno risposto correttamente. Il codice che hai usato tu serve a creare un "effetto" di transizione ma con i delay fermi l'esecuzione del programma.

Tieni anche conto che "teoricamente" ha anche ragione Diamond39 dato che con un ciclo for (ma anche scrivendo i digitalWrite uno dopo l'altro), anche se in maniera velocissima, accendi sempre in sequenza i led: ad occhio nudo, a 16 MHz di velocità del micro, la cosa è trascurabile, ma tecnicamente non li stai accendendo insieme... Per poterlo fare serve usare altri accorgimenti.

Diamond39: Non puoi accendere o spegnere più di un led con un ciclo for, proprio perchè esegue le operazioni relativamente per contatore, quindi non puoi =D

Sí, forse la frase scritta da Diamond é da spiegare meglio. Si usa il ciclo for per non dover scrivere (in questo caso) 6 volte

digitalWrite(pinArray[],HIGH);

Si scrive 1 volta e il ciclo lo esegue 6 volte con l'indice del Array diverso. In questo modo cambio lo stato delle 6 uscite, una dopo l'altra, ma cosí velocemente che non si nota. Ciao Uwe

Diamond39: Non puoi accendere o spegnere più di un led con un ciclo for, proprio perchè esegue le operazioni relativamente per contatore, quindi non puoi =D

parole sagge, ma puoi fargli fare un'operazione alla volta alla velocità di 16 milioni di hz e farlo sembrare un'unica informazione.

attento a non esagerare, l'arduino ha un'erogazione massima di corrente (varia in base al tipo di arduino), se non si accendono contemporaneamente la causa potrebbe essere l'insufficenza ad alimentare da parte di arduino.

se ti capita questo bisogna alimentare i led separatamente.

Ciao Marbi

Marbi:

Diamond39:
Non puoi accendere o spegnere più di un led con un ciclo for, proprio perchè esegue le operazioni relativamente per contatore, quindi non puoi =D

parole sagge, ma puoi fargli fare un’operazione alla volta alla velocità di 16 milioni di hz e farlo sembrare un’unica informazione.

Se andiamo nel pignolo é possibile accendere 8 LED in contemporanea se sono messi sui ping giusti, ma non l’ ho segnalato perché é complesso. Si puó manipolare direttamente i registri di uscita del ATmega e visto che ne ha 3 che fanno le 20 uscite/entarte si possono settare 8 alla volta. Si deve conoscere bene a quale pin corrisponde quale Bit del rigistro. Oltre a quello si devono avere le idee chiare per l’uso delle operazioni and e or di bit.
vedi http://www.arduino.cc/en/Reference/PortManipulation

ciao Uwe

Per poterlo fare serve usare altri accorgimenti.

E' lo stesso motivo (la complessità) per cui anch'io avevo accennato al fatto che è è possibile accendere contemporaneamente 8 led ma non avevo aggiunto info dato che l'utent è alle prime armi ed è bene che inizi capendo le basi.

Sí leo. Stiamo esagerando.

Il fatto che i LED si accendono con qualche µ-secondo di differenza non é ne visibile ne ha qualche altro effetto. Percui mi permetto di dire che con un ciclo for i LED si accendono praticamente in contemporanea.

Ciao Uwe

Quanto cose ho da apprendere da voi !!! Quella che a me sembrava una cosa banale ed ovvia dove io non riuscivo ad arrivare, in realtà ha generato una discussione molto interessante e “tecnica”. Per quello che intendevo fare io, ossia spegnere ed accendere contemporaneamente tutti led bastava sfruttare la velocità di esecuzione e come ha detto giustamente Uwe la differenza non è visibile ad occhio. In pratica ho utilizzato il codice postato da smasho inserendo il ritardo dopo il ciclo for

void loop() 
{
   for (count=0;count<6;count++) {
   digitalWrite(pinArray[count], HIGH);}
   delay(timer);
   for (count=0;count<6;count++) {
   digitalWrite(pinArray[count], LOW);}
   delay(timer);
  }

Per quanto riguarda l’utilizzo diretto dei registri di uscita per attivare contemporaneamente tutte le uscite, mi sa’ che dovrò studiare ancora molto !!! XD
Però anche se non necessario nel mio caso per l’accensione dei led ritengo molto utile l’informazione ricevuta che comunque è una cosa possibile anche se non semplice da mettere in pratica.

Uwe e Leo, quanto scommettete che tra poco finirete in OT parlando della possibilità di lanciare 2 missili contemporaneamente nello spazio? :smiley:

dvb a stare dietro loro s’impara molto, il problema è che dovresti sequestrarteli e portarteli a casa, li leghi e li fai parlare.

Quando non ti occorrono più nasce il secondo problema… t’accorgi che non riesci più a fermarli. ahahah

[DOMANDA]

cmq per capirci era possibile farlo anche così?
Possiedo un Arduino Mega, i valori saranno differenti?

int Tempo = 500; //Intervallo in ms
void setup () {
DDRD = B11111100; // setta dal pin 2 al pin 7 in uscita
}
void loop () {
PORTD = B11111100;
delay(Tempo);
PORTD = B00000000; 
delay(Tempo);
}

Marbi

Però se mi porti a casa mi devi anche sfamare... e nonostante la mia costituzione esile ti posso garantire che consumo... e molto! :D

PS: era il metodo a cui accennavamo: pilotare i bit delle porte di I/O in maniera diretta. In questo modo avresti la certezza che l'accensione è simultanea dato che il registro che gestisce la porta viene presentato in un unico passaggio. Ma siamo a livelli di programmazione che, per un uso "normale" (qual è appunto l'accensione di qualche led), servono a poco. Meglio fare le cose in modo semplice ma funzionale.

Marbi:
[DOMANDA]
cmq per capirci era possibile farlo anche così?

Possiedo un Arduino Mega, i valori saranno differenti?

sí, È possibile farlo cosí, ma come tu fai ignori lo stato dei BIT 0 e 1 del Registro che potrebbero essere usati per altri scopi. Devi leggere lo stato del registro e cambiare solo i bit che Ti servono e poi scriverlo.

È proprio questo la difficoltá di sapere al livello uscita quale registro corrisponde con quale piedino del ATmega e con quale PIN del arduino é collegato.
Guara il datasheet del ATmega2560 o rispettivamente ATmega1280 e gli schemi elettrici del Arduino MEGA/MEGA2560 .
Ciao Uwe

Leo a casa mia dove mangiano in 5 mangiano anche in 6 uwe io il datasheet l'ho guardato per molto tempo, ma ad un certo punto mi si incrociano gli occhi e non capisco più niente.

ancora sono molto in alto mare nel campo dell'elettronica :(

cmq ho capito cosa intendi dire, bisognerebbe prelevare lo stato e successivamente modificare i singoli bit che vanno modificati lasciando inalterati gli altri... non dovrebbe essere estremamente complicato.

Marbi

Uwe voleva dirti che ogni porta potrebbe essere usata per altre cose. Ad esempio metà dei bit potrebbero gestire una cosa e metà un'altra. Quindi andrebbero modificati solo i bit realmente usati e riscritto il registro così com'è. Se modifichi tutto un registro tocchi anche i bit che non usi per cui puoi dar noia al resto che usa lo stesso registro. Per le operazioni sui singoli bit puoi far riferimento al Reference.

al Reference ancora non ci sono arrivato, ma il concetto adesso mi è chiaro.

grazie delle molteplici info ragazzi :D

leo72: Uwe voleva dirti che ....

che bello, ho l'interpretatore personale. ;) ;) ;) Confermo quello che disse Leo riguardo ai registri.

Marbi: uwe io il datasheet l'ho guardato per molto tempo, ma ad un certo punto mi si incrociano gli occhi e non capisco più niente.

È proprio per quello che non diciamo sempre tutto a tutti. Per capire il datasheet ci vuole un po di esperienza nel campo che uno che incomincia non ha a ancora. Il dato della correspondenza dei port con i piedini del ATmega2560 e 1280 lo trovi a pagina 2 del http://www.atmel.com/dyn/resources/prod_documents/doc2549.PDF e dei piedini a pin sul http://arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf Ciao Uwe

fammi capire se ho capito... per esempio i pin dal 71 al 78 li gestisco con le funzioni "PORTA","DDRA" e "PINA", e così via... ho inteso bene?

Marbi

vorrei essere pignolo: dai piedini 78 a 71 del ATmega2560; il bit 0 é 78 e il bit 7 é 71

che poi sul Arduino Mega sono collegati ai pin 22 fino 29 ciao Uwe