Pages: [1] 2   Go Down
Author Topic: Random()  (Read 1212 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a project, in which i need to choose between 4 numbers.
I used random(2,5) because those were the values I need.
However, i need to make sure each return is different.
Ex. I can't have the same number repeat. How do I do this?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

keep track of the most recent random number. Then before allowing a new random number, compare it to the variable. If it's different, do what you need to do with it. If it's the same, keep generating new ones until it's different.

Lather, rinse, repeat.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ex. I can't have the same number repeat. How do I do this?


You want a shuffle algorithm. Put the four numbers into an array. Pick one at random. Remove that. Pick one of the remaining three at random. Remove that. Pick one of the remaining two at random. Then you have the last one.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nick, Docedison, Shmaron, Thanks for the replies! I'll try Nick's out soon.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

More info: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks!
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 549
Posts: 46077
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I used random(2,5) because those were the values I need.
Keep in mind that the random() function will never return the upper value of the range that you specify. If you want it to return 2, 3, 4, and 5, the upper limit needs to be 6.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for your help everyone, I got it to work now!
Here's the code if anyone else wants to know...
Code:
// Random LED lights code...

long randNumber1;
int val = 2;
int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;


void setup() {               
 
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);     
  pinMode(led3, OUTPUT);     
  pinMode(led4, OUTPUT);     
  Serial.begin(9600);
  randomSeed(analogRead(1));
  //make sure pins are on low.
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);
 
 
}

// the loop routine runs over and over again forever:
void loop() {
  delay(3000);
 
  val = 1; 
  randNumber1 = random(2,6);
   

 //First LED.
  digitalWrite(randNumber1, HIGH);
  delay(700);
  val = randNumber1;
  digitalWrite(randNumber1, LOW);
  //Serial.println(randNumber1);
  //Serial.println(val);
 
  //Check to see if randNum is same. If so, change it.
  randNumber1 = random(2,6);
  while (randNumber1 == val) {
    randNumber1 = random(2,6);
  }
  //write to 2nd LED
  digitalWrite(randNumber1, HIGH);
  delay(700);
  digitalWrite(randNumber1, LOW);
  val = randNumber1;


  //Check 
 randNumber1 = random(2,6); 
  while (randNumber1 == val) {
    randNumber1 = random(2,6);
  }
  //Write to 3rd LED
  digitalWrite(randNumber1, HIGH);
  delay(700);
  digitalWrite(randNumber1, LOW);
    val = randNumber1;

 
  //Check
  randNumber1 = random(2,6);
  while (randNumber1 == val) {
    randNumber1 = random(2,6);
  }
 
  //Write to 4th LED.
  digitalWrite(randNumber1, HIGH);
  delay(700);
  digitalWrite(randNumber1, LOW);
    val = randNumber1;

 
delay(1000);
}
Logged

Indiana, US
Offline Offline
Full Member
***
Karma: 12
Posts: 204
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi iluvplanes,

Just a few coding observations that can make your code easier to read and easier to understand:

You have 2 delays, 3 sec at the beginning of your loop and 1 sec at the bottom of the loop, that can be combined into a single delay.

// Comments help to explain what you are doing. I had to read through the code to determine the following:

It appears that you have a loop cycle time of 6.8 seconds when you add all of the delays.  Within this time you would like to randomly flash some LEDs for 0.7 seconds.

From your code, it appears that you can flash an LED multiple times in the cycle--just not twice in a row, and that within a cycle it is ok if an LED doesn't flash at all. If not, then Nick's shuffle approach is the way to go.

That said... This was probably just supposed to be a fun activity and now that you've gotten it to work, you can move on to other things!  FUN, FUN, FUN.  If you're looking for something to tweak (and something to learn), maybe use potentiometers to vary the loop delay and on/off delays?
Logged

There are 10 types of people in the world, those that understand binary, and those that don't.

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi iluvplanes,

Just a few coding observations that can make your code easier to read and easier to understand:

You have 2 delays, 3 sec at the beginning of your loop and 1 sec at the bottom of the loop, that can be combined into a single delay.

// Comments help to explain what you are doing. I had to read through the code to determine the following:

It appears that you have a loop cycle time of 6.8 seconds when you add all of the delays.  Within this time you would like to randomly flash some LEDs for 0.7 seconds.

From your code, it appears that you can flash an LED multiple times in the cycle--just not twice in a row, and that within a cycle it is ok if an LED doesn't flash at all. If not, then Nick's shuffle approach is the way to go.

That said... This was probably just supposed to be a fun activity and now that you've gotten it to work, you can move on to other things!  FUN, FUN, FUN.  If you're looking for something to tweak (and something to learn), maybe use potentiometers to vary the loop delay and on/off delays?

Patduino, thanks for the tips!  What the code does is flash each LED once, making sure that each is flashed only once.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 169
Posts: 12448
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@iluvplanes
You can remove the while loops (and possibly endless testing) and make a function that scrambles the array.

Nice part of this solution is that double numbers are allowed  (and you can call scramble as often as you want)

Code:
int numbers[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13 };
int count = 13;

void setup()
{
  Serial.begin(9600);
  
  scrambleArray(numbers, count);
  for (int i=0; i<count; i++)
  {
    Serial.println(numbers[i]);
  }
  Serial.println("----");
}

void loop()
{}

void scrambleArray(int * array, int size)
{
  int last = 0;
  int temp = array[last];
  for (int i=0; i<size; i++)
  {
    int index = random(size);
    array[last] = array[index];
    last = index;
  }
  array[last] = temp;
}
« Last Edit: November 18, 2012, 03:56:20 pm by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Indiana, US
Offline Offline
Full Member
***
Karma: 12
Posts: 204
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi iluvplanes,

There seems to be a few other discussions happening here...  I'll try to address your comment:

Quote
What the code does is flash each LED once, making sure that each is flashed only once.

If you are happy with your code, then ignore me...  But I believe your software won't do what you wanted.  (1) the way you check for repeated random numbers wont guarantee that an LED wont repeat (walk through your code with the sequence: 2 3 2 3) and, (2) the whole thing is in a loop, so this will all happen more than once.

Just trying to help. I hope I'm not being too picky!
Logged

There are 10 types of people in the world, those that understand binary, and those that don't.

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Let me give it a try:

Code:
// the loop routine runs over and over again forever:
void loop() {
  //seed the random number generator in the setup()

  randNumber1 = random(0,1<<4); //generate a 4-bit random number
  digitalWrite(led1, randNumber1 & 0x01); //turn led1 on / off
  digitalWrite(led2, randNumber1 & 0x02); //turn led2 on / off
  digitalWrite(led3, randNumber1 & 0x04); //turn led3 on / off
  digitalWrite(led4, randNumber1 & 0x08); //turn led4 on / off

  delay(1000); //waste some time
}

A little bit tighter.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi iluvplanes,


If you are happy with your code, then ignore me...  But I believe your software won't do what you wanted.  (1) the way you check for repeated random numbers wont guarantee that an LED wont repeat (walk through your code with the sequence: 2 3 2 3) and, (2) the whole thing is in a loop, so this will all happen more than once.

Just trying to help. I hope I'm not being too picky!

Thanks, Pat, You're not being picky at all!  smiley
I see what you mean by a repeat, now... So I guess the only way to make it work would either be an array, or assign val 1-4, and then check each previous one.
About the loop, that's not much of an issue as much as getting the LEDs to flash in a random sequence.
Thanks for your help!
MT
Logged

Pages: [1] 2   Go Up
Jump to: