[SOLVED] Random LED's

Hi,

Say I have 9 LED's connected to my arduino on pin 1 to 9. I want to be able to let a certain number of LED's go on, but which of the LED's go on has to be random. Any thoughts?

I wouldn't use Pin 1 (Serial TX) for I/O since Serial.print() is so helpful for debugging.

I'd use an array of N pin numbers. Pick some pairs of random numbers between 0 and N-1. Swap those two elements of the array to shuffle the array. Go through the array from 0 to N-1 turning on the desired number of LEDs and turning off the rest.

pseudo code

for (int i=0; i<9; i++)
{
  if (random(2) == 1) led[i] on
  else led[i] off
}

robtillaart:
pseudo code

for (int i=0; i<9; i++)

{
  if (random(2) == 1) led[i] on
  else led[i] off
}

That will turn on a random combination of the 9 LEDs but will not "let a certain number of LED's go on, but which of the LED's go on has to be random." By that I assume they meant that the number of lights turned on is known but the pattern is random. That's why I recommended the shuffle.

johnwasser:
That will turn on a random combination of the 9 LEDs but will not "let a certain number of LED's go on, but which of the LED's go on has to be random." By that I assume they meant that the number of lights turned on is known but the pattern is random. That's why I recommended the shuffle.

That's right, I didn't fully understand your first post though but so far I've got this:

int timer = 1000; //Sets timer
int ledPins [] = {2, 3, 4, 5, 6, 7,}; //Sets pins
int pinCount = 6; //Sets the number of pins
int Number = 3; //Sets the amount of LEDs that will go on
int thisPin; //Specificies a certain pin
  
void setup() {
  Serial.begin(9600);
  for (int thisPin = 0; thisPin < pinCount; thisPin++) {
    pinMode(ledPins[thisPin], OUTPUT); //Sets all the ledPins as output
  }
}

void loop(){
  for (int i=0; i<=Number; i++){
  if (i < Number) { 
  thisPin = random(pinCount);
  digitalWrite(ledPins[thisPin], HIGH); }  //this will loop "Number" times
  else {
  delay(timer);
  for (int thisPin = 0; thisPin < pinCount; thisPin++) {
  digitalWrite(ledPins[thisPin], LOW); } //turns of all the pins
  }
  }
}

this almost works except sometimes there will be only 1 or 2 light burning instead of 3, because the pin has already been picked.

sometimes there will be only 1 or 2 light burning instead of 3, because the pin has already been picked.

So instead of just picking a random number and using it you pick a random number and if it has already been chosen pick another one. A wile loop can be used to ensure that it only exits when a number not chosen before has been selected.

This is oddly prescriptive, is it homework?

Thanks!

Grumpy_Mike:
This is oddly prescriptive, is it homework?

No not at all, I just picked up Arduino as a hobby and I'm trying to rebuild a binary clock I saw a while back.

you need to set a random value like in this sketch.

#include <LiquidCrystal.h>

int address;
long randomvalue = 0; //random balue 1
long countervalue = 0; // counter value
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup()
{

  lcd.begin(16,2);
  lcd.print("COX Industries");
  delay(1000);
  

  countervalue = 1;
  lcd.setCursor(0,0);
  lcd.print("------START-----");
  lcd.setCursor(0,1);
  lcd.print("--CALCULATION---");
  delay(1500);
  lcd.clear();
}


void loop()
{
  lcd.setCursor(0,0);
  randomvalue = random(1000000000);
  lcd.print(countervalue);
  lcd.setCursor(4,1);
  lcd.print(randomvalue);



  delay(500);
  lcd.clear();
  countervalue = (countervalue+1)%1000000;// increment the counter

}

you need to set a random value like in this sketch.

And how is that going to stop there being a repeat number in any batch of random numbers?

Grumpy_Mike:

sometimes there will be only 1 or 2 light burning instead of 3, because the pin has already been picked.

So instead of just picking a random number and using it you pick a random number and if it has already been chosen pick another one. A while loop can be used to ensure that it only exits when a number not chosen before has been selected.

Like this:

int timer = 1000; //Sets timer
const int ledPins [] = {
  2, 3, 4, 5, 6, 7,}; //Sets pins
const int pinCount = 6; //Sets the number of pins
int Number = 3; //Sets the amount of LEDs that will go on
int thisPin;
int alreadySet;

void setup() {
  Serial.begin(9600);
  for (int thisPin = 0; thisPin < pinCount; thisPin++) {
    pinMode(ledPins[thisPin], OUTPUT); //Sets all the ledPins as output
  }
}

void loop(){
  // Turn off all the LEDs
  for (int thisPin = 0; thisPin < pinCount; thisPin++)
    digitalWrite(ledPins[thisPin], LOW);

  // Turn on "Number" randonm LEDs
  for (int i=0; i<Number; i++) {
    do {
      thisPin = random(pinCount);
      alreadySet = digitalRead(ledPins[thisPin]);
      digitalWrite(ledPins[thisPin], HIGH); 
    } 
    while (alreadySet);  // If the LED was already on, try a different one
  }

  delay(timer);
}

Thanks John! Although this way I won't be able to use shift registers won't I? because in my final project I will be using 27 LED's. But that's not to big of a problem, in that case I will use I2C I/O expanders.

No not at all, I just picked up Arduino as a hobby and I'm trying to rebuild a binary clock I saw a while back.

How does a clock use random numbers?

How does a clock use random numbers?

Well, I was just reading this Instructable about someone whose sleep pattern might be better suited to 6x sleeps a week not the traditional 7..... maybe others would be happier on time system which wakes them up and sends them to bad randomly.

