I have a funny problem.
I tryed to generate random numbers from 0 to 7, but somehow the series always starts with a 0,then random numbers. This happens everytime I reset, although I use randomSeed on analogRead(0). It's really strange, because if I try to generate numbers from 0 to any other number, it works. For sure it's not the code, because it couldn't be simpler. I use arduino 1.8.2. I did restart IDE and computer, tried different usb ports, nothing helped.
Why is 7 so special, is this only happening to me?
Any thoughts on this?
If it's so simple, post it. From your subject title I understand that you never get the number 7; correct? Else please give a better description of the problem.
Are you sure analogRead(0) is random? I doubt it.
int number;
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
}
void loop() {
number=random(7);
Serial.println(number);
delay(300);
}
It does generate numbers from 0 to 6, thats what i want. But it always starts with a zero if i reset. Always. And if I change 7 to any other number, then it works as it should, randomly. I don't get it.
I know this is pseudo random generator, but it should start with different numbers most of the time I do reset.
pilijanc:
...but it should start with different numbers most of the time I do reset.
Congratulations. You have proven, like many before you, that seeding from a floating pin, in the best case, does not work work well and, in the worst case, does not work at all.
One way to improve
Thanks.
So I just have to replace randomSeed in the setup with reseedRandom, insert the function and eeprom library, everything in the loop can stay the same?
It could also be that odd numbers are better than even numbers. It might be better to do this:
http://c-faq.com/lib/randrange.html
(It is probably a good idea to print your seed, too.)
pilijanc:
So I just have to replace randomSeed in the setup with reseedRandom, insert the function and eeprom library, everything in the loop can stay the same?
This is the latest version...
https://forum.arduino.cc/index.php?topic=66206.msg537783#msg537783
The stuff commented-out is optional; you can exclude it.
#3 in this post is especially germane...
http://forum.arduino.cc/index.php?topic=396191.msg2726782#msg2726782
An alternative...
It looks like #3 is the case, interesting. I did print my seed and when reseting, I got values above 400, not the same numbers, but probably too close for the random function to distinguish between values...
I will look into all of the stuff, thank you very much!!
I can't find the source code for the RNG but there's obviously something strange going on with random(7).
The first call to random(7) will result in zero for every value of seed up to and including 1277743. Because of this, if you use analogRead(A0) to seed the RNG, random(7) will always start with zero because analogRead can only return numbers from 0 to 1023.
I've just run another test and 1277744 seems to be a magic number. When the seed is 1277744, random(7) returns 6 and so does every seed from 1277744 up to 1277744*2-1. After that it returns 5 for the next 1277744 seeds, then it returns 4 and I presume that the pattern persists with higher values of seed.
Looks like you'll need a different RNG if you want to use random(7)
Pete.
Haaaa, that was really insightfull, I'm really glad someone comfirmed this, I'm not delusional!!
el_supremo:
I can't find the source code for the RNG...
It's Park-Miller Minimal Standard. If you really want a link let me know. I'll hunt it down.
...but there's obviously something strange going on with random(7). When the seed is 1277744, random(7) returns 6 and so does every seed from 1277744 up to 1277744*2-1. After that it returns 5 for the next 1277744 seeds, then it returns 4 and I presume that the pattern persists with higher values of seed.
That's not how random is used.
But, you are correct about low seeds and prime numbers. As mentioned in my linked post some prime numbers with low seeds are poison. Which is why I changed the Happy Prime from 937 to 127807.
In any case, modulus and Lehmer random number generators are a bad idea. The link @KeithRB provided has some solutions.
That's not how random is used.
I realize that. I am just confirming/explaining @pilijanc's observation that "somehow the series always starts with a 0" with this specific RNG.
Pete
So a trick, I suppose, would be to use the low bits of a floating analog pin.
void setup() {
unsigned long seed = 0;
for(int i = 0; i<32;i++) {
seed ^= ((unsigned long)analogRead(A0)) << i;
delay(1);
}
randomSeed(seed);
}
As everyone has noted - it must be a floating pin.
I believe Mr. Kristinsson provided experimental evidence that sampling the least-significant-bit also did not work particularly well. I recall high correlation being the problem (if the previous bit was zero there is a high probability the next bit will be zero).
Hi,
Quick fix.
int number;
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
for (int i=0; i< analogRead(0); i=i+1)
{
number=random(7);
}
}
void loop() {
number=random(7);
Serial.println(number);
delay(300);
}
Just run the randon functiuon in setup without printing, for your seed value iterations, then start sampling in the loop.
Just a quick thought..
Tom...
That's what I thought too, but that method could easily discard zero values and it could do it repeatably.
A Teensy or some other Arduinos does have a true random. If you really need randomness, then that might be a good choice. However there's few applications outside of government-level cryptography which need this.
My preferred method to get an approximation of random is to use some kind of user input. The millis() value when the first button is pushed is pretty good as a seed or a discard count.
As everyone has noted - it must be a floating pin.
Electrical pedantry here (and I'm honestly not sure of what the real answer is, just "throwing this out there"). In my experience of other chips (mostly '74 series) floating i.e. physically unconnected pins can sometimes take up a single (albeit unpredictable) value. That is they don't "flap around" randomly and the circuit topology may cause the same value to be picked up every time the circuit is powered on thus being just as "poisonous" as any other method?
Can someone correct me or clarify?
Tom's quick fix works for me just well, it's simple and it does it job.
Thank you!