Random led 8 luci + 8 buzzer collegati

salve a tutti,
mi presento, sono Francesco. Sono arrivato nel mondo di arduino da circa due settimane.
Lo schema del mio progetto è molto semplice:
randomizzare l'accensione spegnimento di 8 led collegati ad altrettanti buzzer (passivi o attivi, ancora non so) così:
accensione del buzzer e spegnimento di esso dopo 2 msec
accensione del led ad esso collegato dopo lo spegnimento del buzzer dopo 50 msec
spegnimento del led dopo 100 msec.

Sto avendo difficoltà già con la prima parte: randomizzare i led con un chip 74hc595.
Ho trovato molto semplice randomizzare le luci attaccando i led direttamente ai pin, ma dovendo poi collegare i buzzer finirei le porte, per questo ho deciso di utilizzare il chip, spero di aver fatto bene..

Comunque vi allego il codice scritto da me con qualche aiuto trovato in giro, manuale compreso.. Per adesso si accendono in modo random i led, ma essi non mi si spengono quando vorrei io, ma lo fanno quando si accende consecutivamente il led successivo (nel codice ho messo dei delay ampi in modo tale che siano ben visibili).
un aiutino al nuovo arrivato?
grazie a tutti e buona giornata!
Francesco

//Random 8 blink

    int SER_Pin = 12;    //dataPin
    int RCLK_Pin = 11;   //latchPin
    int SRCLK_Pin = 9;   //clockPin 
    byte leds = 0;
    int randNumb; 

         
    #define number_of_74hc595s 1 //How many of the shift registers are there daisey chained?
    #define numOfRegisters number_of_74hc595s * 9
         
    int registers[numOfRegisters];
         
    void setup(){
         
      Serial.begin(9600);
  setRegister(1, LOW);
  setRegister(2, LOW);
  setRegister(3, LOW);
  setRegister(4, LOW);
  setRegister(5, LOW);
  setRegister(6, LOW);
  setRegister(7, LOW);
  setRegister(8, LOW);
     
  writeRegisters();
         
      pinMode(SER_Pin, OUTPUT);
      pinMode(RCLK_Pin, OUTPUT);
      pinMode(SRCLK_Pin, OUTPUT);
      randomSeed(analogRead(A0));
         
      clearRegisters();
      writeRegisters();
    }               

    void clearRegisters(){
      //set all registers to LOW
      for(int i = numOfRegisters; i >  0; i--){
         registers[i] = LOW;
      }
    }


    void writeRegisters(){
    //Set and display registers
      digitalWrite(RCLK_Pin, LOW);
         
      for(int i = numOfRegisters; i >  0; i--){
        digitalWrite(SRCLK_Pin, LOW);
           
        int val = registers[i];
           
        digitalWrite(SER_Pin, val);
        digitalWrite(SRCLK_Pin, HIGH);
      }
      digitalWrite(RCLK_Pin, HIGH);
    }

    void setRegister(int index, int value){
      //set individual register
      registers[index] = value;
    }


    void loop(){
            {
     delay(500);
     leds = 0;
     clearRegisters();
     delay(500);
       int randNum = random(1,9);
        Serial.println(randNum);
       {   
       if(randNum == 1)
         setRegister(1, HIGH);
       }
       {
         if(randNum == 2)
         setRegister(2, HIGH);
       }
       {
         if(randNum == 3)
         setRegister(3, HIGH);
       }
       {
         if(randNum == 4)
         setRegister(4, HIGH);
       }
       {
         if(randNum == 5)
         setRegister(5, HIGH);
       }
       {
         if(randNum == 6)
         setRegister(6, HIGH);
       }
       {
         if(randNum == 7)
         setRegister(7, HIGH);
       }
       {
         if(randNum == 8)
         setRegister(8, HIGH);
       }
     }

     writeRegisters();
     delay(1000);
    }

Fammi capire:
che controller usi? Arduino Uno o altro?
in che senso led e buzzer collegati?

Ciao, grazie della risposta..
Uso un Elegoo UNO.
Collegati nel senso che per esempio se l'outupt é generato dal buzzer n. 1 allora si accenderà sempre il led n. 1
Se l'output é generato dal buzzer n. 2 si accenderà sempre il led n. 2 e così via..
Probabilmente dovró usare due chip alla volta collegandoli in serie (o altro metodo) , ma per adesso sto ancora lottando con la randomizzazione dei led.. (uso in questa fase i led e non i buzzer per praticità, tanto per adesso mi basta trovare la strada giusto per randomizzare).

