I have been advised time and again to embrace the "blink without delay" example to perform functions independently. This sketch is a failed attempt to program two solenoids to fire randomly, not consecutively. Although they are random, one activates after the other in sequence. Am I asking Arduino to do something it wasn't designed to do?
int solOne =2;
int solTwo =4;
int solState = LOW;
long previousMillis = 0;
long interval = 10;
long randOn1 = 0; // Initialize a variable for the ON time
long randOff1 = 0;
long randOn2 = 0; // Initialize a variable for the ON time
long randOff2 = 0;
void setup() {
randomSeed (analogRead (0));
pinMode (solOne, OUTPUT);
pinMode (solTwo, OUTPUT);
}
void loop()
{
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (solState == LOW)
solState = HIGH;
else
solState = LOW;
OneSol();
TwoSol();
delay(1000);
}
}
void OneSol()
{
randOn1 = random (100, 1200); // generate ON time between 0.1 and 1.2 seconds
randOff1 = random (200, 900); // generate OFF time between 0.2 and 0.9 seconds
digitalWrite(solOne, HIGH); // sets the solenoid on
delay(randOn1); // waits for a random time while ON
digitalWrite(solOne, LOW); // sets the solenoid off
delay(randOff1);
}
void TwoSol()
{
randOn2 = random (150, 500); // generate ON time between 0.1 and 1.2 seconds
randOff2 = random (100, 1900); // generate OFF time between 0.2 and 0.9 seconds
digitalWrite(solTwo, HIGH); // sets the solenoid on
delay(randOn2); // waits for a random time while ON
digitalWrite(solTwo, LOW); // sets the solenoid off
delay(randOff2);
}
Looking at your code I see that the call to TwoSol() always follows the call to OneSol() so it is no wonder that the solenoids always work in sequence, and you exacerbate that by using delay() in the functions which is exactly what you are trying to avoid.
If 1/100th of a second has passed since the time was last noted:
begin
note the time.
Toggle 'solState' which is never used.
Turn on Solenoid One
delay between 100 and 1200 milliseconds
Turn off Solenoid One
delay between 200 and 900 milliseconds
Turn on Solenoid Two
delay between 150 and 500 milliseconds
Turn off Solenoid Two
delay between 100 and 1900 milliseconds
delay 1000 milliseconds
end
Since your IF statement takes at least 1.45 seconds (all those delays) the 1/100th of a second will always have passed before you check again. To do 'Blink Without Delay' you have to take out ALL the delays.
Great advise, great because I understand what you are describing, which is not always the case. First time I've actually gotten two of anything to function independently. Now for the random business which I assume is just a matter of editing. Thanks again.
After looking at web examples, I assumed this would generate random solenoids. I am puzzled why it doesn't. The two ignore the random and fire at 1/2 and one second just as before.
const byte solOne = 2;
const byte solTwo = 4;
// Time periods of blinks in milliseconds (1000 to a second).
unsigned long solOneinterval = 0;//500
unsigned long solTwointerval = 0;//1000
// Variable holding the timer value so far. One for each "Timer"
unsigned long solOnetimer;
unsigned long solTwotimer;
// remember when we toggled it
solTwotimer = millis ();
} // end of toggleRedLED
void loop ()
{
// Handling the blink of one LED.
solOneinterval = random (100,500); ?????????
if ( (millis () - solOnetimer) >= solOneinterval)
toggleSolOne ();
solTwointerval = random (500,1000); ????????
// The other LED is controlled the same way. Repeat for more LEDs
if ( (millis () - solTwotimer) >= solTwointerval)
toggleSolTwo ();
/* Other code that needs to execute goes here.
It will be called many thousand times per second because the above code
does not wait for the LED blink interval to finish. */
Looks to me like you are resetting your random value every iteration.
Check the timer first, if it has ended call the toggle, and after that reset the random value still within the braces { } that belong to the if statement (you aren't using those yet).
Then the random value will not be reset every iteration (which is more than several thousand times per second).
You are still setting the random interval every time the loop runs.
You should only set a new value after the old one had reached its end.
So change this part of your code:
void loop ()
{
solOneinterval = random (100,500);
if ( (millis () - solOnetimer) >= solOneinterval)
toggleSolOne ();
solTwointerval = random (500,1000);
if ( (millis () - solTwotimer) >= solTwointerval)
toggleSolTwo ();
}
To:
void loop ()
{
if ( (millis () - solOnetimer) >= solOneinterval)
{
toggleSolOne ();
solOneinterval = random (100,500); // A new value is set after the old value has done it's job
}
if ( (millis () - solTwotimer) >= solTwointerval)
{
toggleSolTwo ();
solTwointerval = random (500,1000); // A new value is set after the old value has done it's job
}
}