aiuto per scrittura programma (sintassi base)

void setup() {                
  pinMode(13, OUTPUT);     
  pinMode(12, OUTPUT); 
  pinMode(11, OUTPUT);     
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);     
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT); 
  pinMode(6, OUTPUT);     
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);     
}

void loop() {
  digitalWrite(13, HIGH);  
  delay(100);  
  digitalWrite(13, LOW);  
  digitalWrite(12, HIGH); 
  delay(100);
  digitalWrite(12, LOW);  
  digitalWrite(11, HIGH);   
  delay(100);
  digitalWrite(11, LOW); 
  digitalWrite(10, HIGH); 
  delay(100);    
  digitalWrite(10, LOW);
  digitalWrite(9, HIGH);   
  delay(100);              
  digitalWrite(9, LOW);
  digitalWrite(8, HIGH);  
  delay(100);        
  digitalWrite(8, LOW);
  digitalWrite(7, HIGH);   
  delay(100);              
  digitalWrite(7, LOW); 
  digitalWrite(6, HIGH); 
  delay(100);  
  digitalWrite(6, LOW);
  digitalWrite(5, HIGH);  
  delay(100);             
  digitalWrite(5, LOW);
  digitalWrite(4, HIGH);  
  delay(100);
  digitalWrite(4, LOW);  
}

lo sketch sopra e' solo un giochino di luci, accende i led in sequenza

vorrei capire il modo ordinato di scrivere sequenze simili tutte sulla stessa linea, posso trattare (in questo caso le 10 uscite)
comandandole con una linea tipo

1000000000
delay
0100000000
delay
0010000000
delay
0001000000
ecc...
0000000001

