Help - Random function not working

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

Hi!

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

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

do u call
randomSeed(analogRead(0));
or so, too?

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

Bye

There is a known bug with the current Arduino implementation of random(x) and random(x, y). As a replacement, try the following:

unsigned long newrandom(unsigned long howsmall, unsigned long howbig)
{
  return howsmall + random() % (howbig - howsmall);
}

(This calls the stdlib implementation of random.)

Mikal

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

  for (int i=0; i<100; ++i)
  {
    Serial.print(random(1, 6));
    Serial.print(" ");
  }

Mikal

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.

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

Doesn’t work for me either.
Duemilanove, Arduino 0012 Alpha, Linux (Kubuntu 8.10) x86, Intel CPU).

Default random w/o randomSeed(analogRead(0));

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

With randomSeed(analogRead(0));
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:

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?

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

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.

Where would I file a bug report about this?

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:

16807 1 43 57
282475249 1 71 249
1622650073 5 29 73
984943658 2 111 158
1144108930 4 93 180
470211272 2 122 22
101027544 0 60 44
1457850878 2 98 128
1458777923 5 43 173
2007237709 1 42 209
823564440 0 47 190
1115438165 5 86 165
1784484492 0 126 242
74243042 2 112 42
114807987 3 114 237
1137522503 5 13 3
1441282327 1 94 77
16531729 1 12 229
823378840 4 121 90
143542612 4 100 112

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

Mikal

Hi,

Good thing I searched the forum before posting my first question :slight_smile: 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.

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

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:

16807 1 43 57
282475249 1 71 249
1622650073 5 29 73
984943658 2 111 158
1144108930 4 93 180
470211272 2 122 22
101027544 0 60 44
1457850878 2 98 128
1458777923 5 43 173
2007237709 1 42 209
823564440 0 47 190
1115438165 5 86 165
1784484492 0 126 242
74243042 2 112 42
114807987 3 114 237
1137522503 5 13 3
1441282327 1 94 77
16531729 1 12 229
823378840 4 121 90
143542612 4 100 112

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

@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():

static long
do_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));
}

long
random_r(unsigned long *ctx)
{
  return do_random(ctx);
}

static unsigned long next = 1;

long
random(void)
{
  return do_random(&next);
}

void
srandom(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?

@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.

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

I believe I am (I’ve tried so many different versions on different computers lately, I can’t remember which one I used last).

uname - a gives me
Linux ratatosk 2.6.27-9-generic #1 SMP Thu Nov 20 21:57:00 UTC 2008 i686 GNU/Linux

@mikalhart: my results are the same as yours, running SUSE 11.0 x86_64…

Linux polaris 2.6.25.18-0.2-default #1 SMP 2008-10-21 16:30:26 +0200 x86_64  GNU/Linux

Using arduino-0012 on a Duemilanove.

Hi,

I’m not really familiar with how the arduino environment generates it’s random numbers. However, if it’s using openssl then there is a bug in Debian (and its derivatives e.g. Ubuntu) that may be the cause.

https://docs.astro.columbia.edu/ticket/793
http://www.us-cert.gov/cas/techalerts/TA08-137A.html

and for Ubuntu:

The latter gives the version numbers of fixed packages for openssl by distro version (e.g. Hardy). It also mentions that Intrepid (8.10) had this bug while it was under development.

Tonight I’ll check what version of openssl my Ubuntu 8.10 install is using. However, since my ISP currently has connectivity issues (submarine cable fault), I may not be able to post my results until I get back to work on Monday.

Ver
(fixed punctuation :P)

Veronica, it’s a similar concept, but I would be very surprised if OpenSSL used the libc implementation of rand(). When you get into cryptography, people really get extremely picky at the mathematical features of their random-number-generators.

If this were put into a car analogy, the OpenSSL guys are complaining that the tires have a weak tread pattern that might have trouble on ice, while the Arduino behavior seen above is like noticing that you have three flat tires and no engine.

hmm, that makes sense halley, but it does seem, so far, as if its limited to debian distros maybe even just Ubuntu. Saxdude doesn’t have the problem using SUSE 64 bit, whereas Berg (Kubuntu 8.10 32 bit) and I (Ubuntu 8.10 64 bit) do.

I don’t have another linux distro to test on though I will try installing a vm with Centos to see if the problem still occurs.

Ver