Números Aleatoris a Arduino IDE

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.

Com funcionen internament

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

Seed (llavor) i la seva utilitat

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) );

Utilitats

Algorisme determinista i LCG

Tant random() d’Arduino com rand() de C fan servir un Generador Congruencial Lineal (LCG). La fórmula és:

\[ X_{n+1} \;=\; (a \cdot X_n + c) \bmod m \]

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.

Conclusió

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.

Exemple pràctic pas a pas (Arduino)

Pas 1: Sense 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() {}

Pas 2: Llavor aleatòria amb soroll analògic

void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(A0));  // llavor variable
  for (int i = 0; i < 5; i++) {
    Serial.println(random(0, 100));
  }
}
void loop() {}

Pas 3: Llavor fixa per reproduir seqüències

void setup() {
  Serial.begin(9600);
  randomSeed(1234);           // llavor fixa
  for (int i = 0; i < 5; i++) {
    Serial.println(random(0, 100));
  }
}
void loop() {}