che ogni "bit" corrisponda ad un uscita che deve andare alta o bassa (spero d'essermi spiegato anche se molto malamente...)

Intendi così ????

void setup() {                
  for(int i=13;i>=4;i--){ //Così attivi tutte le porte dalla 13 alla 4 
  pinMode(i, OUTPUT);  
   }  
}

void loop() {
  digitalWrite(13, HIGH);  
  delay(100);
  for(int j=13; j>=4; j--){  
  digitalWrite(j, LOW);  
  digitalWrite(j-1, HIGH); 
  delay(100);
  }
}

Comandare la uscite come bit si può ma non saprei come.....
così fà tutto il for se l'ho scritto giusto :stuck_out_tongue:

Beh, hai un sacco di modi per ottenere quella cosa.
Un modo potrebbe essere quello di usare un array di 10 elementi e mettere 1 o 0 in ogni cella se il relativo bit lo vuoi acceso o spento e poi con un for leggerti l'array e fare le opportune scritture.

Visto il tuo caso potresti fare una cosa banale come:

void setup() {
....
}

void loop() {
  for (int i=13; i>3; i--) {
    digitalWrite(i, HIGH);
    delay(100);
    digitalWrite(i, LOW);
  }
}

Poi ripeto, ci sono 1000 modi.

EDIT1:
accident'alla-miseria-ladra-del-"while-you-were" :slight_smile:

EDIT2:
@ratto:
mi sa che col tuo modo il led 4 resta acceso, finito il loop.

il mio era solo un esempio e nell'esempio accende dal 13 al 4 e riparte

ma io intendo proprio accendere come da sequenza che variera'

0100000000
0001000000
1000000000
0000100010
0010000000

insomma quello che e' scritto e ovviamente non gestibile da un +1 il ciclo dopo

ora studio sul tuo suggerimento leo, vediamo che ne capisco

nel C per microcontrollori per pic ricordo che si poteva scrivere PORTB(o A o C o quello che è)=00001111;
e accendeva le porte come riportato nel datasheet.

comunque pagina 81 del datasheet dell'atmega328 sembra esserci qualcosa

La via più semplice è quella di usare una matrice con X celle, con X uguale al numero dei pin che devi gestire e poi con un ciclo accendere/spengere in base allo stato. Oppure usare un int bit per bit.

#define NUM_MAX_LED 10
unsigned int matriceLed=0;

void setup() {
  for (int i=0; i<NUM_MAX_LED;i++) {
    pinMode(i, OUTPUT); //inizializzo pin
  }
}

void loop() {
  accendiLed(0b0000001100110011); //accende i led sui pin 4/5, 8/9 e 12/13
  delay(1000);
  accendiLed(0); //spenge tutto - equivalente a 0b000000000000000;
  delay(1000);
}

void accendiLed(unsigned int temp) {
  byte stato;
  for (int i=0; i<NUM_MAX_LED; i++) {
    digitalWrite(i+4, bitRead(temp, i));
  }
}

Potresti usare un unsigned int e gestire così fino a 16 bit/pin.
Ogni bit rappresenta lo stato del corrispondente led. Nel tuo caso la digitalWrite parte da 4 perché tu usi dal pin 4 al pin 13 (NUM_MAX_LED-1).

"Dovrebbe" funzionare, non l'ho provato.

PS:
cmq con tutti quei led io penserei a qualcos'altro per pilotarli tutti, mi pare un grosso spreco di pin. Basta un misero (ma onesto) 74595 e con 3 pin piloti un numero di led limitato solo dalla massima corrente fornibile dal tuo alimentatore :stuck_out_tongue:

tnx leo :wink:

ora studio il tuo codice, e' quello che cercavo/avevo in mente, ora mi applico :slight_smile:

son richieste per capire come funzionano le cose, i 74hc595 non li ho sottomano ma li devo ordinare per imparare ad usare pure quelli, prossimamente :wink:

Copia il codice di ora, non quello che c'era fino a pochi minuti fa. Avevo in mente un'altra idea ed ho mescolato le cose :stuck_out_tongue:

Ma.... capisco che di pazzi è pieno il mondo :P:P
ma controllarlo in binario così per sport...... :grin:

E' più utile di quel che credi, oltre a farti risparmiare decine di byte di variabili :wink:
In pratica riproduco ciò che la CPU fa internamente, ossia usare dei byte come registri ed i suoi bit come flag di stato.

Sto usando questo metodo con la mia stazione meteo per memorizzare lo stato dei LED e gli errori usando solo 2 byte.
Il byte di stato dei LED lo passo poi direttamente ad uno Shift Register così che a bit settato corrisponde LED acceso e viceversa. Il byte degli errori, mi basta verificare che il suo valore sia maggiore di 0 e so che c'è qualcosa che non va. Il "cosa" lo deduco vedendo appunto quali bit sono settati e quali no.

Si un caso è il debug ma per un giochino va bene anche una variabile di tipo int :smiley:

leo, ho fatto qualche modifica:

#define NUM_MAX_LED 16
unsigned int matriceLed=0;

void setup() {
  for (int i=0; i<NUM_MAX_LED;i++) {
    pinMode(i, OUTPUT); //inizializzo pin
        
  pinMode(A2, OUTPUT);
  pinMode(A1, OUTPUT);  
  pinMode(A0, OUTPUT);
  
  }
}

void loop() {

  accendiLed(0b1000000000000000); //A2
  delay(1000);
  accendiLed(0b0100000000000000); //A1
  delay(1000);
  accendiLed(0b0010000000000000); //A0
  delay(1000);
  accendiLed(0b0001000000000000); //13
  delay(1000);
  accendiLed(0b0000100000000000); //12
  delay(1000);
  accendiLed(0b0000010000000000); //11
  delay(1000);
  accendiLed(0b0000001000000000); //10
  delay(1000);
  accendiLed(0b0000000100000000); //9
  delay(1000);
  accendiLed(0b0000000010000000); //8
  delay(1000);
  accendiLed(0b0000000001000000); //7
  delay(1000);
  accendiLed(0b0000000000100000); //6
  delay(1000);
  accendiLed(0b0000000000010000); //5
  delay(1000);
  accendiLed(0b0000000000001000); //4
  delay(1000);
  accendiLed(0b0000000000000100); //3
  delay(1000);
  accendiLed(0b0000000000000010); //2
  delay(1000);
  accendiLed(0b0000000000000001); //1
  delay(1000);
  
  //accendiLed(0); //spenge tutto - equivalente a 0b000000000000000;
  
}

void accendiLed(unsigned int temp) {
  byte stato;
  for (int i=0; i<NUM_MAX_LED; i++) {
    digitalWrite(i+1, bitRead(temp, i));
  }
}

ho messo 16 led per usare tutti e 16 i "bit" (si possono usare 20 bit come le uscite dell'atmega?)
ho dovuto mettere A0 A1 A2 come output perche' altrimenti non s'accendevano correttamente
non ho capito come poter usare l'output0 (RX) (sarebbe da sistemare qui "digitalWrite(i+1, bitRead(temp, i));" ma non capisco come...)

per fare giochi di luci basta un attimo ad aggiungere 000100100100010 o quel che si voglia :wink:

#define NUM_MAX_LED 16
unsigned int matriceLed=0;

void setup() {
  for (int i=0; i<NUM_MAX_LED;i++) {
    pinMode(i, OUTPUT); //inizializzo pin
  //pinMode(A2, OUTPUT); questi non servono - li hai
  //pinMode(A1, OUTPUT);  già inizializzati qui sopra dato che
  //pinMode(A0, OUTPUT); pin 14=A0, pin 15=A1, pin 16=A2
  // e poi perché li hai messi nel ciclo for? Così li hai
  //inizializzati 16 volte  o__O
  }
}

void loop() {
  matriceLed=0;
  for (int i=0; i<NUM_MAX_LED; i++) {
    bitSet(matriceLed, i); //imposta a 1 l'i-esimo bit del numero
    accendiLed(matriceLed); accende i LED
    delay(1000);
    bitClear(matriceLed, i); //lo spenge - si poteva usare matriceLed=0 ma così è più pulito
    accendiLed(matriceLed); //reimposta
    delay(1000);
  }
}

void accendiLed(unsigned int temp) {
  byte stato;
  for (int i=0; i<NUM_MAX_LED; i++) {
    digitalWrite(i, bitRead(temp, i));
  }
}

ma scusate quello che ho proposto io di usare le funzioni integrate del C è sbagliato? :disappointed_relieved:

Ma il tuo metodo deve tener conto del cambiamento delle porte mentre così comandi direttamente i pin.

Cmq continuo a ribadire che comandare 16 led con 16 piedini è uno spreco di risorse: con 2 595 e 3 piedini ottieni lo stesso risultato.

superlol, il tuo metodo e' troppo avanzato per me, ho guardato il datasheet ma non c'ho capito nulla :slight_smile:

leo, e' solo per provare/imparare, quando avro' i 595 ti rompo pure per loro, assieme ai 5940...
grazie ancora :wink:

leo, dimmi se sbaglio, ma con questo sistema si puo' controllare una matrice di led 8x8?

con i primi 8 bit faccio le righe e con i secondi 8 bit mando a massa la colonna desiderata accendendo i led che seleziono, fattibile con arduino senza altri ic aggiuntivi?

reizel:
leo, dimmi se sbaglio, ma con questo sistema si puo' controllare una matrice di led 8x8?

con i primi 8 bit faccio le righe e con i secondi 8 bit mando a massa la colonna desiderata accendendo i led che seleziono, fattibile con arduino senza altri ic aggiuntivi?

una matrice 8x8 sefvono 16 pin e controlli 64 led, è fattibile, però invece che mettere a massa 8 pin devi metterli ad altri pin di arduino, dai corrente positiva riga (o colonna dipende come si vede) che vuoi e metti a massa la riga (o colonna), il resto lo porti a uno stato logico diverso in modo che non accenda altri led (metti che 1 colonna è LOW le altre tutt HIGH)

superlol, quindi e' fattibile senza molte difficolta', e' una cosa che provero' prossimamente usando il codice di leo

se i primi 8 bit mi gestiscono le colonne e i secondi 8 bit gestiscono le righe

accendiLed(0b0111111100000000); delay(time); //metto a massa la riga 0000 0000
accendiLed(0b1011111100000000); delay(time); //metto a massa la riga 0000 0000
accendiLed(0b1101111100100100); delay(time); //metto a massa la riga 0010 0100
accendiLed(0b1110111100000000); delay(time); //ecc
accendiLed(0b1111011101000010); delay(time);
accendiLed(0b1111101100100100); delay(time);
accendiLed(0b1111110100011000); delay(time);
accendiLed(0b1111111000000000); delay(time);

con un alta frequenza ottengo una specie di faccina :slight_smile:

00000000
00000000
00x00x00
00000000
0x0000x0
00x00x00
000xx000

avete link che spiegano una matrice 8x8 monocromatica...?