Go Down

### Topic: Help - Random function not working (Read 12181 times)previous topic - next topic

#### Patzak

##### Nov 20, 2008, 10:54 pm
Hi...Just received an Arduino Duemilanove...works fine with everything that I have tried with the exception of all the random functions.  The random calls all return one of two values when placed in a loop, I am just trying to randomly flash five LEDs.  Random(1,6) returns 2 or 4.  Loaded example from language reference and experienced a similar problem.  Any help will be appreciated.

Thank You,
Pat

#### RIDDICK

#1
##### Nov 20, 2008, 11:42 pmLast Edit: Nov 20, 2008, 11:43 pm by RIDDICK Reason: 1
Hi!

What if u use
random(0,5120)/1024+1
random(1,6)
?
This would use some upper bits of the random numbers... The lower bits r sometimes not really random... *giggle*

Do u call random() just once between two board-resets?

do u call
or so, too?

random() uses GNU CC's rand() function, which should deliver quite good pseudo-random numbers...

Bye
-Arne

#### mikalhart

#2
##### Nov 20, 2008, 11:53 pmLast Edit: Nov 20, 2008, 11:54 pm by mikalhart Reason: 1
There is a known bug with the current Arduino implementation of random(x) and random(x, y).  As a replacement, try the following:

Code: [Select]
`unsigned long newrandom(unsigned long howsmall, unsigned long howbig){  return howsmall + random() % (howbig - howsmall);}`

(This calls the stdlib implementation of random.)

Mikal

#### mikalhart

#3
##### Nov 21, 2008, 12:44 am
Patzak--

I think you must be seeing something different than me.  When I repeatedly call (the built in Arduino) random(1, 6), I get perfectly reasonable values:

2 1 1 4 1 2 1 5 3 2 4 4 1 2 2 2 5 4 3 1 2 2 1 3 1 2 4 1 5 2 1 5 1 2 2 3 4 3 5 4 2 5 4 3 1 1 5 1 4 2 3 1 5 4 5 1 1 5 1 3 4 2 2 5 4 2 3 5 1 5 4 3 5 5 3 3 5 5 3 5 5 2 5 4 4 2 5 3 1 2 2 1 2 5 2 2 3 4 4 3

This was generated with
Code: [Select]
`  for (int i=0; i<100; ++i)  {    Serial.print(random(1, 6));    Serial.print(" ");  }`

Mikal

#### Patzak

#4
##### Dec 08, 2008, 12:52 am
I purchased a windows Vista laptop today.  Loaded Arduino-0012  and ran the same random() code.  All results were acceptable.  There is a bug in Linux AMD_64  for all random functions.

#### mikalhart

#5
##### Dec 08, 2008, 01:24 am
That's distressing.  It's hard to see how that can be; isn't it the same compiler?  Does anyone else using AMD_64 Arduino experience that?

Mikal

#### Berg

#6
##### Dec 09, 2008, 10:32 pm
Doesn't work for me either.
Duemilanove, Arduino 0012 Alpha, Linux (Kubuntu 8.10) x86, Intel CPU).

Code: [Select]
`long randomred = random(127);long randomgreen = random(250);long randomblue = random(250);Serial.print(randomblue);Serial.print(" ");Serial.print(randomgreen);Serial.print(" ");Serial.println(randomblue);`
Produces

38 236 38
236 238 236
238 38 238
38 38 38
38 236 38
236 238 236
238 38 238
38 38 38
38 236 38

I get

38 236 38
236 238 236
238 38 238
38 38 38
38 236 38
236 238 236
238 38 238
38 38 38

Same results every time, no matter how many restarts/reboots/plugging things in on pin 0.

Using Mikalhart's suggestion:
Code: [Select]
`long randomred = newrandom(0,127);long randomgreen = newrandom(0,250);long randomblue = random(0,250);Serial.print(randomblue);Serial.print(" ");Serial.print(randomgreen);Serial.print(" ");Serial.println(randomblue);`
Produces

236 0 236
38 210 38
38 160 38
238 34 238
236 0 236
38 210 38
38 160 38
238 34 238
236 0 236
38 210 38

Is this a bug or am I missing something?

#### mikalhart

#7
##### Dec 12, 2008, 10:42 pm
Well, one minor observation is that you are printing randomblue twice and randomred not at all, but that doesn't explain the remarkably unrandom behavior.  Yipes!

Mikal

#### Berg

#8
##### Dec 14, 2008, 09:47 pm
Quote
Well, one minor observation is that you are printing randomblue twice and randomred not at all

Ooops.
Well, after rewriting the code a number of times, trying  to find what I was certain was an error on my behalf, I guess another error snuck in.

However, I am now more or less certain that there is a bug in the Linux version of Arduino: I ran the very same code on a Windows XP computer, and it gave me random numbers without the above repetitions.

#### mikalhart

#9
##### Dec 15, 2008, 07:28 am
Quote
However, I am now more or less certain that there is a bug in the Linux version of Arduino.

I unhappily agree.  Let's see if we can get to the bottom of this.  Would anyone who wants to participate, please run this short sketch:

void setup()
{
Serial.begin(9600);
for (int i=0; i<20; ++i)
{
long l = random();
Serial.print(l); Serial.print(" ");
Serial.print(l % 6); Serial.print(" ");
Serial.print(l % 127); Serial.print(" ");
Serial.pri lnt(l % 250); Serial.println();
}
}

void loop()
{}

If your results differ from those posted by anyone else, please note the platform and post them.  When I run this with Arduino 0012 from my Vista laptop, I get the following:

Code: [Select]
`16807 1 43 57282475249 1 71 2491622650073 5 29 73984943658 2 111 1581144108930 4 93 180470211272 2 122 22101027544 0 60 441457850878 2 98 1281458777923 5 43 1732007237709 1 42 209823564440 0 47 1901115438165 5 86 1651784484492 0 126 24274243042 2 112 42114807987 3 114 2371137522503 5 13 31441282327 1 94 7716531729 1 12 229823378840 4 121 90143542612 4 100 112`

I would expect the Linux users to report something quite different.

Mikal

#### Veronica

#10
##### Dec 16, 2008, 12:04 am
Hi,

Good thing I searched the forum before posting my first question I've got the same problem of repeating numbers.

Results from Ubuntu 8.10 x86_64 and arduino 0012

0 0 0 0
31031784 0 96 34
26852320 4 75 70
4242000 0 73 0
842292 0 28 42
453960 0 62 210
211932 0 96 182
84160 4 86 160
0 0 0 0
31031784 0 96 34
26852320 4 75 70
4242000 0 73 0
842292 0 28 42
453960 0 62 210
211932 0 96 182
84160 4 86 160
0 0 0 0
31031784 0 96 34
26852320 4 75 70
4242000 0 73 0

Ver.

#### mikalhart

#11
##### Dec 16, 2008, 05:12 am
Wow, that's really a stunning bug.  And the scary thing is, it's nothing (apparently) to do with Arduino, since my test sketch calls the stdlib implementation of random().

Thanks, Veronica.  Does anyone else get anything different?  Do all Linux implementations get the same results?

Mikal

#### halley

#12
##### Dec 16, 2008, 05:25 amLast Edit: Dec 16, 2008, 05:32 am by halley Reason: 1
I would not be surprised if it was simply an artifact of the 8 bit processing?  As much as I'm impressed that the cross compiler is able to do all sorts of amazing math accurately, I also know that PRNG routines are generally bit-fiddling exercises more than actual math.  Some unexpected endian-ness bug could easily blow the seed series.

I wonder if the Mersenne Twister (the current darling of PRNG science) is implementable instead of the stdlib variety.  I recall reading that it actually is less computationally intense than some, but may require more scratch memory.

OSX Arduino 0012, Duemilanove:

Code: [Select]
`16807 1 43 57282475249 1 71 2491622650073 5 29 73984943658 2 111 1581144108930 4 93 180470211272 2 122 22101027544 0 60 441457850878 2 98 1281458777923 5 43 1732007237709 1 42 209823564440 0 47 1901115438165 5 86 1651784484492 0 126 24274243042 2 112 42114807987 3 114 2371137522503 5 13 31441282327 1 94 7716531729 1 12 229823378840 4 121 90143542612 4 100 112`

Looks good here, I guess.  What is different between OSX backends and Ubuntu backends, for the avr-gcc cross-compiled stdlib?

#### mikalhart

#13
##### Dec 16, 2008, 05:49 amLast Edit: Dec 16, 2008, 06:07 am by mikalhart Reason: 1
@halley: What 8 bit processing are you talking about?  All the small modulus operations?  I just threw those in because people earlier in the thread were noticing unpleasant patterns with those.  They're superflous as it turns out, because the real unpleasant pattern is the series of raw numbers returned by the stdlib random() function itself (in Linux):

0(!), 31031784, 26852320, 4242000, 842292, 453960, 211932, 84160, 0(!!), 31031784, ...

It appears that there are only 8 "random" numbers before the series repeats!  Something is badly wrong.  Here is the source to avr-libc 1.6.2's random():

Code: [Select]
`static longdo_random(unsigned long *ctx){  /*   * Compute x = (7^5 * x) mod (2^31 - 1)   * wihout overflowing 31 bits:   *      (2^31 - 1) = 127773 * (7^5) + 2836   * From "Random number generators: good ones are hard to find",   * Park and Miller, Communications of the ACM, vol. 31, no. 10,   * October 1988, p. 1195.   */  long hi, lo, x;  x = *ctx;  /* Can't be initialized with 0, so use another value. */  if (x == 0)    x = 123459876L;  hi = x / 127773L;  lo = x % 127773L;  x = 16807L * lo - 2836L * hi;  if (x < 0)    x += 0x7fffffffL;  return ((*ctx = x) % ((unsigned long)RANDOM_MAX + 1));}longrandom_r(unsigned long *ctx){  return do_random(ctx);}static unsigned long next = 1;longrandom(void){  return do_random(&next);}voidsrandom(unsigned long seed){  next = seed;}`

As you can see, assuming you don't call srandom(), the first random number generated should be 16807, which it is in both yours and my sequences.  Why not Linux as well?

Mikal

EDIT: Is there anyone using 32-bit Linux experiencing this problem?

#### halley

#14
##### Dec 16, 2008, 06:37 amLast Edit: Dec 16, 2008, 06:37 am by halley Reason: 1
@mikalhart, I meant the 8bit architecture of the atmega-- some bug in the avr tools.  Maybe doing huge number modulus operations is not well-tested and the mini-routine for doing it has a bug in one particular release of the libs.  Maybe the use of a static long does not put the right value in PROM or RAM on startup.  I just looked at the elf disassembly for the code you showed, and it *looks* okay but I am not used to avr opcodes enough to spot bugs.

Go Up

Please enter a valid email to subscribe