PaulS:

No not at all, I just picked up Arduino as a hobby and I'm trying to rebuild a binary clock I saw a while back.

How does a clock use random numbers?

Like this!

Mubanga:
Thanks John! Although this way I won't be able to use shift registers won't I? because in my final project I will be using 27 LED's. But that's not to big of a problem, in that case I will use I2C I/O expanders.

You can use an unsigned long (32-bit integer) to keep track of which LEDs you want on and off.

int timer = 1000; //Sets timer
const int pinCount = 6; //Sets the number of pins
int Number = 3; //Sets the amount of LEDs that will go on
unsigned long pattern;
int thisPin;
int alreadySet;

void loop(){
  // Turn off all the LEDs
  pattern = 0;

  // Turn on "Number" randonm LEDs
  for (int i=0; i<Number; i++) {
    do {
      thisPin = random(pinCount);
      alreadySet = pattern & (1<<thisPin));
      pattern |= (1<<thisPin);
    } 
    while (alreadySet);  // If the LED was already on, try a different one
  }
  //  Send 'pattern' to shift registers
  delay(timer);
}

[/quote]

johnwasser:

Mubanga:
Thanks John! Although this way I won't be able to use shift registers won't I? because in my final project I will be using 27 LED's. But that's not to big of a problem, in that case I will use I2C I/O expanders.

You can use an unsigned long (32-bit integer) to keep track of which LEDs you want on and off.

int timer = 1000; //Sets timer

const int pinCount = 6; //Sets the number of pins
int Number = 3; //Sets the amount of LEDs that will go on
unsigned long pattern;
int thisPin;
int alreadySet;

void loop(){
  // Turn off all the LEDs
  pattern = 0;

// Turn on "Number" randonm LEDs
  for (int i=0; i<Number; i++) {
    do {
      thisPin = random(pinCount);
      alreadySet = pattern & (1<<thisPin));
      pattern |= (1<<thisPin);
    }
    while (alreadySet);  // If the LED was already on, try a different one
  }
  //  Send 'pattern' to shift registers
  delay(timer);
}

So i thought this did the trick since I tested it with one shift register (register pin 0 - 7), today I tried daisy chaining an other one to it (register pin 0 - 15). And I ran in to the same problem: most of the time the desired amount of LEDs are burning but about 10% of the time a couple of them don't light up (I guess it has some thing to do with the pattern being full or something?). Is there a fix for this?

I think you have to show your code.

johnwasser:
I think you have to show your code.

yeah it was basically the code you gave me, modified for shift register usage

it works when my loop is like this:

void loop(){

    // Turn on "Number" randonm LEDs
  for (int i=0; i<Number; i++) {
    do {
      thisPin = random(8);
      alreadySet = pattern & (1<<thisPin);
      pattern |= (1<<thisPin);
      setRegisterPin(thisPin, HIGH);
      writeRegisters(); 
    } 
    while (alreadySet);  // If the LED was already on, try a different one
  }
pattern = 0;


  delay(timer);
  
  clearRegisters();

}

but as soon as I change the 8 in: thisPin = random(8) to a higher number, (starting to use the second shift register, which is a 74HC595 by the way) I get the problem (most of the time the desired amount of LEDs are burning but about 10% of the time a couple of them don't light up)

Here is the complete code if needed

int timer = (1000);
int SER_Pin = 8;   //pin 14 on the 75HC595
int RCLK_Pin = 9;  //pin 12 on the 75HC595
int SRCLK_Pin = 10; //pin 11 on the 75HC595
int Number = 4;
int thisPin;
int alreadySet;

#define shiftCount 2 //How many shift registers
#define pinCount shiftCount * 8 //How many pins

boolean registers[pinCount];
unsigned long pattern;

void setup(){
  pinMode(SER_Pin, OUTPUT);
  pinMode(RCLK_Pin, OUTPUT);
  pinMode(SRCLK_Pin, OUTPUT);
  Serial.begin(9600);

  //reset all register pins
  clearRegisters();
  writeRegisters();
}               

//set all register pins to LOW
void clearRegisters(){
  for(int i = 0; i <  pinCount; i++){
     registers[i] = LOW;
     
  }
} 

//Set and display registers
//Only call AFTER all values are set how you would like (slow otherwise)
void writeRegisters(){

  digitalWrite(RCLK_Pin, LOW);

  for(int i = pinCount - 1; i >=  0; i--){
    digitalWrite(SRCLK_Pin, LOW);

    int val = registers[i];

    digitalWrite(SER_Pin, val);
    digitalWrite(SRCLK_Pin, HIGH);

  }
  digitalWrite(RCLK_Pin, HIGH);

}

//set an individual pin HIGH or LOW
void setRegisterPin(int index, int value){
  registers[index] = value;
}

void loop(){

    // Turn on "Number" randonm LEDs
  for (int i=0; i<Number; i++) {
    do {
      thisPin = random(8);
      alreadySet = pattern & (1<<thisPin);
      pattern |= (1<<thisPin);
      setRegisterPin(thisPin, HIGH);
      writeRegisters(); 
    } 
    while (alreadySet);  // If the LED was already on, try a different one
  }
pattern = 0;


  delay(timer);
  
  clearRegisters();

}

Oh and my set up is like this:

The code looks OK. Have you checked to see that all of the lights work? Watch each light for 10 seconds or until if comes on. It might be that one or more of your LEDs is not working (bad connection) and so the random patterns will sometimes hit a non-working LED.