random() always returns the same number

Hello,
I want Arduino to choose randomly between 1 and 5. Simple task - irritating problems.

// integers are here to make the program easier to modify in the future
int filesAmount = 5;
int randomNum = 0;
randomNum = random(1, filesAmount + 1);

I expect that the number will be different every time I start Arduino (so the code above runs only once). Wherever I place this code - in void(setup) or void(loop) stopped with "while(1){}" - random() always returns 3. I remember using it the same exact way a few weeks ago and it worked flawlessly, now it's the "it worked but it stopped working for whatever reason" situation with Arduino programs once again. Tried using randomSeed() but it doesn't help much, it only makes another number being chosen every time Arduino starts - I'd need yet another source of random integers to make this function effective...
Any suggestions? My board is Arduino Uno and I'm using Windows 8.1. IDE is updated to the newest version.

Thanks a lot for advance.

I expect that the number will be different every time I start Arduino

Why?

AWOL:
Why?

To make a random file play when the board starts.

int filesAmount = 5;
int randomNum = 0;
randomNum = random(1, filesAmount + 1);
char chosenFile[10];
sprintf(chosenFile, "%d.AFS", randomNum);
SdPlay.setFile(chosenFile);
SdPlay.play();

No, why do you "expect" that it will be different?
It's a pseudo-random number generator.

What is wrong with randomSeed? I don't understand your comment about it. As AWOL points out, it is a pseudo-random number generator. If you want better "randomness" you'll have to use a better generator.
Did you try something like this?

  randomSeed(analogRead(A0));

Pete

1 Like

You need to initialize your random number generator with a random seed - not just the same old seed every time. Same random seed = same stream of pseudo-random numbers.

Maybe you could use analogRead() on a floating pin, and use that as the seed?

Edit: bah, beaten.

AWOL:
No, why do you "expect" that it will be different?
It's a pseudo-random number generator.

Well, it's supposed to be "random" so that's why I expected that :stuck_out_tongue:
If it's "pseudo-random" then it kind of explains it. Though I'm wondering why wouldn't Arduino randomize the seed itself?

el_supremo:
You need to seed the random number generator. Add this statement to your setup() function:

  randomSeed(analogRead(A0));

This is still not a great way to seed the generator but it is (usually) better than nothing.

Pete

I will try it, thank you.

EDIT: It did the trick, thanks again. Meanwhile could you tell me about a better ways to generate random numbers (or for another sources of random integers for use in randomSeed())?

Arduino doesn't randomize the seed because true randomness is hard to achieve.
Analog read on a floating pin is fine if you don't start analyzing the results. If you do, patterns will emerge. Like I said, random is hard.

Alternative way is to use user input. Take a millis reading of the moment a user pushes the first button and use that as seed.

Sometimes you want the same sequence of numbers every time - it helps when debugging.

You could keep the last used random value as a seed in EEPROM. That's a last resort, if you have no user input. There's also a temperature sensor in the chip, you could check into that as a possible source for a seed. The problem with using built in analog values that don't change very much, is that although the subsequent random numbers in the sequence are "spread" numerically, they will tend to keep reoccurring at a higher frequency than statistically expected for randomness (it will be a cluster of values).

Except he is only going 1 - 6, so that will not work very well.

aarg:
You could keep the last used random value as a seed in EEPROM.

Yup. Works well...
http://forum.arduino.cc/index.php?topic=66206.msg537783#msg537783

Shpaget:
Analog read on a floating pin is fine if you don't start analyzing the results.

Somewhere between "fine" and terrible.

Worth reading...
http://forum.arduino.cc/index.php?topic=66206.msg630884#msg630884

KeithRB:
Except he is only going 1 - 6, so that will not work very well.

Most random functions work with a large number and then truncate it to the user's range, or provide a large number and expect the user to perform the truncation themselves. On some systems, it's a float value between 0.0 and 0.99999999...

The truncation for 1-6 would be
(pseudocode) integer(random()*6)+1

You don't save the result as a seed, you save the float value in this example.