Generazione numeri random con arduino

Ciao a tutti,

sono alle prime armi e sto provando a scrivere un codice (che allego qua sotto) che simuli un "dado" cioè al premere di un pulsante il programma genera un numero a caso da 1 a 7 e in base al numero uscito mi accenda determinati led (anch'essi sono 7).

Quando premo il bottone però mi si accendono sempre tutti e 7 i led, come risolvo?

Vi ringrazio in anticipo dell'aiuto :wink:

 int L1=9;
int L2=8;
int L3=7;
int L4=6;
int L5=10;
int L6=11;
int L7=12;
int pulsante=13;
int lettura;
int x=0;
void setup() {

  pinMode(pulsante,INPUT);
  pinMode(L1,OUTPUT);
  pinMode(L2,OUTPUT);
  pinMode(L3,OUTPUT);
  pinMode(L4,OUTPUT);
  pinMode(L5,OUTPUT);
  pinMode(L6,OUTPUT);
  pinMode(L7,OUTPUT);

}

void loop() {
  
  randomSeed(millis());
  if(digitalRead(pulsante)==HIGH){

    x=random(1,7);

    if(x==1){

      digitalWrite(L1,HIGH);
      
    }
    else if(x==2){

      digitalWrite(L1,HIGH);
      digitalWrite(L6,HIGH);
      
    }
    else if(x==3){

      digitalWrite(L1,HIGH);
      digitalWrite(L7,HIGH);
      digitalWrite(L6,HIGH);
      
    }
    else if(x==4){

      digitalWrite(L1,HIGH);
      digitalWrite(L3,HIGH);
      digitalWrite(L4,HIGH);
      digitalWrite(L6,HIGH);
      
    }
    else if(x==5){

      digitalWrite(L1,HIGH);
      digitalWrite(L3,HIGH);
      digitalWrite(L4,HIGH);
      digitalWrite(L6,HIGH);
      digitalWrite(L7,HIGH);
      
    }
    else if(x==6){

      digitalWrite(L1,HIGH);
      digitalWrite(L2,HIGH);
      digitalWrite(L3,HIGH);
      digitalWrite(L4,HIGH);
      digitalWrite(L5,HIGH);
      digitalWrite(L6,HIGH);
      
    }
     else if(x==6){

      digitalWrite(L1,HIGH);
      digitalWrite(L2,HIGH);
      digitalWrite(L3,HIGH);
      digitalWrite(L4,HIGH);
      digitalWrite(L5,HIGH);
      digitalWrite(L6,HIGH);
      digitalWrite(L7,HIGH);
      
    }
    
  }
 
}

Buongiorno,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

A parte che il codice potrebbe essere accorciato molto Credo che il problema sia che non hai bene in mente le tempistiche in cui un loop gira. Esse sono centinaia e forse migliaia di volte al secondo ( dipende dalla complessità del programma). Questo significa che se anche tu tenessi il pulsante premuto per un decimo di secondo, il programma sarebbe decine o centinaia di cicli validi, e quindi ci sarebbero decine o centinaia di estrazioni di numeri casuali, ed è sufficiente che una sola di esse via come risultato sei per avere l' output che lamenti.
Il problema può essere risolto in due modi: ho facendosi che ogni caso spenga tutti i led che non accende ( così si avrebbe l'output corrispondente all'ultimo caso eseguito) eo facendo sì che venga generato un unico numero casuale ogni pressione del pulsante ( così facendo si avrebbe laut corrispondente alla prima ed unica "estrazione" fatta)

...facendosi che ogni caso spenga tutti i led che non accende ...

per quanto hai detto (n cicli loop al secondo), senza un "flag" per determinare pulsante rilasciato, avresti i led con effetto tremolo...ci vuole una variabile per memorizzare che il pulsante è stato premuto una volta e che si resetti al rilascio di questo....

Certo, quella é la soluzione migliore. Non pensavo che per pochibistanti si vedesse comunque (poi quello bisogna farlo lo stesso per non avere turti i led accesi alla fine)

Ma anche tremolante fino a che si rilascia sarebbe un bell'effetto, magari un breve delay per vederlo....
Certo è che serve spegnerle le uscite...

Primo, nel loop generalmente dovresti evitare il "bounce" ossia i rimbalzi meccanici del pulsante (sarebbe bene farlo via hardware con un condensatore ed una resistenza, ma per semplicità per ora tralasciamo questo e facciamolo via software). Però nel tuo caso questo non è importante, in quanto a te basta avere un valore random quantomeno quando rilasci il pulsante: eventuali numeri estratti -anche qualche migliaio al secondo- quando il pulsante rimbalza o anche mentre tieni premuto il pulsante si potrebbero considerare come "rotazioni del dado", quello che conta è il numero finale di quando si rilascia il pulsante.

Ma la cosa più importante è che se i led li accendi solamente (come già ti hanno fato notare) e non spegni quelli relativi al precedente numero, alla fine saranno sempre tutti accesi.

Tra parentesi, la corrispondenza che hai messo tra numero e led da accendere è sbagliata per l'1 in quanto dovrebbe accendere il led centrale, ossia il 7, non l'1, e poi hai due blocchi "if (x==6)".

Per cui per ora ti può bastare cambiare le if in questo modo per far spegnere i led che non servono, e rallentare la generazione dei numeri emettendone non più di una decina al secondo usando un delay(100). Però poi ti consiglio di studiarti un poco gli array, come usare il debounce software e quello hardware, e come rendere migliore la generazione dei numeri casuali:

...
void loop() 
{
  if(digitalRead(pulsante)==HIGH){
    randomSeed(millis());
    x=random(1,7);
    if(x==1){
      digitalWrite(L1,LOW);
      digitalWrite(L2,LOW);
      digitalWrite(L3,LOW);
      digitalWrite(L4,LOW);
      digitalWrite(L5,LOW);
      digitalWrite(L6,LOW);
      digitalWrite(L7,HIGH);
    }
    else if(x==2){
      digitalWrite(L1,HIGH);
      digitalWrite(L2,LOW);
      digitalWrite(L3,LOW);
      digitalWrite(L4,LOW);
      digitalWrite(L5,LOW);
      digitalWrite(L6,HIGH);
      digitalWrite(L7,LOW);    
    }
    else if(x==3){
      digitalWrite(L1,HIGH);
      digitalWrite(L2,LOW);
      digitalWrite(L3,LOW);
      digitalWrite(L4,LOW);
      digitalWrite(L5,LOW);
      digitalWrite(L6,HIGH);
      digitalWrite(L7,HIGH);
    }
    else if(x==4){
      digitalWrite(L1,HIGH);
      digitalWrite(L2,LOW);
      digitalWrite(L3,HIGH);
      digitalWrite(L4,HIGH);
      digitalWrite(L5,LOW);
      digitalWrite(L6,HIGH);
      digitalWrite(L7,LOW);
    }
    else if(x==5){
      digitalWrite(L1,HIGH);
      digitalWrite(L2,LOW);
      digitalWrite(L3,HIGH);
      digitalWrite(L4,HIGH);
      digitalWrite(L5,LOW);
      digitalWrite(L6,HIGH);
      digitalWrite(L7,HIGH);
    }
    else if(x==6){
      digitalWrite(L1,HIGH);
      digitalWrite(L2,HIGH);
      digitalWrite(L3,HIGH);
      digitalWrite(L4,HIGH);
      digitalWrite(L5,HIGH);
      digitalWrite(L6,HIGH);
      digitalWrite(L7,LOW);
    }
    delay(100);
  }
 
}

Solo come curiosità, visto l'argomento, segnalo QUESTO prodottino :smiley:

Guglielmo

gpb01:
Solo come curiosità, visto l'argomento, segnalo QUESTO prodottino :smiley:

Guglielmo

Geniale :slight_smile:

Però 35$... A quel punto usiamo le onde del mare e una boa ;D

Puoi semplicemente fare millis()%7, ottenendo un numero causale tra 0 e 6.
Il modo più semplice è usando il port manipulation:

const byte x=10; // Ingresso per pulsante

void setup()
{
DDRD=127; // Imposta D0...D6 Come uscite
}

void loop()
{
if(digitalRead(x))
  {PORTD=1<<(millis()%7);}
}

In questo modo accende un solo led a caso tra D0 e D6: finché tieni premuto il pulsante, i led scorrono velocissimamente; quando lo lasci, ne resta acceso solo uno. Facendo così non devi nemmeno preoccuparti dei rimbalzi del pulsante.

Uhmm... Tu volevi una cosa diversa, però...

Credo che abbiamo dato fin troppe risposte, l'OP non ha più scritto nulla, e sono passate 3 settimane per cui se non interessa a lui...