Arduino Forum

Using Arduino => LEDs and Multiplexing => Topic started by: tekjones9 on May 22, 2019, 09:01 pm

Title: Randomly Alternate LED pins
Post by: tekjones9 on May 22, 2019, 09:01 pm
I would like to use an Arduino Uno board to control multiple (2 to 4) LEDs. I can set them up to blink independently at the desired rates, but I would like these blink rates to vary randomly on one LED and for the blink to be randomly given to one over the other.

Essentially, I have an LED mounted to the left (pin 10) and an LED mounted to the right (pin 11). 1 LED should always 'blink' at a perceived constant rate of 20 kHz and this should be randomly assigned to either the right or left. The second LED (on either the left or right, depending on the first assignment) should blink at randomly varying intervals from 10 - 100 Hz in 5 Hz increments.

The following code controls two LEDs independently at 10 Hz and 20 kHz but I do not know how to make the random assignments to each pin or randomly vary one LED's rate.

Code: [Select]

unsigned long previousMillisLED10 = 0; //millis() returns an unsigned long
unsigned long previousMillisLED11 = 0; //millis() returns an unsigned long

unsigned long intervalLED10 = 100; //time needed to wait
unsigned long intervalLED11 = 0.00005;

boolean LED10State = false; //state variable for LED
boolean LED11State = false;

int ledPin1 = 11;
int ledPin2 = 10;
 
void setup() {
  // put your setup code here, to run once
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT); 
}

void loop() {
  // put your main code here, to run repeatedly:
 
unsigned long currentMillis = millis(); //grab current time
//toggle LED10
if ((unsigned long)(currentMillis-previousMillisLED10)>= intervalLED10){
  LED10State =!LED10State; //toggles the state
  digitalWrite(ledPin1, LED10State); //sets the LED based on ledState
  //save the 'current' time to pin 10's previousMillis
  previousMillisLED10 = currentMillis;
}
//toggle LED11
if ((unsigned long)(currentMillis-previousMillisLED11)>= intervalLED11){
  LED11State =!LED11State; //toggles the state
  digitalWrite(ledPin2, LED11State); //sets the LED based on ledState
  //save the 'current' time to pin 11's previousMillis
  previousMillisLED11 = currentMillis;
}
}
Title: Re: Randomly Alternate LED pins
Post by: PaulRB on May 22, 2019, 09:21 pm
Quote
. 1 LED should always 'blink' at a perceived constant rate of 20 kHz
Perceived by what? That's far too fast for a human to perceive.

Quote
The following code controls two LEDs independently at 10 Hz and 20 kHz
Your code might do the 10Hz thing, but it won't do the 20KHz thing.

Code: [Select]
unsigned long intervalLED11 = 0.00005;
An integer, even an unsigned long integer, can't hold a fraction.
Title: Re: Randomly Alternate LED pins
Post by: tekjones9 on May 22, 2019, 10:50 pm
Perceived by what? That's far too fast for a human to perceive.
Your code might do the 10Hz thing, but it won't do the 20KHz thing.

Code: [Select]
unsigned long intervalLED11 = 0.00005;
An integer, even an unsigned long integer, can't hold a fraction.
Not for humans. And it is supposed to be perceived as constant (not blinking). Basically, any value above 100 Hz will do. My problem is the randomization, not the blinking.
Title: Re: Randomly Alternate LED pins
Post by: UKHeliBob on May 22, 2019, 11:55 pm
Quote
I do not know how to make the random assignments to each pin or randomly vary one LED's rate.
I assume that you are aware of the random() and randomSeed() functions
Title: Re: Randomly Alternate LED pins
Post by: tekjones9 on May 23, 2019, 12:30 am
I assume that you are aware of the random() and randomSeed() functions
I tried using the random function and got errors. I tried:

Code: [Select]
int ledPin1 = random(10,12)

to select randomly between pins 10 and 11 but this did nothing. How (and where) would that function be implemented?
Title: Re: Randomly Alternate LED pins
Post by: david_2018 on May 23, 2019, 03:34 am
You cannot use random() when you are declaring the ledPin1 and ledPin2 variables, because random() only works when the sketch is running on an arduino.  You would need to use random() in setup() to set the pin numbers assigned to the variables. It is also important to use randomseed() prior to using random(), otherwise you may get the same random number every time you run the sketch.



Title: Re: Randomly Alternate LED pins
Post by: UKHeliBob on May 23, 2019, 08:04 am
Quote
I tried using the random function and got errors. I tried:
Please post the complete program that you tried

