Controlling Multiple Solenoids with millis()


I’m trying to help a friend interested in using multiple solenoids to make music but I’m a bit at a loss for programming this. They want to be able to control each solenoid individually, with independent times of HIGH and LOW activity, but without the delay function. Here is the failing code that I have now if it helps at all–I was testing with only one solenoid to see if it would work the rest is commented out and doesn’t use millis().

long interval_one = 500;
long delay_one =  250;

long interval_two = random(300, 750);
long delay_two = random(200, 450);

long interval_three = random(700, 2000);
long delay_three = random(300, 450);

long interval_four = random(500, 3000);
long delay_four = random(250, 500);

long interval_five = random(550, 1000);
long delay_five = random(225, 500);

long interval_six = random(1750, 7000);
long delay_six = random(175, 475);

long interval_seven = random(2000, 2500);
long delay_seven = random(270, 380);

long interval_eight = random(600, 3000);
long delay_eight = random(325, 400);

unsigned long time;

void setup() {
  // Variable i denotes values between 0-8 to "activate" each solenoid 
  for (int i; i < 9; i++){
      pinMode(i, OUTPUT); 

void loop() {

  time = millis();

  if (time % delay_one == 0){
    digitalWrite(1, HIGH);
  if (time % interval_one == 0){
    digitalWrite(1, LOW);

//  digitalWrite(2, HIGH);
//  delay(delay_two);
//  digitalWrite(2, LOW);
//  delay(random(1/(interval_two/10))); 
//  digitalWrite(3, HIGH);
//  delay(delay_three);
//  digitalWrite(3, LOW);
//  delay(random(1/(interval_three/10))); 
//  digitalWrite(4, HIGH);
//  delay(delay_four);
//  digitalWrite(4, LOW);
//  delay(random(1/(interval_four/10))); 
//  digitalWrite(5, HIGH);
//  delay(delay_five);
//  digitalWrite(5, LOW);
//  delay(random(1/(interval_five/10))); 
//  digitalWrite(6, HIGH);
//  delay(delay_six);
//  digitalWrite(6, LOW);
//  delay(random(1/(interval_six/10))); 
//  digitalWrite(7, HIGH);
//  delay(delay_seven);
//  digitalWrite(7, LOW);
//  delay(random(1/(interval_seven/10))); 
//  digitalWrite(8, HIGH);
//  delay(delay_eight);
//  digitalWrite(8, LOW);
//  delay(random(1/(interval_eight/10))); 

Try reading, testing and then modifying this: Demonstration code for several things at the same time - Project Guidance - Arduino Forum
Several things at one time should do what you need.

If you’re going to use Serial:


Then you can’t use the hardware serial pins (0 and 1) for your relays.

for (int i; i < 9; i++){
      pinMode(i, OUTPUT); 

You also have a huge bug in that for loop. You forgot to give i a starting value. So it will start with whatever random garbage value was left over in memory when it was created and your for loop may run anything from 0 to 9 times.

if (time % delay_one == 0){

This is not a good way to use millis for timing. If this code doesn’t run the exact millisecond that it should, then you’ll be waiting for another complete interval before it triggers again. See the Blink Without Delay example for a better method. Usually, we take the difference between the time now and the time at the beginning of some interval to get the elapsed time and compare to the required elapsed time.

Thanks! I was able to resolve the problems by re-working the Blink w/o Delay and SeveralThingsAtTheSameTime scripts.