
In riferimento al precedente post: “Come ottenere più valori da una funzione in Arduino: variabili globali, riferimenti e struct – lezione 1/2” un utente mi ha scritto in privato per chiedermi chiarimenti in merito all’uso di randomSeed(), nello specifico di randomSeed(analogRead(A0)). La spiegazione che ho fornito è diventata alla fine qualcosa che posso riutilizzare con i miei studenti quindi ne ho realizzato un post sul sito in modo che possa essere letto da tutti.
Quando in uno sketch usate random(), state usando un generatore pseudo-casuale: i numeri “sembrano” casuali, ma in realtà seguono una sequenza deterministica. Se riavviate la scheda e non fate nulla, spesso la sequenza riparte uguale. Per evitare questo comportamento (molto evidente nei giochi, nelle simulazioni e nelle attività di laboratorio), Arduino mette a disposizione randomSeed(), che inizializza il punto di partenza della sequenza.
Sintetizzo cosa fa nel dettaglio randomSeed()
- random() genera numeri pseudo-casuali.
- randomSeed(seed) imposta il seme (seed), cioè il valore da cui parte la sequenza.
questo vuol dire che:
- Seed uguale > sequenza uguale.
- Seed diverso > sequenza diversa.
L’effetto di randomSeed(analogRead(A0)) utilizzato nella lezione precedente è duplice:
- legge un valore analogico da
A0conanalogRead(A0) usa quel valore come seme per randomSeed(...)
L’idea (consigliata anche nella documentazione Arduino) è: se A0 è scollegato, la lettura è influenzata dal “rumore” elettrico ambientale e tende a variare; quindi anche il seed cambia e, a ogni reset, random() produce una sequenza diversa.
Però attenzione, un pin “floating” non garantisce casualità perfetta; spesso fornisce poca entropia, ma per scopi didattici (giochi, simulazioni, esercizi) è in genere sufficiente. Ovviamente non è una tecnica adatta a sicurezza/criptografia.
Precisazione: differenze tra UNO R3 e UNO R4
- Arduino UNO R3: analogRead() è a 10 bit: valori 0–1023.
- Arduino UNO R4: per compatibilità, analogRead() parte di default a 10 bit (0–1023), ma l’UNO R4 supporta risoluzioni più alte (fino a 14 bit) tramite analogReadResolution().
Questa informazioni può essere utile anche per il seed: più risoluzione vuol dire più livelli possibili nella lettura analogica, quindi (potenzialmente) seed più variabile.
Di seguito alcune proposte di attività da svolgere a scuola o per esercitarsi.
Tutti gli esempi stampano su Serial Monitor. Usate 9600 baud e, quando richiesto, lasciate A0 scollegato.
Attività 01: serie che si ripete – (senza randomSeed)
Obiettivo: vedere che, senza inizializzazione, la sequenza tende a ripetersi dopo un reset
Consegna: fate partire lo sketch, annotate i primi 10 numeri, premete reset e confrontate.
/*
Prof. Maffucci Michele
14.02.26
Attività 01: serie che si ripete - (senza randomSeed)
*/
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("Primi 10 numeri pseudo-casuali (senza seed):");
for (int i = 0; i < 10; i++) {
Serial.println(random(0, 100));
}
Serial.println("--- Premi reset della scheda e confronta ---\n");
delay(3000);
}
Attività 02: Seed fisso = sequenza ripetibile (utile nei test)
Obiettivo: capire che un seed costante produce sempre la stessa sequenza (utile per il debug).
Consegna: verificare che a ogni reset i numeri restano identici.
/*
Prof. Maffucci Michele
14.02.26
Attività 02: capire che un seed costante produce sempre la stessa sequenza (utile per il debug)
*/
void setup() {
Serial.begin(9600);
randomSeed(12345); // seed fisso
}
void loop() {
Serial.println("Primi 10 numeri con seed fisso (12345):");
for (int i = 0; i < 10; i++) {
Serial.println(random(0, 100));
}
Serial.println("--- Premi reset: deve ripetersi uguale ---\n");
delay(3000);
}
Attività 03: Seed “rumoroso” con analogRead(A0) (A0 scollegato)
Obiettivo: ottenere sequenze diverse a ogni reset usando randomSeed(analogRead(A0)).
Consegna:
- eseguite con A0 scollegato > osservate seed e sequenza
- collega A0 a GND o 5V > osservate come seed e sequenza diventano più “stabili” (meno variabili)
/*
Prof. Maffucci Michele
14.02.26
Attività 03: ottenere sequenze diverse a ogni reset usando randomSeed(analogRead(A0))
*/
void setup() {
Serial.begin(9600);
// A0 deve essere scollegato per sfruttare la variabilità del rumore
int seme = analogRead(A0);
randomSeed(seme);
Serial.print("Seed letto da A0: ");
Serial.println(seme);
Serial.println();
}
void loop() {
Serial.println("Primi 10 numeri con seed da A0:");
for (int i = 0; i < 10; i++) {
Serial.println(random(0, 100));
}
Serial.println("--- Premi reset: dovrebbero cambiare ---\n");
delay(3000);
}
Attività 04: utilizzo di UNO R4 per avere seed più “ricco” aumentando la risoluzione (12/14 bit)
Obiettivo: su UNO R4 aumentare la risoluzione ADC e “mescolare” più letture per un seed più variabile.
Consegna:
- fate 5 reset su UNO R3 e 5 reset su UNO R4, annotate i seed e valutate quanto cambiano
- su UNO R4 provate anche analogReadResolution(12) e confronta con 14
Lo sketch che segue viene compilato anche su UNO R3: la parte analogReadResolution() viene attivata solo su UNO R4.
/*
Prof. Maffucci Michele
14.02.26
Attività 04: utilizzo di UNO R4 per avere seed più "ricco" aumentando la risoluzione (12/14 bit)
*/
unsigned long creaSeedDaRumoreA0() {
unsigned long seed = 0;
// Su UNO R4 puoi aumentare la risoluzione (10 bit default, fino a 14 bit)
#if defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
analogReadResolution(14);
#endif
// Mescolo 32 letture per raccogliere più variabilità
for (int i = 0; i < 32; i++) {
seed = (seed << 1) ^ (unsigned long)analogRead(A0);
delay(2);
}
return seed;
}
void setup() {
Serial.begin(9600);
Serial.println("Seed avanzato da A0 (A0 scollegato):");
unsigned long seed = creaSeedDaRumoreA0();
Serial.print("Seed calcolato: ");
Serial.println(seed);
randomSeed(seed);
Serial.println();
}
void loop() {
Serial.println("Primi 10 numeri con seed avanzato:");
for (int i = 0; i < 10; i++) {
Serial.println(random(0, 100));
}
Serial.println("--- Reset e confronta ---\n");
delay(3000);
}
Ora vi propongo un piccolo progetto, il classico dado, che sicuramente riuscirete a svolgere velocemente.
Esercizio: “dado elettronico”
Obiettivo: usare random() in un contesto concreto e verificare che con randomSeed i lanci non siano sempre uguali dopo reset.
Vi lascio qualche giorno per provare a sviluppare una soluzione e poi ve ne propongo una io. 🙂
Terminiamo questa lezione riassumendo quanto visto:
random()= pseudo-casuale (sequenza deterministica);randomSeed()sposta il punto di partenza della sequenza;randomSeed(analogRead(A0))funziona solo se A0 varia davvero (meglio scollegato o con una sorgente “rumorosa”);- UNO R4 può aumentare la risoluzione ADC con analogReadResolution() (default 10 bit per compatibilità).
Buon Coding a tutti 🙂




