I would put the pin numbers to be selected at random in an array and use random() to choose the array index and hence a random pin number
Title: Re: Randomly Alternate LED pins
Post by: tekjones9 on May 27, 2019, 06:38 pm
Here is the code that I attempted to run. The LED attached to pin 10 flashes at 10 hz and the other remains unlit...
Code: [Select]


unsigned long previousMillisLED10 = 0; //millis() returns an unsigned long
unsigned long previousMillisLED11 = 0; //millis() returns an unsigned long

unsigned long intervalLED10 = 100; //time needed to wait (ms) - 10 Hz
unsigned long intervalLED11 = 1; //1 kHz

boolean LED10State = false; //state variable for LED
boolean LED11State = false;

int ledPin1;
int ledPin2;

void setup() {
  // put your setup code here, to run once
pinMode(ledPin1, OUTPUT);
//pinMode(ledPin2, OUTPUT); 

int myPins[]={10, 11};
randomSeed(2);

ledPin1 = myPins[random(10,12)];

if(ledPin1 = 10){
  int ledPin2 = 11;}
  else {
    int ledPin2 = 10;}
   
}

void loop() {
  // put your main code here, to run repeatedly:
 
unsigned long currentMillis = millis(); //grab current time
//toggle LED10
if ((unsigned long)(currentMillis-previousMillisLED10)>= intervalLED10){
  LED10State =!LED10State; //toggles the state
  digitalWrite(ledPin1, LED10State); //sets the LED based on ledState
  //save the 'current' time to pin 10's previousMillis
  previousMillisLED10 = currentMillis;
}
//toggle LED11
if ((unsigned long)(currentMillis-previousMillisLED11)>= intervalLED11){
  LED11State =!LED11State; //toggles the state
  digitalWrite(ledPin2, LED11State); //sets the LED based on ledState
  //save the 'current' time to pin 11's previousMillis
  previousMillisLED11 = currentMillis;
}
}
Title: Re: Randomly Alternate LED pins
Post by: PaulRB on May 27, 2019, 08:41 pm
Code: [Select]
ledPin1 = myPins[random(10,12)];
No, the array indexes are 0 and 1, not 10 and 11.
Title: Re: Randomly Alternate LED pins
Post by: tekjones9 on May 29, 2019, 04:09 pm
Code: [Select]
ledPin1 = myPins[random(10,12)];
No, the array indexes are 0 and 1, not 10 and 11.
Now neither LED illuminate after changing things so I'm not sure what I'm doing wrong here.





Code: [Select]
unsigned long previousMillisLED10 = 0; //millis() returns an unsigned long
unsigned long previousMillisLED11 = 0; //millis() returns an unsigned long

unsigned long intervalLED10 = 100; //time needed to wait (ms) - 10 Hz
unsigned long intervalLED11 = 1; //1 kHz

boolean LED10State = false; //state variable for LED
boolean LED11State = false;

int ledPin1;
int ledPin2;

void setup() {
  // put your setup code here, to run once
pinMode(ledPin1, OUTPUT);
//pinMode(ledPin2, OUTPUT); 

int myPins[]={10, 11};
randomSeed(2);

ledPin1 = myPins[random(0,1)];

if(ledPin1 = 0){
  int ledPin2 = 1;}
  else {
    int ledPin2 = 0;}
   
}

void loop() {
  // put your main code here, to run repeatedly:
 
unsigned long currentMillis = millis(); //grab current time
//toggle LED10
if ((unsigned long)(currentMillis-previousMillisLED10)>= intervalLED10){
  LED10State =!LED10State; //toggles the state
  digitalWrite(ledPin1, LED10State); //sets the LED based on ledState
  //save the 'current' time to pin 10's previousMillis
  previousMillisLED10 = currentMillis;
}
//toggle LED11
if ((unsigned long)(currentMillis-previousMillisLED11)>= intervalLED11){
  LED11State =!LED11State; //toggles the state
  digitalWrite(ledPin2, LED11State); //sets the LED based on ledState
  //save the 'current' time to pin 11's previousMillis
  previousMillisLED11 = currentMillis;
}
}
Title: Re: Randomly Alternate LED pins
Post by: PaulRB on May 29, 2019, 05:04 pm
Code: [Select]
ledPin1 = myPins[random(0,1)];
Mistake there. When you wanted random to return 10 or 11, did you put "random(10,11)" ?
Title: Re: Randomly Alternate LED pins
Post by: tekjones9 on May 29, 2019, 05:30 pm
Code: [Select]
ledPin1 = myPins[random(0,1)];
Mistake there. When you wanted random to return 10 or 11, did you put "random(10,11)" ?
Am I supposed to use the array indices of 0 and 1 or the actual pin numbers 10 and 11?
Title: Re: Randomly Alternate LED pins
Post by: UKHeliBob on May 29, 2019, 05:58 pm
The pin numbers are in an array
The array indices are 0 and 1
You need to generate a random number that is either 0 or 1 to use as the index to the array
Code: [Select]
random(0, 1);
does not generate a random number that is either 0 or 1.  Print it to see what it does generate
Title: Re: Randomly Alternate LED pins
Post by: DrAzzy on May 29, 2019, 06:34 pm
The pin numbers are in an array
The array indices are 0 and 1
You need to generate a random number that is either 0 or 1 to use as the index to the array
Code: [Select]
random(0, 1);
does not generate a random number that is either 0 or 1.  Print it to see what it does generate
Or he could just read the reference documentation, specifically that for the max parameter...
https://www.arduino.cc/reference/en/language/functions/random-numbers/random/ (https://www.arduino.cc/reference/en/language/functions/random-numbers/random/)
Title: Re: Randomly Alternate LED pins
Post by: UKHeliBob on May 29, 2019, 07:29 pm
Or he could just read the reference documentation, specifically that for the max parameter...
https://www.arduino.cc/reference/en/language/functions/random-numbers/random/ (https://www.arduino.cc/reference/en/language/functions/random-numbers/random/)
Agreed, but back in reply #7 he/she used the random() function correctly, albeit to generate the 2 wrong numbers
Title: Re: Randomly Alternate LED pins
Post by: tekjones9 on May 29, 2019, 07:37 pm
The pin numbers are in an array
The array indices are 0 and 1
You need to generate a random number that is either 0 or 1 to use as the index to the array
Code: [Select]
random(0, 1);
does not generate a random number that is either 0 or 1.  Print it to see what it does generate
Well, changing it to ledPin1=myPins[random(o,2)]; which should generate a value between 0 and 1 does not actually fix the problem so what is wrong?
Title: Re: Randomly Alternate LED pins
Post by: PaulRB on May 29, 2019, 08:02 pm
More errors here:
Code: [Select]
ledPin1 = myPins[random(0,2)];

if(ledPin1 = 0){
  int ledPin2 = 1;}
  else {
    int ledPin2 = 0;}

What value could ledPin1 be here? Should it ever be zero?
 
It's important to understand the difference between "=" and "=="
Title: Re: Randomly Alternate LED pins
Post by: tekjones9 on May 29, 2019, 10:58 pm
Thank you to everyone for your helpful comments. This isn't a programming language I have used much before so the little things become frustratingly invisible.

Below is the code that achieves my desired output for any future reference:

Code: [Select]

unsigned long previousMillisLED10 = 0; //millis() returns an unsigned long
unsigned long previousMillisLED11 = 0; //millis() returns an unsigned long

unsigned long intervalLED10 = 100; //time needed to wait (ms) - 10 Hz
unsigned long intervalLED11 = 1; //1 kHz

boolean LED10State = false; //state variable for LED
boolean LED11State = false;

int ledPin1;
int ledPin2;

void setup() {
  // put your setup code here, to run once
Serial.begin(9600);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT); 

int myPins[]={10, 11};

randomSeed(analogRead(A0));

ledPin1 = myPins[random(0,2)];

   if(ledPin1 == 10){
  ledPin2 = 11;}
  else if (ledPin1 == 11){
    ledPin2 = 10;}

Serial.print("Pin 1: " );
Serial.println(ledPin1);
Serial.print("Pin 2: " );
Serial.println(ledPin2);
}

void loop() {
  // put your main code here, to run repeatedly:
 

   

unsigned long currentMillis = millis(); //grab current time
//toggle LED10
if ((unsigned long)(currentMillis-previousMillisLED10)>= intervalLED10){
  LED10State =!LED10State; //toggles the state
  digitalWrite(ledPin1, LED10State); //sets the LED based on ledState
  //save the 'current' time to pin 10's previousMillis
  previousMillisLED10 = currentMillis;
}
//toggle LED11
if ((unsigned long)(currentMillis-previousMillisLED11)>= intervalLED11){
  LED11State =!LED11State; //toggles the state
  digitalWrite(ledPin2, LED11State); //sets the LED based on ledState
  //save the 'current' time to pin 11's previousMillis
  previousMillisLED11 = currentMillis;
}
}