If you do an analogRead() on A0 do you get a steady value or does it vary ? Have you got anything connected to A0 ?
With a floating A0 I get 0 more than 6 times in a row with the original code.
Hi,
Nothing connected to A0. analogRead varies a littlevalues clustered around 314, tending to become more stable over time.
Michael
Whandall, thanks for your tip. I'll remember that one.
Michael
A different working solution (with minimal changes to the original)
#define SEED_PIN A0
const byte QUANT_CHOICE = 7;
byte choice;
void setup() {
Serial.begin(57600);
randomSeed(((long)analogRead(SEED_PIN))<<16);
choice = random(QUANT_CHOICE);
}
void loop() {
Serial.println(choice);
delay(500);
}
Came up with a workaround myself:
#define SEED_PIN A0
const byte QUANT_CHOICE = 7;
byte choice;
void setup() {
Serial.begin(57600);
randomSeed(analogRead(SEED_PIN));
choice = random(1, QUANT_CHOICE);
choice;
}
void loop() {
Serial.println(choice);
delay(500);
}
I still would like to understand, though. This doesn't appear to be how the function is supposed to work.
Michael
Oops, meant to write choice = random(1, QUANT_CHOICE + 1);
Michael
PS. Huh. Looked like it was working for a while, but now returned 0 on more than 20 trials in a row.
I think for the special value 7 (which is used by a %) there should be more noise in the upper part of the long that steps through the sequence.
Some more data to add to what you say.
Works: choice = random(1, 7); choice; Works: choice = random(6);
Returns 0: choice = random(1, 8); choice; Returns 0: choice = random(7);
Michael
That emoticon is supposed to be a numeral 8. Michael
Whandall,
Your suggestion at #9 always returns 254 for me.
Michael
edit: Sorry, had a leftover line in my test code. It always returns 0. Your earlier suggestion does appear to return random values.
Returns 0: choice = random(1, 8); choice;
Returns 0: choice = random(7);
both variants end in the same % 7 operation.
long random(long howbig)
{
if (howbig == 0) {
return 0;
}
return random() % howbig;
}
long random(long howsmall, long howbig)
{
if (howsmall >= howbig) {
return howsmall;
}
long diff = howbig  howsmall;
return random(diff) + howsmall;
}
#define SEED_PIN A0
const byte QUANT_CHOICE = 7;
byte choice;
void setup() {
Serial.begin(57600);
}
void loop() {
long anaVal = analogRead(SEED_PIN);
randomSeed(anaVal<<16);
long lRandom = random();
Serial.print(F("A0 0x"));
Serial.print(anaVal, HEX);
Serial.print(F(" seeded<<16 Random 0x"));
Serial.print(lRandom, HEX);
Serial.print(F(" > "));
choice = lRandom % (long) QUANT_CHOICE;
Serial.println(choice);
delay(500);
}
A0 0x158 seeded<<16 Random 0x386800B0 > 6
A0 0x141 seeded<<16 Random 0x526700A4 > 4
A0 0x12F seeded<<16 Random 0x34A9009B > 6
A0 0x120 seeded<<16 Random 0x5BE00093 > 0
A0 0x115 seeded<<16 Random 0x9B3008E > 5
A0 0x10A seeded<<16 Random 0x37860088 > 4
A0 0x102 seeded<<16 Random 0x2A4E0084 > 1
A0 0xFB seeded<<16 Random 0x5EBD0080 > 5
A0 0xF6 seeded<<16 Random 0x167A007E > 0
A0 0xF0 seeded<<16 Random 0xC90007B > 3
A0 0xEC seeded<<16 Random 0x5F40079 > 5
A0 0xEA seeded<<16 Random 0x2A60078 > 6
A0 0xE7 seeded<<16 Random 0x3DB10076 > 1
A0 0xE5 seeded<<16 Random 0x3A630075 > 2
A0 0xE3 seeded<<16 Random 0x37150074 > 3
A0 0xE1 seeded<<16 Random 0x33C70073 > 4
A0 0xE2 seeded<<16 Random 0x756E0073 > 4
A0 0xE0 seeded<<16 Random 0x72200072 > 5
A0 0xDF seeded<<16 Random 0x30790072 > 5
A0 0xE1 seeded<<16 Random 0x33C70073 > 4
A0 0xE0 seeded<<16 Random 0x72200072 > 5
A0 0xE0 seeded<<16 Random 0x72200072 > 5
I only partially understand. I'm going to have to put some work into digesting this. Let me ask an elementary question:
After calling randomSeed, you call random() without any arguments ("long lRandom = random();). How does that work? Does it assume that its max value is the maximum value of a long?
Thanks for your help understanding this.
Michael
edit: there's the damn emoticon again. " long lRandom = random() ; "
Look at the second part of #16, there is the code of the random functions with parameters.
I did not locate the source code of srandom(long) and random() yet.
There are three problems at play…

In general, using analogRead to initialize the random number generator is a bad idea…
http://forum.arduino.cc/index.php?topic=66206.msg630884#msg630884This is a better choice…
http://forum.arduino.cc/index.php?topic=66206.msg537783#msg537783In your case using analogRead is disastrous because of #3 below.

Using modulus to reduce a Lehmer random number generator is a bad idea. But, the alternatives are annoying so a modulus is usually what is used. If you keep the mostsignificantbits as the mostsignificantbits instead of using modulus your problem will very likely disappear. However, if you insist on continuing to use analogRead a good hash function will work far better for what you are doing than a random number generator.

Low seed values with some prime number divisors are poison with the ParkMiller generator. I’m too lazy to find the thread but there is a detailed discussion on this forum. Given your experience seven is very likely one of those prime number divisors.
Thanks. I've bookmarked those threads and will read through them when I get a chance. This isn't a missioncritical issue for me, just something I stumbled across while I was trying out various things in some test code.
Add one more item to the long (long) list of things to learn about. ;)
Michael
Whandall: I did not locate the source code of srandom(long) and random() yet.
https://github.com/vancegroupmirrors/avrlibc/blob/master/avrlibc/libc/stdlib/random.c
@mjward, you are welcome.
(reseedRandom updated with the new value. The remainder of this post is now trivia.)
Bear in mind you will need to use a much larger prime (the constant named HappyPrime in reseedRandom) It does not have to be a Happy Prime; just a prime number. Ideally you should use something slightly more than the "dead zone". I vaguely recall it being about 1.5 million. It's easy enough to write a little sketch to determine where it ends. The dead zone ends at 127,774...
void setup()
{
uint32_t seed;
uint8_t choice;
Serial.begin( 250000 );
seed = 0;
do
{
++seed;
randomSeed( seed );
choice = random( 7 );
if ( (seed & 0x0000FFFF) == 0 )
{
Serial.write( '.' );
}
}
while ( choice == 0 );
Serial.println();
Serial.print( seed );
Serial.print( F( " > ") );
Serial.print( choice );
Serial.println();
}
void loop()
{
}
If we stick with Happy Primes the nearest value greater than 127,774 is #1859 = 127807.