Random 1/0 ? ...Cubo led + Video

Ciao a tutti ragazzi...son riuscito a creare il mio cubo led 6x6 con 6 74hc595 e...strano ma vero...funziona!! solo che ora mi sorge un problma di programmazione...io vorrei fare una cosa random....ma essendo che questo cubo è fato con i 74hc595 non saprei come fare...come posso fare a dire all'arduino di crearmi 6 serie di numeri random da 8 bit che siano o "1" o "0" ? grazie a chiunque possa aiutarmi...

EDIT del 29-08-2011 Eccovi il link al video...

Usa delle variabili di tipo byte e poi accendi/spengi i singoli bit con le funzioni per i bit (vedi reference) bitSet e bitClear. Poi mandi direttamente i byte ai 595. Bit 1 = led acceso, bit 0 = led spento.

d'accordo...funziona...cioè, non ho capito cosa mi hai detto tu, ma ho preso spunto dalla tua risposta e son riuscito a realizzare qualcosa Rando....ma ora mi sorge un altro problema...per quanto riguarda il random delle colonne va benissimo...solo che vorrei impostare anche un random di tipo diverso per il 595 che gestisce i piani....vorrei che il suo random venga scelto fra determinati numeri preimpostati...come per esempio....21,45,37 ecc.... è possibile? ps, se poi interessa a qualcuno posto delle foto...

Se hai bisogno di estrarre da valori predeterminati, creati un array con le combinazioni che desideri e poi "pesca" da quello.
Altrimenti considerando che la griglia è 6x6 puoi semplicemente estrarre 2 numeri compresi fra 0 e 5 ed avrai così le coordinate x,y del led da accendere.

mi sembra anche logica come soluzione ma...per crearmi un array dovrei crearmi le combinazioni per ogni singolo led? ovvero dovre scrivere che il primo le in alto a sinistra corrisponde a :=
01111111
11111111
11111111
11111111
11111111
10010001

per esempio...e tutto ciò dovrei farlo per ogni singolo led per ogni array? O.o son più di 200 combinazioni...

Ciao

credo che il suggerimento fosse diverso... ammettiamo che vuoi un random tra 5, 7, 12, 23, 70
crei un array con tali valori, usi la funzione random(5) che ti da un valore tra 0 e 4 e prendi il valore ottenuto come indice dell'array (ovvero rendi randomica la "scelta" dell'elemento nel tuo array)

bye

allora, 8 bit sono valori in decimale da 0 a 255.
Quindi metodo molto facile: crei un numero random da 0 a 255, ed ecco la tua serie di 0 e 1 casuali.
i numeri random li crei con la funzione random(): http://www.arduino.cc/en/Reference/Random

Ancora meglio: visto che devi creare molti bit casuali, non limitarti a 255.
La random lavora con i long, quindi puoi usare random(-2,147,483,648, 2,147,483,647) creando ben 4 byte alla volta, poi per creare "solo" 2 byte usi il range degli integer, ovvero da -32,768 a 32,767

poi per estrarre solo un byte, usi il bitshif (che lavora sui bit)

esempio

long numeroRandom=random(-2,147,483,648, 2,147,483,647);//creo un long random
byte serie[4];
serie[0]=numeroRandom; //estraggo il byte più a destra
serie[1]=numeroRandom>>8; //estraggo il secondo byte più a destra
serie[2]=numeroRandom>>16; //estraggo il terzo byte più a destra
serie[4]=numeroRandom>>24; //estraggo il byte più a sinistra
(il codice può essere migliorato con l'uso di un for per riempire l'array)

