Els números aleatoris en Arduino no són realment “aleatoris”, sinó pseudoaleatoris. Això vol dir que es generen mitjançant un algorisme determinista i, si es parteix del mateix estat inicial (seed), sempre generaran la mateixa seqüència.
Arduino utilitza la funció random()
per generar números pseudoaleatoris.
Aquesta crida es basa en un LCG (veure secció següent), molt similar a la funció rand()
de C.
Abans de generar valors, és recomanable inicialitzar la llavor amb randomSeed()
:
randomSeed(seed); // inicialitza la llavor
long val = random(0, 100); // retorna un valor entre 0 i 99
La funció randomSeed(seed)
estableix el valor inicial X₀
.
Sense aquesta crida, Arduino utilitza una llavor per defecte (normalment 1), i la seqüència serà sempre la mateixa.
Una tècnica comuna per generar una llavor menys previsible és usar el soroll analògic d’un pin sense connexió:
randomSeed( analogRead(A0) );
Tant random()
d’Arduino com rand()
de C fan servir un Generador
Congruencial Lineal (LCG). La fórmula és:
On:
Exemple típic de constants en C:
Aquesta seqüència de valors entre 0 i \(m-1\) és previsible si es coneix la llavor inicial — per això és pseudoaleatòria.
Els nombres aleatoris d’Arduino són pseudoaleatoris i útils per a aplicacions generals,
però no per a seguretat crítica. L’ús de randomSeed()
basat en soroll pot fer la seqüència
menys previsible, però sempre serà determinista si es coneix la llavor.
randomSeed()
Seqüència fixa cada reinici:
void setup() {
Serial.begin(9600);
// No randomSeed(): llavor per defecte
for (int i = 0; i < 5; i++) {
Serial.println(random(0, 100));
}
}
void loop() {}
void setup() {
Serial.begin(9600);
randomSeed(analogRead(A0)); // llavor variable
for (int i = 0; i < 5; i++) {
Serial.println(random(0, 100));
}
}
void loop() {}
void setup() {
Serial.begin(9600);
randomSeed(1234); // llavor fixa
for (int i = 0; i < 5; i++) {
Serial.println(random(0, 100));
}
}
void loop() {}