Sign in to follow this  
Followers 0
mateolasic14

True random numbers

18 posts in this topic

Please see the random() reference here: http://energia.nu/Random.html
You will also find an example Sketch on this page.
 
Put the following code in setup()
 
  randomSeed(analogRead(A0));
  Serial.println("===========");
  randNumber = random(300);
  Serial.println(randNumber);  

  // print a random number from 10 to 19
  randNumber = random(10, 20);
  Serial.println(randNumber);

Most important is to seed the random number generator with a different value every time the chip is reset. Doing an analogRead on an unconnected analog pin will have enough noise on it to seed the random number generator with a unique seed on startup.

 

 

abecedarian likes this

Share this post


Link to post
Share on other sites

 

Please see the random() reference here: http://energia.nu/Random.html
You will also find an example Sketch on this page.
 
Put the following code in setup()
 
  randomSeed(analogRead(A0));
  Serial.println("===========");
  randNumber = random(300);
  Serial.println(randNumber);  

  // print a random number from 10 to 19
  randNumber = random(10, 20);
  Serial.println(randNumber);

Most important is to seed the random number generator with a different value every time the chip is reset. Doing an analogRead on an unconnected analog pin will have enough noise on it to seed the random number generator with a unique seed on startup.

 

 

 

I saw that but I always get the same number

Share this post


Link to post
Share on other sites

Answer probably partly depends on how "truly" random it needs to be.

You could hook up an Atiny and use AVR entropy

http://hackaday.com/2014/02/10/the-two-component-random-number-generator/

 

(Some of the links in the followup to the hack a day post, or on the AVRentropy web site might be useful for exploring approaches.)

 

On the other hand, if different on each reset is all you need, what about saving the random number seed (in or flash, FRAM, or eeprom) and just increment it (or change it in some other way) after each reset.

 

http://xkcd.com/221/

Share this post


Link to post
Share on other sites

You could do an analogRead on several pins, do something like bit shifting or calculating an average / mean, set that as the seed, read a few random numbers and re-read the pins again, doing more math and averages and use that result as a final seed. No matter what you do though, if the seed value is re-used, the 'random' sequence following that would be the same.

 

For instance:

randomSeed((analogRead(A0) << random(16)) + (analogRead(A5) << random(16)) + (analogRead (A2) >> random(16)));
randomSeed((((analogRead(A3) << 1) + (analogRead(A1) >> 3) + (analogRead (A6) << 1)) + random(300) + random(500) + random (1024)) >> 2);
Get creative. ;)
energia likes this

Share this post


Link to post
Share on other sites

Thanks guys

I dont need TRUE random number,I only wanted a "random" number.I found that something is wrong with my chip and I change it and programmed it with same simple code with seed=analogread(unconnected pin) and it worked ;)

Share this post


Link to post
Share on other sites

Hello Guys !! 

how can i get random numbers between (e.g : {1839765.71, 1839765.79}) ... But only move the last digit (from 1 to 8). 

 

thanks !!

regards . MR

Share this post


Link to post
Share on other sites
1 hour ago, Medsimo said:

Hello Guys !! 

how can i get random numbers between (e.g : {1839765.71, 1839765.79}) ... But only move the last digit (from 1 to 8). 

 

thanks !!

regards . MR

Try modulo. 

result = random_number % 10;

 

enl likes this

Share this post


Link to post
Share on other sites

Notation: [ and ] indicate that the endpoint is included, ( and ) indicate a range that is open (endpoint not included)

First, I will presume you have a way to produce a random sequence of values (standard function or your own). Depending on the toolchain and libraries you use, the most common results of this are: A float (or double) [0..1), an unsigned (int or long int) over the full range of the type, or an int in a specified interval [0..n). The function to produce a bounded integer can be written several ways, but the two most common are


// return a random value from the interval[0..n]
unsigned random (unsigned n) {

   // rand() returns an unsigned int over [0..MAXUNSIGNED]
   return rand()%n;
}

as shown above, and

// return a random value from the interval[0..n]
unsigned random (unsigned n) {

   // rand() returns an unsigned int over [0..MAXUNSIGNED]
   return (int)((((double)rand())/MAXUNSIGNED)*n);
}

The second version (yes, I over-parenthesized to make the structure clear) first generates a real over [0..1) then scales to the desired range and truncates to an int. This is preferred for good behavoiur in some applications, especially with the common congruential pseudorandom generators, but is slower then the other version. For most things, it isn't important.

 

(warning: the code is off the top of my head and untested...)

 

If you are generating an integer in a range, such as [20..28)--8 values in the set--, or, more generally, [k..k+n) with n values:

// k is least in interval
// n is number of values to include
// random(n) is a function that produces values in the interval [0..n)

int r=k+random(n);

If you are generating a real value, as in your example, the principle is the same

// generate a double in specified interval from [a..b), selected from n values

double randomd(double a, double b, unsigned n) {
// this could be simpler in practice, but the structure here is to show method
// the method requires care it it is critical that it produces best values in
// that can be represented, starting with the applications definition of 'best'
   unsigned ri=random(n);
   double range =b-a;
   double offset=range*ri/n; // this is the offset from the starting value
   // ri/n will be a real from [0, range/n, 2*range/n,... (n-1)*range/n]
   return a+offset;
}

If you want a value selected from all reals in the interval:

// generate a double in specified interval from [a..b)

double randomd2(double a, double b) {
   double range =b-a;
   double offset=range*(rand()/MAXUNSIGNED); // this is the offset from the starting value
   return a+offset;
}

Share this post


Link to post
Share on other sites

(continued, due to editor throwing a fit on last code block in previous post)

Your example: ( {1839765.71, 1839765.79} ) ... But only move the last digit (from 1 to 8)

 

Presuming that you mean the last digit is selected from [1, 2, ..9], could be written as

randomd(1839765.71,1839765.80,9);

Again, note that the randomd() function DOES NOT include the right endpoint, so b is one least count greater in the function call than in your example. If you want the upper bound included, the function gets an n-1 for the division in offset.

Share this post


Link to post
Share on other sites
On 13/4/2017 at 5:28 PM, Rei Vilo said:

Try modulo. 


result = random_number % 10;

 

I try this example but the reaults is not what i'm looking for .... how can i fix it ? 

long randNumber;
float result;

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

void loop() {
  
  randNumber = random (183976571, 183976579);
  Serial.println(randNumber);
  result = randNumber%10;
  Serial.println(result);
  delay(1000);
}

 

Share this post


Link to post
Share on other sites

@Medsimo Can you provide an example of what you're looking for? Actually, I don't understand your requirements. 

On 13/04/2017 at 3:33 PM, Medsimo said:

how can i get random numbers between (e.g : {1839765.71, 1839765.79}) ... But only move the last digit (from 1 to 8). 

Share this post


Link to post
Share on other sites

Rei Vilo what i need is generate random numbers between {1839765.71, 1839765.79} but with float variable ... 

how can I get it ?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0