Attenzione: se non includi i numeri negativi il bit più a sinistra sarà sempre 0.
Attenzione2: se resetti arduino noterai che la random crea sempre gli stessi valori. Per evitare ciò puoi inizializzare (una sola volta nel setup basta) un seme (http://arduino.cc/en/Reference/RandomSeed) con un numero casuale, che per esempio potrebbe essere una lettura analogica su un pin vuoto
Vantaggi: la random è relativamente lenta, minimizzare le volte che chiami la funzione è l'ideale. Potresti usare solo le letture analogiche, ma rischi di vedere sempre le stesse frequenze.

Tu hai fatto una domanda, io ti ho dato una risposta :wink:
Non so quante combinazioni precostituite vuoi.

Puoi usare un semplice array monodimensionale con i valori come li avevi messi tu, ossia 21, 45 ecc... e fare poi la conversione in fase di invio dati. Ad esempio, 21 potrebbe indicare il led da accendere nella forma YX, quindi 2a riga e 1a colonna. I modi sono tanti ed io non so quante combinazioni vuoi. E come vuoi accendere i led, ossia a gruppi oppure singolarmente ecc...

babbu95:
mi sembra anche logica come soluzione ma...per crearmi un array dovrei crearmi le combinazioni per ogni singolo led? ovvero dovre scrivere che il primo le in alto a sinistra corrisponde a :=
01111111
11111111
11111111
11111111
11111111
10010001

per esempio...e tutto ciò dovrei farlo per ogni singolo led per ogni array? O.o son più di 200 combinazioni...

sono 255 combinazioni. Probabilmente l'atmega non ha nemmeno abbastanza RAM per contenere il tutto. Creare l'array mi sembra una baggianata, visto che comunque useresti una random. Insomma tanto codice per nulla.

A parte che le combinazioni non sono date da una matrice 8x8 dato che lui ha detto di avere una griglia di led 6x6 quindi non deve usare tutti gli 8 bit di 8 byte ma, come ho detto all'inizio, 36 bit, 6x6 bit (quindi 5 byte max). Ma le combinazioni totali di 6x6 led sono al max (6^2)*(6^2)=1296.

Ribasco:

I modi sono tanti ed io non so quante combinazioni vuoi. E come vuoi accendere i led, ossia a gruppi oppure singolarmente ecc...

ah già, son stato ingannato da

6 serie di numeri random da 8 bit che siano o "1" o "0" ?

comunque rimane il problema che non hai abbastanza ram.

ps. alla luce dei 6 bit, il bitshif può essere fatto di soli 6 bit alla volta, però usando valori da 0 a 8^3

Cmq rimane il fatto che non hai letto ciò che ho scritto per 2 volte, ossia che ho scritto chiaro e tondo che non sapendo cosa l'utente voglia fare, non possiamo dare indicazioni più precise :wink:

E qui si torna al fatto che siamo sempre a proporre soluzione ed a scannarci tra di noi e l'utente che chiede aiuto non specifica meglio le sue idee o ciò che vuole ottenere. :smiley:

Questo è il mio codice ..(nell'ultimo shiftout, il secondo, terzo , quesrto, quinto sesto e settimo bit corrispondono ai sei piani :wink: )

long randNumber;//Dichiaro i numeri random
long randNumber1;
long randNumber2;
long randNumber3;
long randNumber4;
long randNumber5;

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;
int tempo = 80;//tempo fra un bitshift e l'altro
void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
 randomSeed(analogRead(0));
}
void loop () {
  
  randNumber = random(0,255);
  randNumber1 = random(0,255);
  randNumber2 = random(0,222);
  randNumber3 = random(0,255);
  randNumber4 = random(0,255);
  randNumber5 = random(0,255);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber1);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber2);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber3);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber4);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber5);
  digitalWrite(latchPin, HIGH);
  delay(tempo);
  }

come faccio a creare un random per i piani che ne faccia accendere meno alla volta... ovvero che nel numero binario siano presenti più "0" che "1" ? c'è un modo per impostare delle "percentuali di probabilità " diciamo? ps, a qualcuno interessa qualche foto del cubo? anche se forse è uscito un pò storto...ma per un 16enne alla prime armi...beh non sembra male...

Salve, voglio fare solo una precisazione sulla funzione random(): è vero che genera un valore casuale ma in realtà ad ogni accensione la sequenza di numeri che genera saranno sempre gli stessi. Mi spiego meglio: supponi che la funzione ti genera 6, 230, 98, 249, 11 ecc ecc e fin qui va bene; questa sequenza però rimane invariata ad ogni riavvio della scheda quindi ogni volta che accenderai il circuito ti darà sempre la stessa sequenza di numeri 6, 230, 98, 249, 11 ecc ecc.
Se questo inconveniente ti può recare disturbo usa la libreria TrueRandom che elimina il problema. Ecco il link: Google Code Archive - Long-term storage for Google Code Project Hosting.
Ciao

@Pelletta: senza scomodare librerie esterne:

