0
Offline
Newbie
Karma: 0
Posts: 9
Arduino rocks
|
 |
« on: November 20, 2008, 04:54:37 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
|
|
|
|
|
Logged
|
|
|
|
|
Brunsbüttel, SH, F.Rep.GERM
Offline
God Member
Karma: 4
Posts: 596
|
 |
« Reply #1 on: November 20, 2008, 05:42:09 pm » |
Hi! What if u use random(0,5120)/1024+1instead of 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 randomSeed(analogRead(0));or so, too? random() uses GNU CC's rand() function, which should deliver quite good pseudo-random numbers... Bye
|
|
|
|
« Last Edit: November 20, 2008, 05:43:31 pm by RIDDICK »
|
Logged
|
-Arne
|
|
|
|
Austin, TX USA
Offline
God Member
Karma: 3
Posts: 992
Arduino rocks
|
 |
« Reply #2 on: November 20, 2008, 05:53:46 pm » |
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
|
|
|
|
« Last Edit: November 20, 2008, 05:54:29 pm by mikalhart »
|
Logged
|
|
|
|
|
Austin, TX USA
Offline
God Member
Karma: 3
Posts: 992
Arduino rocks
|
 |
« Reply #3 on: November 20, 2008, 06:44:19 pm » |
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
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 9
Arduino rocks
|
 |
« Reply #4 on: December 07, 2008, 06:52:25 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Austin, TX USA
Offline
God Member
Karma: 3
Posts: 992
Arduino rocks
|
 |
« Reply #5 on: December 07, 2008, 07:24:16 pm » |
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
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 3
Arduino rocks
|
 |
« Reply #6 on: December 09, 2008, 04:32:18 pm » |
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?
|
|
|
|
|
Logged
|
|
|
|
|
Austin, TX USA
Offline
God Member
Karma: 3
Posts: 992
Arduino rocks
|
 |
« Reply #7 on: December 12, 2008, 04:42:19 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
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 3
Arduino rocks
|
 |
« Reply #8 on: December 14, 2008, 03:47:12 pm » |
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?
|
|
|
|
|
Logged
|
|
|
|
|
Austin, TX USA
Offline
God Member
Karma: 3
Posts: 992
Arduino rocks
|
 |
« Reply #9 on: December 15, 2008, 01:28:16 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Jr. Member
Karma: 0
Posts: 65
Arduino rocks
|
 |
« Reply #10 on: December 15, 2008, 06:04:25 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Austin, TX USA
Offline
God Member
Karma: 3
Posts: 992
Arduino rocks
|
 |
« Reply #11 on: December 15, 2008, 11:12:36 pm » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Connecticut, US
Offline
Edison Member
Karma: 1
Posts: 1036
Whatduino
|
 |
« Reply #12 on: December 15, 2008, 11:25:09 pm » |
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?
|
|
|
|
« Last Edit: December 15, 2008, 11:32:23 pm by halley »
|
Logged
|
|
|
|
|
Austin, TX USA
Offline
God Member
Karma: 3
Posts: 992
Arduino rocks
|
 |
« Reply #13 on: December 15, 2008, 11:49:27 pm » |
@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?
|
|
|
|
« Last Edit: December 16, 2008, 12:07:57 am by mikalhart »
|
Logged
|
|
|
|
|
Connecticut, US
Offline
Edison Member
Karma: 1
Posts: 1036
Whatduino
|
 |
« Reply #14 on: December 16, 2008, 12:37:27 am » |
@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.
|
|
|
|
« Last Edit: December 16, 2008, 12:37:57 am by halley »
|
Logged
|
|
|
|
|
|