Controlling independent systems "simultaneously"

Hello,

I’m trying to write a program where I can turn a light on and off using one switch, and independently run two solenoids using a second switch. Eventually, I want to use a switch case to enable the use of a third switch to change the sequence on the solenoids, but for now I’m just trying to test the concept. The problem is that the light control works fine, but I can’t get the solenoids to run when I hit the second switch. I understand that the Arduino can’t really do two things at once, so I’ve used millis() (although I’m still learning how to use that) and put in subroutines instead of trying to write all of my code in the main loop, but I still can’t seem to figure out what I’m doing wrong. I’m a n00b, so it’s probably something fairly elementary. Pardon my ignorance. Here is my code, if anyone might have a suggestion. I’ve tried to comment extensively and organize it well.

 //----------- CONSTANTS-----------------------

const int solenoid2 = 2; // the pin numbers for the solenoids and light
const int solenoid1 = 3;
const int light = 4;

const int switch1 = 8; // the pin number for the switches
const int switch2 = 9;
const int switch3 = 10;

const int threeInterval = 3000; //number of milliseconds for different intervals to drop a ping-pong ball
const int fourInterval = 4000;
const int sixInterval = 6000;

const int solenoidDuration = 500; // number of millisecs that solenoids are on - all three solenoids use this

const int switchInterval = 100; // number of millisecs between switch readings



//------------ VARIABLES (will change)---------------------


byte solenoid2_State = LOW;           //   LOW = off
byte solenoid1_State = LOW;
byte switch1_State = LOW;
byte switch2_State = LOW;
byte switch3_State = LOW;
byte light_State = LOW;

unsigned long currentMillis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long previous_solenoid2_Millis = 0;
unsigned long previous_solenoid1_Millis = 0;

unsigned long previous_switchMillis = 0; // time when switches last checked




//========================================

void setup() {

      // set the solenoid pins as output:
 
  pinMode(solenoid2, OUTPUT);
  pinMode(solenoid1, OUTPUT);
  pinMode(light, OUTPUT);
  
      // set the switch pins as inputs
  pinMode(switch1, INPUT);
  pinMode(switch2, INPUT);
  pinMode(switch3, INPUT);
  

 
}

//========================================

void loop() {

    

  currentMillis = millis();   // capture the latest value of millis()
                              // this is equivalent to noting the time from a clock
                            
  
  lightControl();      //function manages the light
  solenoidControl();   //function manages the solenoids
  switch_solenoids();  //function actually turns the solenoids or light on and off
 


}

//========================================

void solenoidControl(){

int switchCondition = !digitalRead(switch2);  // creates a new variable which represents the condition of switch2 (eventually both switches 2 and 3)

if (millis() - previous_switchMillis >= switchInterval) {
  
switch(switchCondition) {   //eventually will go into one of three different cases depending on switches 2 and 3
                            //the cases will vary the time between ping-pong ball drops
                            //for now just has two cases for testing
  
  case 0:
  
    digitalWrite(solenoid2, LOW);
    digitalWrite(solenoid1, LOW);
    
    break;
    
  case 1:
  
    update_solenoid2_State();
    update_solenoid1_State();
    
    break;
    
  default:
  
    digitalWrite(solenoid2, LOW);
    digitalWrite(solenoid1, LOW);
    
    break;
    }
  }
}
//========================================

void update_solenoid2_State() {
  
//this code updates solenoid2_State, depending on time elapsed
  if (solenoid2_State == LOW) {
    if (currentMillis - previous_solenoid2_Millis >= threeInterval) {
       solenoid2_State = HIGH;
       previous_solenoid2_Millis += threeInterval;
    }
  }
  else {
    if (currentMillis - previous_solenoid2_Millis >= solenoidDuration) {
       solenoid2_State = LOW;
       previous_solenoid2_Millis += solenoidDuration;
    } 
  }    
}

//========================================

void update_solenoid1_State() {
  
//this code updates solenoid1_State, depending on time elapsed  

  if (solenoid1_State == LOW) {
    if (currentMillis - previous_solenoid1_Millis >= (threeInterval)) {
       solenoid1_State = HIGH;
       previous_solenoid1_Millis += (threeInterval + 500);
    }
  }
  else {
    if (currentMillis - previous_solenoid1_Millis >= solenoidDuration) {
       solenoid1_State = LOW;
       previous_solenoid1_Millis += solenoidDuration;
    }
  }    
}

//========================================

void switch_solenoids() {
  
 // this is the code that actually switches the solenoids on and off

  digitalWrite(solenoid2, solenoid2_State);
  digitalWrite(solenoid1, solenoid1_State);
  digitalWrite(light, light_State);
}

//========================================

void lightControl() {
  
 
      // this only reads the switch state after the switch interval has elapsed
      // this avoids multiple flashes if the button bounces
      // every time the button is pressed it changes light_State causing the light to go on or off
      // Notice that there is no need to synchronize this use of millis() with the solenoids
  
  if (millis() - previous_switchMillis >= switchInterval) {

    if (!digitalRead(switch1) == HIGH) {
      light_State = HIGH; // this changes it to LOW if it was HIGH 
                                           //   and to HIGH if it was LOW
      previous_switchMillis += switchInterval;
    }
    if (!digitalRead(switch1) == LOW) {
      light_State = LOW;
      
      previous_switchMillis += switchInterval;
    }
  }

}

You have the basic idea, but it might be helpful to review the technique as described in the thread “Demonstration code for several things at the same time”.

Thanks! That's actually where I pulled the code from and then modified it for my own purposes. Anyway, I went to lunch, came back and rewrote my switch case and switchCondition variables and suddenly everything worked fine. Must have been the little green man or something.