se resetti arduino noterai che la random crea sempre gli stessi valori. Per evitare ciò puoi inizializzare (una sola volta nel setup basta) un seme (http://arduino.cc/en/Reference/RandomSeed) con un numero casuale, che per esempio potrebbe essere una lettura analogica su un pin vuoto

come faccio a creare un random per i piani che ne faccia accendere meno alla volta... ovvero che nel numero binario siano presenti più "0" che "1" ? c'è un modo per impostare delle "percentuali di probabilità " diciamo?

ci sono vari metodi.
Il metodo brute force consiste nel creare numeri random come fai ora e scartare i risultati invalidi.
Un metodo invece "elegante" e il seguente: crei un'array con tanti 0 e 1 quanti ne vuoi, esempio 00001111. Poi, per diciamo una decina o più volte, crei un numero random da 0 alla grandezza dell'array-1 e scambi di posizione i valori.
questo è un metodo che usavo anche per "mischiare il mazzo di carte", ovviamente virtuali :slight_smile:

a qualcuno interessa qualche foto del cubo? anche se forse è uscito un pò storto

foto?? vogliamo il video!!!!!

Pelletta:
...
Se questo inconveniente ti può recare disturbo usa la libreria TrueRandom che elimina il problema. Ecco il link: Google Code Archive - Long-term storage for Google Code Project Hosting.
Ciao

Senza usare la libreria si puó avere un numero di partenza casuale leggendo il valore di un entrata analogica non collegata a niente e usare quello per randomSeed().
http://arduino.cc/en/Reference/RandomSeed
Ciao Uwe

lesto:
@Pelletta: senza scomodare librerie esterne:

se resetti arduino noterai che la random crea sempre gli stessi valori. Per evitare ciò puoi inizializzare (una sola volta nel setup basta) un seme (http://arduino.cc/en/Reference/RandomSeed) con un numero casuale, che per esempio potrebbe essere una lettura analogica su un pin vuoto

come faccio a creare un random per i piani che ne faccia accendere meno alla volta... ovvero che nel numero binario siano presenti più "0" che "1" ? c'è un modo per impostare delle "percentuali di probabilità " diciamo?

ci sono vari metodi.
Il metodo brute force consiste nel creare numeri random come fai ora e scartare i risultati invalidi.
Un metodo invece "elegante" e il seguente: crei un'array con tanti 0 e 1 quanti ne vuoi, esempio 00001111. Poi, per diciamo una decina o più volte, crei un numero random da 0 alla grandezza dell'array-1 e scambi di posizione i valori.
questo è un metodo che usavo anche per "mischiare il mazzo di carte", ovviamente virtuali :slight_smile:

a qualcuno interessa qualche foto del cubo? anche se forse è uscito un pò storto

foto?? vogliamo il video!!!!!

ho inserito come dicevi tu l'array, ma mi da degli errori... potreste controllarmi il codice modificato? ...cos'è che sbaglio? codice :

long randNumber;//Dichiaro i numeri random
long randNumber1;
long randNumber2;
long randNumber3;
long randNumber4;
long randNumber5;
int piani[10]{1,0,1,0,1,0,1,0,1,0};
int latchPin = 8;
int clockPin = 12;
int dataPin = 11;
int tempo = 80;//tempo fra un bitshift e l'altro
void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
 randomSeed(analogRead(0));
}
void loop () {
  
  randNumber = random(10,255);
  randNumber1 = random(10,255);
  randNumber2 = random(10,222);
  randNumber3 = random(10,255);
  randNumber4 = random(10,255);
  randNumber5 = random[9];
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber1);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber2);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber3);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber4);
  shiftOut(dataPin, clockPin, MSBFIRST,randNumber5);
  digitalWrite(latchPin, HIGH);
  delay(tempo);
  
}

e questo l'errore : cuboled:6: error: function definition does not declare parameters
cuboled.cpp: In function 'void loop()':
cuboled:24: error: invalid types '[int]' for array subscript

int piani[10] = {1,0,1,0,1,0,1,0,1,0};
:wink:

Ho modificato abncora il codice e aggiunto un potenziometro e un pulsante...eccovi il video...fatemi sapere...ps, lo aggiungo anche nel primo post :wink: Grazie a tutti per l'aiuto :slight_smile:

Avresti dovuto aggiungere un cavaletto alla lista del materiale usato.
Il movimento della videocamera é fastidioso. :wink: :wink: :wink:
Ciao Uwe