[RISOLTO]Utilizzare 4 registri a scorrimento (con 32 LED) senza i delay

mi scuso ancora per il tempo che ci metto a rispondere... Può sembrare un pò irresponsabile, ma non sono sempre libero e qualche volta, quando posso, non ho la testa per ragionare... In giornata proverò ad andare avanti con lo sketch e postero tutto.
Mi scuso ancora per la mancanza di costanza in questi giorni :wink:

Mi sto confondendo, non sto riuscendo nemmeno a capire dove mettere le mani e come devo muovermi: Per questo sto postando il codice il giorno dopo...

#define data_ 2
#define latch_ 3
#define clock_ 4
void setup() {
 pinMode(data_, OUTPUT);
 pinMode(latch_, OUTPUT);
 pinMode(clock_, OUTPUT);

}

void loop() {
DXtoSX(30);   //tempo di accensione tra un LED e l'altro
// SXtoDX(30);   //tra parentesi il delay casualmente uguale tra le animazioni
}

void scritturaregistro(unsigned long valore){          //funzione che si occupa del passaggio dei bit al registro
  digitalWrite(latch_, LOW);
  shiftOut(data_ ,clock_ ,MSBFIRST , valore >> 24 );   //sposto le cifre più significative "in fondo" fino al 32 esimo LED
  shiftOut(data_ ,clock_ ,MSBFIRST , valore >> 16 );
  shiftOut(data_ ,clock_ ,MSBFIRST , valore >> 8 );
  shiftOut(data_ ,clock_ ,MSBFIRST , valore);
  digitalWrite(latch_, HIGH);      }

void DXtoSX(unsigned int delaytoSX){     //DXtoSx (da destra verso sinistra)
 for(long i = 0 ; i < 32 ; i++ ){
  scritturaregistro((unsigned long)0x1 << i);
  delay(delaytoSX);             //ritardo definito nel loop
  }}
 /* void SXtoDX(unsigned int delaytoDX){   //SXtoDX (da sinistra verso destra)
  for(long i = 0 ; i < 32 ; i++){
  scritturaregistro(0x80000000 >> i);
  delay(delaytoDX);             //ritardo definito nel loop (delay diversi per le due animazioni)
  } 
                             }*/

Intanto ho messo come commento la seconda parte di questa animazione, come hai detto tu, in modo da potermi concentrare sulla prima... Bene ora mi chiedo: cosa devo combinare a questa bella funzione? Io non sto riuscendo nemmeno a capire come devo muovermi per fare quello che mi hai detto... Potresti farmi un favore? Che ne dici se provassi a dare una rinfrescata al mio programma? solo per capire cosa inizieresti a fare, in modo da avere magari un input da cui partire... perchè sono veramente in difficoltà... XD

Sei arrivato ad avere una sola fuzione (DXtoSX) in azione, perfetto. Adesso devi eliminare il for e gestire tramite una variabile globale inizializzata a zero. Dentro la funzione (DXtoSX) dopo il delay diciamo, la devi incrementare e verificare se il suo valore non ha sforato il valore massimo (32), in tal caso dovrai azzerarla.
Più chiaro e consico di così non si può :slight_smile:

brun0filipp0:
non sto riuscendo nemmeno a capire dove mettere le mani

I seguenti codici fanno la stessa cosa. Il primo esegue un for di 32 iterazioni contenuto in una funzione (finché non sono finite non si ripassa per il loop). Il secondo esegue sempre le stesse iterazioni (fa 'cose' con 'i' che varia da 0 a 31) ma senza for, affidandosi al fatto che il loop è già un ciclo (non ci si ferma mai a ciclare dentro la funzione, si ripassa sempre per il loop ad ogni giro).

void loop()
{
    funzione();
}
//-------------------------------
void funzione()
{
    for (byte i = 0; i < 32; i++)
    {
        ...cose...;
    }
}
byte i;
//-------------------------------
void setup()
{
    i = 0;
}
//-------------------------------
void loop()
{
    funzione(); 
}
//-------------------------------
void funzione()
{
    ...cose...;
    i++;
    if (i == 32) { i = 0; }
}

Ecco qua il programma:

#define data_ 2
#define latch_ 3
#define clock_ 4
int i;
void setup() {
  i = 0;
 pinMode(data_, OUTPUT);
 pinMode(latch_, OUTPUT);
 pinMode(clock_, OUTPUT);

}

void loop() {
DXtoSX(30);   //tempo di accensione tra un LED e l'altro
// SXtoDX(30);   //tra parentesi il delay casualmente uguale tra le animazioni
}

void scritturaregistro(unsigned long valore){          //funzione che si occupa del passaggio dei bit al registro
  digitalWrite(latch_, LOW);
  shiftOut(data_ ,clock_ ,MSBFIRST , valore >> 24 );   //sposto le cifre più significative "in fondo" fino al 32 esimo LED
  shiftOut(data_ ,clock_ ,MSBFIRST , valore >> 16 );
  shiftOut(data_ ,clock_ ,MSBFIRST , valore >> 8 );
  shiftOut(data_ ,clock_ ,MSBFIRST , valore);
  digitalWrite(latch_, HIGH);      }

void DXtoSX(unsigned int delaytoSX){     //DXtoSx (da destra verso sinistra)
  scritturaregistro((unsigned long)0x1 << i);
  delay(delaytoSX);            //ritardo definito nel loop
  i++;
    if(i = 32) { i = 0; }
  }
 /* void SXtoDX(unsigned int delaytoDX){   //SXtoDX (da sinistra verso destra)
  for(long i = 0 ; i < 32 ; i++){
  scritturaregistro(0x80000000 >> i);
  delay(delaytoDX);             //ritardo definito nel loop (delay diversi per le due animazioni)
  } 
                             }*/

Continuo ancora con lo scusarmi per la grande chiarezza che richiedo, ma non essendo molto pratico nel programmare sono così'... :slight_smile:
Non perdiamoci in chiacchiere e continuiamo... Ho modificato il programma sostituendo il ciclo for con la variabile i e l'if... Nonostante questa piccola e semplice modifica l' IDE di Arduino ha iniziato a fare i capricci perchè ha iniziato a darmi un errore di caricamento per la mia scheda Arduino Uno (come se avessi collegato al PC un arduino diverso, ma in realtà non ho toccato nè l'arduino nè la breadboard con tutto il circuito)

exit status 1
Errore durante la compilazione per la scheda Arduino/Genuino Uno.

Quale potrebbe essere il problema?

Mi rammarico di non aver scritto 32==i come volevo fare :roll_eyes:

if (32 == i) { i = 0; }

A parte quello il codice è giusto. L'errore di caricamento dipende da altro.

Ho sistemato l'if come dicevi tu, ho messo solo un uguale perchè non me n'ero accorto... Solo che non riesco a capire quale sia il problema del programma perchè con alcuni programmi si riesce a caricarli su arduino... (la porta usb collegata all'arduino non c'entra, ma comunque ho provato anche ad usarne un' altra)

Sto cercando qualche soluzione per far funzionare questo benedetto programma e ho provato questo... Secondo voi sono sulla strada giusta?

 unsigned long previousMillis1;        // will store last time LED1 was updated
 unsigned long previousMillis2;
 const long interval1 = 300;               // interval at which to blink1 (milliseconds)
 unsigned long currentMillis1;
 unsigned long currentMillis2;
 unsigned long intervalshift = 0;
#define data_ 2
#define latch_ 3
#define clock_ 4 
unsigned int i = 0;
void setup() {
  #define led 8
  pinMode(led, OUTPUT);
  pinMode(data_, OUTPUT);
 pinMode(latch_, OUTPUT);
 pinMode(clock_, OUTPUT);
 Serial.begin(9600);
  unsigned long previousMillis1 = 0; 
}

void loop() {
  unsigned long currentMillis1 = millis();
  Serial.println(previousMillis1);
   animazione1();
         }
  
  void scritturaregistro(unsigned long valore){          //funzione che si occupa del passaggio dei bit al registro
  digitalWrite(latch_, LOW);
  shiftOut(data_ ,clock_ ,MSBFIRST , (valore >> 24) );   //sposto le cifre più significative "in fondo" fino al 32 esimo LED
  shiftOut(data_ ,clock_ ,MSBFIRST , (valore >> 16) );
  shiftOut(data_ ,clock_ ,MSBFIRST , (valore >> 8) );
  shiftOut(data_ ,clock_ ,MSBFIRST , valore);
  digitalWrite(latch_, HIGH);      }

void animazione1(){     //funzione che si occupa dell'unica (fin ora) animazione che ho creato
  if((currentMillis1 - previousMillis1) >= 100){ 
 previousMillis1 = currentMillis1;
 i++;
  }
 if(i <= 32){            //animazione da sinistra verso destra
    scritturaregistro((unsigned long)0x1 << i);
 }     
  /*  for(long i = 0 ; i < 32 ; i++){              //animazione da destra verso sinistra
  scritturaregistro(0x80000000 >> i);
  delay(100);
  } */
}

Ditemi cosa ne pensate... sintatticamente il programma è corretto, ma il delay che ho improntato nel void animazione1 non sembra fare il suo lavoro... qualche idea?

Te l'ho data 17 giorni fa, nel messaggio n.12.

ah, scusami Datman... comunque sono ripassato subito a scrivere che sono riuscito a farlo funzionare!!!
ecco il programma:

 unsigned long previousMillis1;        // will store last time LED1 was updated
 unsigned long currentMillis1;
 const int intervalshift = 50;
#define data_ 2
#define latch_ 3
#define clock_ 4 
int i;
void setup() {
  #define led 8
  pinMode(led, OUTPUT);
  pinMode(data_, OUTPUT);
 pinMode(latch_, OUTPUT);
 pinMode(clock_, OUTPUT);
 Serial.begin(9600);
  unsigned long previousMillis1 = 0; 
}

void loop() {
  unsigned long currentMillis1 = millis();
  Serial.println(previousMillis1);
   animazione1();
         }
  
  void scritturaregistro(unsigned long valore){          //funzione che si occupa del passaggio dei bit al registro
  digitalWrite(latch_, LOW);
  shiftOut(data_ ,clock_ ,MSBFIRST , (valore >> 24) );   //sposto le cifre più significative "in fondo" fino al 32 esimo LED
  shiftOut(data_ ,clock_ ,MSBFIRST , (valore >> 16) );
  shiftOut(data_ ,clock_ ,MSBFIRST , (valore >> 8) );
  shiftOut(data_ ,clock_ ,MSBFIRST , valore);
  digitalWrite(latch_, HIGH);      }

void animazione1(){     //funzione che si occupa dell'unica (fin ora) animazione che ho creato
  if((millis() - previousMillis1) >= intervalshift){   //al posto della variabile che "simula" la funzione millis() ho prorpio messo millis()
 previousMillis1 = millis();                           //stessa cosa qua
 i++;
  }
 if(i <= 32){            //animazione da sinistra verso destra
    scritturaregistro((unsigned long)0x1 << i);
 } 
 else { i = 0; }    
  /*  for(long i = 0 ; i < 32 ; i++){              //animazione da destra verso sinistra
  scritturaregistro(0x80000000 >> i);
  delay(100);
  } */
}

ho praticamente messo direttamente la funzione millis al posto della variabile che lo simula... ora qualcuno sa spiegarmi per quale motivo con la variabile, non funziona il "delay"? Quando feci per la mia prima volta un semplice blink, questo funzionava... potrebbe darmi problemi se usassi direttamente la funzione millis() per definire i ritardi delle varie operazioni nel programma? (Datman ho visto la tua idea ma sembra buona, ma credo di averne trovata un buono pure io!)

brun0filipp0:
ho praticamente messo direttamente la funzione millis al posto della variabile che lo simula... ora qualcuno sa spiegarmi per quale motivo con la variabile, non funziona

Non funziona perché hai definito (tramite il qualificatore unsigned long) in differenti punti delle variabili con lo stesso nome, ma che di fatto NON sono la stessa variabile.

Quelle definite dentro le funzioni sono locali (esistono solo all'interno delle funzioni).

Seconda cosa:

ilcodicevaindentatoaltrimentiècomecostringereglialtrialeggereuntestocomequestoscomodovero?

Il che è anche molto semplice, perché sull'IDE basta scegliere:
Strumenti->formattazione automatica.

ok, mi spiace non aver indentato il programma e renderlo mooolto più ordinato, ma a dire il vero non ero nemmeno a conoscenza di questa cosa :)... Quindi grazie!
Va bene, pare che io abbia finalmente risolto questa lunga questione... Ringrazio nuovamente tutti per il supporto... ora, ho un' altra piccola domanda:
Vorrei creare una seconda animazione in questo mio programma che sostanzialmente dovrebbe accendere e spegnere dei led a caso in un determinato intervallo di tempo... (come nelle luci degli alberi di natale). Sapete darmi un aiuto per questo?

Dato che siamo riusciti a far funzionare questo bel programma, lascio a tutti la possibilità di vedere il mio programma ora funzionante, per chiunque volesse dare una sbirciata!

unsigned long previousMillis1;        // dove si aggiorna l'ultima scrittura dei LED
unsigned long previousMillis2;
unsigned long previousMillis3;
unsigned long currentMillis1;
const int intervalshift = 50;
const int intervalshift2 = 350;
#define data_ 2
#define latch_ 3
#define clock_ 4
int i;
int j;
int k;
void setup() {
  pinMode(data_, OUTPUT);
  pinMode(latch_, OUTPUT);
  pinMode(clock_, OUTPUT);
}

void loop() {
  animazione_slide();
 
}

void scritturaregistro(unsigned long valore) {         //funzione che si occupa del passaggio dei bit al registro
  digitalWrite(latch_, LOW);
  shiftOut(data_ , clock_ , MSBFIRST , (valore >> 16) ); //sposto le cifre più significative "in fondo" fino al 32 esimo LED
  shiftOut(data_ , clock_ , MSBFIRST , (valore >> 8) );
  shiftOut(data_ , clock_ , MSBFIRST , (valore) );
  digitalWrite(latch_, HIGH);
}

void animazione_slide() {
  if ((millis() - previousMillis1) >= intervalshift) {    //al posto della variabile che "simula" la funzione millis() ho prorpio messo millis()
    previousMillis1 = millis();                           //stessa cosa qua
    i++;
  }
  if (i <= 24) {          //animazione da sinistra verso destra
    scritturaregistro((unsigned long)0x1 << i);
  }
  else {
    i = 0;
  }
  if ((millis() - previousMillis2) >= intervalshift) {
    previousMillis2 = millis();
    j++;
  }
  if ( j <= 24) {                            //animazione da destra verso sinistra
    scritturaregistro(0x800000 >> i);
  }
  else {
    j = 0;
  }
}





}

Grazie ancora a tutti.