Pages: 1 2 [3] 4   Go Down
Author Topic: Help - Random function not working  (Read 5577 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ubuntu 8.10, 32-bit, Arduino 0012, Duemilanove.

Same issues here. Weird...

I also tried 0011, and it seems to give me the same problem.

Has anyone found toolchain/arduino combination that gives reasonable behavior on linux?
Logged

Connecticut, US
Offline Offline
Edison Member
*
Karma: 2
Posts: 1036
Whatduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Can someone just trade .hex files with someone else, to see exactly what's wrong with the libc rand() on the offending platform?  There's a disassembler in the AVR toolset that someone mentioned, we should see what's broken with a diff.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Linked is a "bad" version of the sketch on the RandomSeed ref page

http://82smugglers.com/misc/sketch_081230b.hex

http://arduino.cc/en/Reference/RandomSeed

It repeats 138,188,288
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

And here is the same code that runs correctly. Compiled on Ubunut 7.10 with arduino-0012

http://82smugglers.com/misc/sketch_081230a.hex

(I don't know enough to mess with the hex, but I'll take a look just for fun)
« Last Edit: December 30, 2008, 10:20:09 pm by timmaah » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am sure this means something to someone... but not my just yet.. .

NON RAND CODE
http://82smugglers.com/misc/sketch_b.txt

PROPER RAND CODE:
http://82smugglers.com/misc/sketch_a.txt

(oh yeah... used vAVRdisasm http://www.frozeneskimo.com/electronics/vavrdisasm-free-avr-disassembler/ )
« Last Edit: December 30, 2008, 10:33:54 pm by timmaah » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@timmahh...Thank you for posting the code and the disassembler source.  The code is fairly easy to trace as the AVR only has 136 instructions but still is quite tedious.  Could you tell me the sources for both code segments, the difference is quite significant.
« Last Edit: December 30, 2008, 10:55:24 pm by Patzak » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sources == Source Code?

If so... both should be the very same.. I noticed the large difference as well..

Code:
long randNumber;

void setup(){
  Serial.begin(9600);
  randomSeed(analogRead(0));
}

void loop(){
  randNumber = random(300);
  Serial.println(randNumber);

  delay(50);
}
Logged

Connecticut, US
Offline Offline
Edison Member
*
Karma: 2
Posts: 1036
Whatduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

timmaah, this is great, but I made a mistake.  We can get a listing file (with symbol info mixed in) from the .elf file, which is the build step just before .hex.  Can you build again on both platforms, and post your .lst file(s)?

Code:
avr-objdump -h -S sketch_081230a.elf > sketch_081230a.lst

I've done this for OSX, can you do one for the broken sketch A?
« Last Edit: December 30, 2008, 11:04:30 pm by halley » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

B is the bad one...

http://82smugglers.com/misc/sketch_081230b.lst


A works...
http://82smugglers.com/misc/sketch_081230a.lst
Logged

Austin, TX USA
Offline Offline
God Member
*****
Karma: 4
Posts: 997
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just to avoid confusion, it might be better to test a script that calls just rand(void) and random(void) -- both of which are misbehaving standard library functions -- and not random(int x), which is the Arduino function that only indirectly calls libc's rand().

Also, calling the seeding functions in the test program muddy the waters unnecessarily.

I am curious to find out why these two functions misbehave and whether there might not be other libc functions that are defective.

Mikal
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 124
Posts: 6637
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just for completeness, could you run "avr-gcc --version" ?
(is there a similar command that will print the versions of all the
libraries involved ?)

The macosx arduino 12 has gcc 4.3.0
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

avr-gcc (GCC) 4.3.0   as well...


mikalhart, I'll make a more direct rand call after work today.. (no boss == short workday.. woohoo)


Logged

Connecticut, US
Offline Offline
Edison Member
*
Karma: 2
Posts: 1036
Whatduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It doesn't matter, mikalhart.

random() calls rand(); rand() calls an internal do_rand().

In A and B, all of the incidental calls like srand(), rand(), random() are identical bytecodes.  The do_rand() is significantly different.

As I mentioned earlier, the usual PRNG approach is more bit-fiddling than what I would call real math, and I expect the bit fiddling math just works out to be wrong in one library or the other.

The do_rand() in B uses more convenience routines to do the prologue and epilogue, but that probably isn't breaking the values.

The two routines are using significantly different operations to move the basic operands into place before starting the math.  This is typical when a compiler's optimizer gets employed, so maybe one libc was built with an optimizer enabled, while the other was not.

The do_rand() in A uses a routine called __udivmodsi4 twice.  In the same fashion, the do_rand() in B uses a routine called __divmodsi4.  Signed vs unsigned division is probably the culprit here.
Logged

Austin, TX USA
Offline Offline
God Member
*****
Karma: 4
Posts: 997
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Halley,

Quote
It doesn't matter... random() calls rand();
I'm just trying to avoid confusing people between Arduino's random(int), which does indeed call rand(), and libc's less-known cousin random() which doesn't, but is broken in the same way as rand().  It calls do_random().  (See random.c.)

If we were going to try to trace through the routines, it would be much better if they started with identical seeds, hence the admonition to avoid calling srand or srandom.

That said, I think you are probably on to something with the do_rand() analysis.  Nice work!  Do we have the wherewithal to push this awful bug back to its source and get it fixed?

Thanks, Halley!

Mikal
« Last Edit: December 31, 2008, 10:46:33 am by mikalhart » Logged

Connecticut, US
Offline Offline
Edison Member
*
Karma: 2
Posts: 1036
Whatduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

mikalhart, no worries, wasn't trying to be dismissive.

As for getting it fixed upstream, I guess someone has to contact the avr-gcc developers to point out the discrepancy.  Showing them the two listing files above, asking them to look at code at <do_rand> and THEN a link to this whole discussion, should be enough for them to track down the problem.
Logged

Pages: 1 2 [3] 4   Go Up
Jump to: