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.
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;
}
}
PaulRB:
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.
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.
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.
Here is the code that I attempted to run. The LED attached to pin 10 flashes at 10 hz and the other remains unlit...
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;
}
}
Now neither LED illuminate after changing things so I'm not sure what I'm doing wrong here.
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;
}
}
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
random(0, 1);
does not generate a random number that is either 0 or 1. Print it to see what it does generate
UKHeliBob:
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
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...
UKHeliBob:
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
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?
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:
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;
}
}