Int rndSeed = (analogRead(A0) * analogRead(A0));

Hey everyone,
I don't need true randomness, but I was hoping to inject a little more entropy by multiplying a few consecutive readings.

Is my syntax wrong, or is it that I have placed this above the void setup(); section?

int rndSeed = (analogRead(A0) * analogRead(A0) * analogRead(A0) * analogRead(A0) * analogRead(A0)); //Unconnected analog pin used to collect noise

randomSeed(rndSeed);

Probably. I suggest put it in setup()

1 Like

Thanks @bobcousins, doesn't that mean the value will no longer be global, though?

Ahh hang on, but I guess it doesn't matter if it's global or not, because the randonSeed has already been set, and I suppose this has to be global by design, right?

That's right once you call randomSeed() rndSeed is no longer referenced.

1 Like

Amazing, thank you, Bob. :pray:

Incidentally, I condensed it to a single line:

randomSeed(analogRead(A0) * analogRead(A0) * analogRead(A0) * analogRead(A0) * analogRead(A0)); //Unconnected analog pin used to collect noise

If you are using analogRead() you can use the noise of the last bit(s) to seed

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  Serial.println(__FILE__);

  uint32_t zd = 0;
  for (int i = 0; i < 32; i++) 
  {
    zd <<= 1;
    zd ^= analogRead(A0);  //  or only last (noise) bit use    zd |= analogRead(A0); 
  }
  randomSeed(zd);
  Serial.println(zd, HEX);
}

void loop()
{
}

Warning: know that analogRead() is not a great source of entropy.

1 Like

If just one reading is 0, the result will compute as zero.

If you want to inject some analogRead(A0) entropy into the system, use addition:

for(ii = 5; ii; --i){
     randomSeed(random()+analogRead(A0));
}

Or try multiple analog ports

for(ii = 5; ii; --i){
     randomSeed(random()+analogRead(ii%5));
}

If you have any externally-forced events you can inject some entropy from them:

     randomSeed(random()+micros());
1 Like

A small correction...
Warning: know that analogRead() can be a terrible source of entropy and successive analog readings of a floating pin tend to drift the value towards zero generally making that useless.

1 Like

Hey everyone,
Thanks for your replies. I really appreciate you sharing your knowledge and experience.

I won't be using this random number for anything critical like cryptography, etc, it's just to select 1 of 5 outputs 'randomly'.

(Further coding fun is that not all 5 output will be used at all times, so might be 1-2-5, 2-3-4-5, etc. But I'm really enjoying the puzzle of working this stuff out. :slight_smile: Arduinos are awesome. :slight_smile: )
(I figure I'll check if the random number is one of the active channels and if not, generate a new random number.)

Ahh. :man_facepalming: Excellent point and so obvious!

Then why do you care about seeding?

Because I read in the Arduino docs that without a seed, it will produce the same random number on subsequent executions. I would like to avoid that.

Not true.

Without seeding, the extremely long series produced by random() starts in the same place on each power up, which is desirable for debugging.

The simplest reliable approach to seeding is to wait for a user to push a button, and use the elapsed milliseconds or microseconds as the seed.

1 Like

To be pedantic: use the elapsed time since bootup, rather than the elapsed time of the button press action.

// Button Entropy Injection for random() and randomSeed()
//https://wokwi.com/projects/421713344617482241
// for https://forum.arduino.cc/t/int-rndseed-analogread-a0-analogread-a0/1349109

const int ButtonPin = 2;

void pauseForButtonEntropy(const int ButtonPin) {
  Serial.println("Press button to start");
  while (digitalRead(ButtonPin) == HIGH) { // wait for button press
    ; //do nothing
  }
  while (digitalRead(ButtonPin) == LOW) { // protect  against button initially being pressed
    ; //do nothing
  }
  randomSeed(micros() + random()); // inject entropy, rather than overwrite entropy -- good for repeated use
}

void setup() {
  Serial.begin(115200);
  pinMode(ButtonPin, INPUT_PULLUP);
}

void loop() {
  pauseForButtonEntropy(ButtonPin);
  Serial.println(random());
  //delay(500); // simple rate-limiting -- need some sort of debouncing for noisy buttons
}

Bear in mind values outside of the 1 - 0x7FFFFFF range are degenerate. Applying a mask before calling randomSeed eliminates the trouble. Zero is best handled by retrying.

Thanks again, everyone!
I have got it to a state where I'm happy with the level of entropy versus complexity.

All the best!
Dax.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.