randomSeed question

So, with the same randomSeed value the random numbers generated from boot will always be the same, right? Is there any way to restart the randomization to get the same set of random numbers again at any given time?

Yes, use the analog inputs.
Have you seen the example at the RandomSeed page.
https://www.arduino.cc/en/Reference/RandomSeed

I prefer to do a little more:

  int r = 0;
  for( int i=A0; i<=A7; i++)
    r += analogRead( i);
  randomSeed(r);

That code would ensure that the random sequence is different every boot, right? What I'm looking for is to recreate the random sequence from boot later in the code. So say the random numbers generated from boot are 50, 43, 200, 0, 7. I want to be able to hit a button and that same sequence will begin again until reset.

So, save the seed value and use it whenever you want to restart the sequence

Sorry :-[ I didn't read you question very well. If you start with a certain seed, you get the same sequence of random numbers. Every seed generates its own sequence.

Have you ever played the Windows game Freecell? That game has 'numbered games' which allow you to pick a specific arrangement of the cards by typing in a number. It actually uses the standard C random() function and the game number is the randomSeed.

So yes, once you've found a random arrangement you like, copy that random seed to use again next time.

Having fun what random and seeds and sequences of random numbers :

//
// http://forum.arduino.cc/index.php?topic=415654.0
//

void setup(){
  Serial.begin(9600);
  
  while(!Serial);   // For Lenoardo/Micro
  
  Serial.println(F( "Random with a few seeds"));
  
}

void loop()
{
  // Select a fixed seed, but the selection is really random.
  // Calling the random() and randomSeed() disturbs the previous sequence of random numbers.
  int r = 0;
  for( int i=A0; i<=A5; i++)
    r += analogRead( i);
  randomSeed(r);
  int selection = random( 4);
  int seed;

  switch( selection)
  {
    case 0:
      seed = 1;
      break;
    case 1:
      seed = 100;
      break;
    case 2:
      seed = 1234;
      break;
    case 3:
      seed = 5;
      break;
  }

  // Set the seed.
  randomSeed( seed);

  Serial.print(F( "seed="));
  Serial.print( seed);
  Serial.print(F( ":   "));
  
  // Print 5 random numbers for this seed.
  for( int i=0; i<5; i++)
  {
    // A random number between from 0 up to 999
    // Changing the minimum and maximum does not really change the internal random sequence.
    // But the numbers will be different of course.
    int r = random( 1000);     
    Serial.print( r);
    Serial.print(F( ", "));
  }
  Serial.println();
  
  delay(1000);
}

After testing with a really simple sketch it is actually doing what I want, always giving the same random sequence when randomseed is called beforehand. My current code uses multiple random values all over the place and calling randomseed isn't giving the same result probably because things are being randomized in a different order every time.

Probably. There is only one random calculation in the library.
In the file WMath.cpp, the Arduino uses the 'srandom' and 'random' from the avr-gcc stdlib library.

You can write your own random function, and use that for a fixed sequence for a certain seed.
Some Arduino users are experts in true random, but you want a simple sequence. I can't find something simple, only a long division is perhaps enough.

Yes if you use the same SEED, you get the same sequence. you can save a SEED once for all into the EEPROM and then read that at every start of your arduino for example to ensure you always get the same or hardcode it.

if you want different SEEDs with different arduinos, then you need a source of entropy - check this post

I like the idea of mixing an analogRead with timing if you have user interaction

srandom(random() ^ ((uint32_t) analogRead(0) << 22) ^ micros());

I think I have made an alternative random generator, to be used for a fixed sequence when the Arduino random function is already used all over the place.

// binRandom
// ---------
//
// The most basic and simple random generator.
// This one is not used a lot, because there are better random generators.
// This one should be in the bin, that's why it is called "binRandom".
//
// Taken from : http://www.avrfreaks.net/forum/random-number
// By avrfreaks.net user "peret".
// Assumed to be public domain.
//
// Tested with Arduino IDE 1.6.10 and Arduino Micro (ATmega32U4).

// A variable that is used to calculate the next random number.
static unsigned long binRandom_base;

void setup()
{
  Serial.begin( 9600);
  while(!Serial);   // Wait for serial monitor when using Leonardo or Micro.

  Serial.println("My first random generator");
}

void loop()
{
  int s = 100;                    // fill in the seed
  binSeed( s);
  Serial.print( "seed=");
  Serial.print( s);
  Serial.print( ":  ");

  for( int i=0; i<30; i++)
  {
    Serial.print( binRandom(10));   // a '10' generates numbers from 0 up to 9.
    Serial.print( ", ");
  }
  Serial.println();
  delay(1000);
}

void binSeed( unsigned int x)
{
  binRandom_base = (unsigned long) x;
}

// Get random number from 0 to max (but not inclusive max).
// This is in the same way as the arduino random function.
unsigned int binRandom( unsigned int max)
{
  // The numbers 2053 and 13849 generate a good sequence of semi-random.
  // Do not change the numbers.
  binRandom_base = 2053UL * binRandom_base + 13849UL;
  return( binRandom_base % max);
}

I did a few tests, and it seems to generate every number in the requested range, even after a very long sequence.

This is a sketch that calculate the uniform distribution of binRandom against the Arduino random. It turns out to be just as good.

// Calculate the uniform distribution of the generated numbers.
// Compare binRandom with Arduino random (Arduino uses the stdlib of avr-gcc).
//
// Tested with Arduino IDE 1.6.10 and Arduino Micro (ATmega32U4).

// A variable that is used to calculate the next random number.
static unsigned long binRandom_base;

// Count the occurance of the numbers for Arduino random [0][] and binRandom [1][].
unsigned int counts[2][20];

void setup() 
{
  Serial.begin( 9600);
  while(!Serial);   // Wait for serial monitor when using Leonardo or Micro.

  Serial.println( "Test of the uniform distribution of Arduino random and binRandom");
  Serial.println( "The occurance of each number between 0 and 20 will be calculated");
  Serial.println( "Running, please wait...");

  
  // Start with a seed.
  // Comment both out, to use the default.
  randomSeed( 123);            // Arduino seed
  binSeed( 123);               // seed for own functions.
}

void loop() 
{
  unsigned int a, b;

  // Clear the counts array.
  for( int i=0; i<2; i++)
    for( int j=0; j<20; j++)
       counts[i][j] = 0;

  while( true)
  {
    a = random( 20);             // Arduino random
    counts[0][a]++;              // increment the occurance of this number.

    b = binRandom( 20);          // own functions
    counts[1][b]++;              // increment the occurance of this number.

    if( counts[0][a] > 6000U || counts[1][b] > 6000U)
      break;
  }
  
  Serial.println();

  Serial.print( "\"binRandom_base\"=");
  Serial.println( binRandom_base);

  Serial.println("Number occurance of Arduino random for numbers 0...19:");
  for( int i=0; i<20; i++)
  {
    Serial.print( counts[0][i]);
    Serial.print( ",");
  }
  Serial.println();

  Serial.println("Number occurance of binRandom for numbers 0...19:");
  for( int i=0; i<20; i++)
  {
    Serial.print( counts[1][i]);
    Serial.print( ",");
  }
  Serial.println();

  // Start the loop and run again.
  // This will continue the sequence.
  // It will show if after a long sequence there is a change in the occurance of some numbers.
}


void binSeed( unsigned int x)
{
  binRandom_base = (unsigned long) x;
}

// Get random number from 0 to max (but not inclusive max).
// This is in the same way as the arduino random function.
unsigned int binRandom( unsigned int max)
{
  // The numbers 2053 and 13849 generate a good sequence of semi-random.
  // Do not change the numbers.
  binRandom_base = 2053UL * binRandom_base + 13849UL;
  return( binRandom_base % max);
}

Reseeding the RNG during sketch run is NOT possible. Only the first randomSeed() call do something.

MWE:

void setup() {
  Serial.begin(115200);
}

void loop() {
  randomSeed(0);
  Serial.println(random());
  delay(1000);
}

This generates random numbers despite it should generate the same number. The sequence start again after restart but this is not what the OP asked for.

I wanted to test a flash memory chip by writing a random number to each location, reseed the RNG and check if the numbers are same. They were not because the randomSeed works only once!

EDIT:
OMG, looking into randomSeed function there is:

void randomSeed(unsigned long seed)
{
  if (seed != 0) {
    srandom(seed);
  }
}

I have no idea why 0 is not allowed but there should be a warning IMHO. References say unsigned long is OK. 0 is unsigned long and if some arbitrary number is to be chosen I think it is 0 quite often.

You can make your own pseudorandom generator. Seeding is done by just initializing the feedback shift register:

//  pseudorandom shift register

unsigned long shiftRegister = 0xDEADBEEF;
unsigned long tempXor;

unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 100;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    // get exclusive or feedback from tap 28 and 31, i.e. bit 27 and 30

    tempXor = (shiftRegister & ((unsigned long)1 << 30)) ^ ((shiftRegister << 3) & ((unsigned long)1 << 30));

    shiftRegister = shiftRegister << 1;
    if (tempXor != 0)
    {
      shiftRegister |= 1;
    }

    // set the LED with the ledState of the variable:
    if (shiftRegister & 1)
    {
      digitalWrite(LED_BUILTIN, 1);
    }
    else
    {
      digitalWrite(LED_BUILTIN, 0);
    }

  }
}  // end loop

This will guarantee the same sequence on different architectures.