Generando números aleatorios en Arduino

Arduino tiene una función random que genera números pseudoaleatorios, pero si queremos generar números aleatorios de verdad hemos de recurrir a algún tipo de generador físico ya que programando nunca podremos conseguir números realmente aleatorios.

analogRead

Generalmente cuando buscas una manera de generar números aleatorios con arduino te aconsejan recurrir a leer el valor puerto analógico que no este conectado a nada El problema es que realmente los valores obtenidos no son aleatorios. Suelen oscilar en torno a un valor sin alejarse demasiado de él. Es decir si el valor es el 150 es más probable que el siguiente número sea el 151 o el 149 que el 3 (en mis pruebas nunca he visto un  salto tan grande de valor). Cómo generador de números aleatorios no solo no es ninguna maravilla, es que es peor que el generador de números pseudoaleatorios.

Cómo solución se suele proponer usar el valor leído como semilla para la función random, lo malo de esto es que acaban siendo otra vez números pseudoaleatorios.

Hay montajes electrónicos que producen valores aleatorios a partir del ruido que sufren los componentes electrónicos, pero suelen ser complicados. Además ya no sería con un arduino y tengo que justificar que el articulo este en la sección de “arduino”.

Volviendo a nuestra idea de leer valores del puerto analógico vemos que el problema es que los números que devuelven oscilan entorno a un valor así que no podemos usar ese número como aleatorio, pero si una parte pequeña de él. El bit de menor peso. Vamos a tomar solo este bit y con ocho de ellos componer un byte. Ese byte debería ser aleatorio.


byte randomAnalog(int analogInput){
  byte rnd = 0;
  for(int i = 0; i < 8; i++){
    int aux = analogRead(analogInput)%2 << i; rnd += aux;
    delay(10);
  }
  return rnd;
}

Para aumentar el ruido se puede conectar un cable suelto en el  puerto que se va a leer, contra más largo y retorcido esté mejor, Por raro que suene si se mueve el cable o el arduino los números leídos del puerto analógico aun varían más.

Combinar varias fuentes

Si te fías poco puedes usar dos fuentes de aleatoriedad obteniendo bytes de dos puertos analógicos distintos y luego combinándolos con un xor.


byte r0 = randomAnalog(A0);
byte r1 = randomAnalog(A1);

byte r = r1 ^ r0;

Puede encontrar el código en el repositorio de github de ArduTips.

Un posible mejora es asegurarse de que el generar de números aleatorio es justo, es decir produce 0 o 1 con un 50% de probabilidades. Se puede leer aquí.

Un comentario en “Generando números aleatorios en Arduino

  1. Pingback: Generador justo de números aleatorios en arduino | Construyendo a Chispas

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.