Che difficoltà incontri nell'uso della funzione random() ?

Guglielmo

La difficoltà é "solamente" :-\ nel fatto che vorrei che la luce che ho acceso in modo random si spegnesse dopo che l'ho accesa, ma se provo ad esempio adare il comando così:

 randNum = random(1,9);
        Serial.println(randNum);
       {   
       if(randNum == 1)
         setRegister(1, HIGH);
         Delay(500);
	setRegister(1, LOW) ;

La luce mi rimane accesa lo stesso fino a che non si accende quella dopo.. Cioé si spegne immediatamente prima dell'accensione di quella dopo..

Una domanda, ma la tua intenzione è avere ad esempio una cosa del tipo più luci che si accendono e spengono indipendentemente l'una dall'altra? Ovvero una luce si accende per N millisecondi, dopo un pochino se ne accende un'altra per X millisecondi, trascorso il tempo N la prima si spegne e così via?

Grazie a tutti per l'aiuto.. Provo a spiegarmi meglio.. ;D
Vorrei che:
Si accende una luce per esempio 100 msec
Poi si spenge.
Dopo altri 50 msec si accende un'altra per 100 msec
Poi si spenge.
Etc etc etc..

Stando al tuo codice ile operazioni sono:
aspetto 500ms
pulisci i registri (ma non li scrivi quindi se era acceso qualcosa resta tale)
aspetti 500ms
calcoli un led a caso da 1 a 9
setti il relativo registro
scrivi i registri (di fatto accendi il led)
aspetti 1000ms
e inizi di nuovo il tutto, secondo me ti basta una writeRegisters() dopo la clearRegisters()

Altra cosa è innutile quella schiera di if, guardali bene se il numero è uguale ad una certa cifra scrivi HIGH nella posizione del numero casuale, ti basta fare:

setRegisters(randNum, HIGH);

eliminando tutti gli if innutili

E non l'avevo notato ma il tuo codice

{   
   if(randNum == 1)
      setRegister(1, HIGH);
}

è scritto male (compilare compila e funzona per pura fortuna ovvero dopo l'if fai una sola operazione).
Per scrivere bene il costrutto la sintassi è la seguente:

if(randNum == 1)
{
  setRegister(1, HIGH);
}

Fermo restando che gli if qui non servono come indicato nel post precedente

Grazie davvero..
Quando torno a casa da lavoro provo e poi vi faccio sapere..
:smiley:

Secondo me non ti è ben chiaro come funziona RCLK, dunque il fatto che se vuoi cambiare tutti gli 8 valori "in una volta sola", devi prima shiftare gli 8 valori nel registro uno ad uno e solo alla fine dare un impulso positivo su RCLK.

SukkoPera:
Secondo me non ti è ben chiaro come funziona RCLK, dunque il fatto che se vuoi cambiare tutti gli 8 valori "in una volta sola", devi prima shiftare gli 8 valori nel registro uno ad uno e solo alla fine dare un impulso positivo su RCLK.

"non ti é ben chiaro" é un eufemismo.. :slight_smile:
Peró cerco di imparare guardando, leggendo e prendendo spunto..
Grazie a tutti veramente..

a me pare che con setregister imposti i "cambiamenti" ma diventano operativo solo dopo che hai eseguito writeRegisters()

io proverei con

       if(randNum == 1)
         setRegister(1, HIGH);
         writeRegisters();
         Delay(500);
	setRegister(1, LOW) ;
        writeRegisters();

mi accorgo ora che è anche quello che ha scritto fabpolli :smiley:

Che poi tutta quella parte di loop (le varie if random== ) possono essere abilmente eliminate, inserendo il codice tra le loro graffe una dola volta ed utilizzando direttamente random al posto dei numeri da 1 a 8. Così riduci le righe e sei più tranquillo da eventuali errori di scrittura

la prima parte del progetto pare che funzioni.. adesso provo a collegare dei buzzer e randomizzare anch'essi..
grazie ancora!!
vi tengo aggiornati e poi fornisco lo script completo a disposizione di tutti..
se riesco a farlo.. :slight_smile: