Your while loops and delays are blocking everything else. Take a look at the Blink Without Delay example and the following guides:
http://forum.arduino.cc/index.php?topic=503368.0
http://forum.arduino.cc/index.php?topic=223286.0
Once you understand that, you can make abstraction of the concept and put it inside a class. This is especially useful if you need the same code multiple times (e.g. for your three loads).
class TimerOutput {
public:
TimerOutput(uint8_t pin)
: pin(pin) {
pinMode(pin, OUTPUT); // Set the pin as a digital output
}
void turnOff() {
digitalWrite(pin, LOW); // Turn off the output
timerActive = false; // Disable the timer
}
void turnOn() {
digitalWrite(pin, HIGH); // Turn on the output
timerActive = false; // Disable the timer
}
void turnOnFor(unsigned long duration) {
digitalWrite(pin, HIGH); // Turn on the output
timerActive = true; // Enable the timer
startOnTime = millis(); // Remember the current time
onDuration = duration; // Remember how long it has to stay on
}
void refresh() {
if (timerActive // If the timer is running,
&& (millis() - startOnTime >= onDuration)) { // and the output has been on for the desired duration or longer
turnOff(); // Turn it off
}
}
private:
const uint8_t pin;
bool timerActive = false;
unsigned long startOnTime;
unsigned long onDuration;
};
/* ----------------------------------------------------------------------------------------------------------------------- */
class PushButton {
public:
PushButton(uint8_t pin)
: pin(pin) {
pinMode(pin, INPUT_PULLUP); // Set the pin as a digital input, and enable the internal pull-up resistor
}
bool isFalling() { // Returns true if the input pin's state goes from high to low (i.e. if the button is pressed)
bool currentState = digitalRead(pin); // Read the button state
bool falling = false;
if (previousState != currentState) { // If the state changed since last time
if (currentState == LOW) { // If the current state is low
falling = true; // The input is low now, and it was high before, so it was falling
}
previousState = currentState; // Remember the current state
}
return falling;
}
private:
const uint8_t pin;
bool previousState = HIGH;
};
/* ----------------------------------------------------------------------------------------------------------------------- */
TimerOutput led_A = { 2 }; // Initialize a TimerOutput object called 'led_A' on digital pin 2
TimerOutput led_B = { 3 };
TimerOutput led_C = { 4 };
PushButton button_A = { 9 };
PushButton button_B = { 10 };
PushButton button_C = { 11 };
void setup() {}
void loop() {
if (button_A.isFalling()) { // If the first button is pressed
led_A.turnOnFor(3000); // Turn on the first LED for 3 seconds
}
if (button_B.isFalling()) {
led_B.turnOnFor(3000);
}
if (button_C.isFalling()) {
led_C.turnOnFor(3000);
}
led_A.refresh(); // Refresh the first LED
led_B.refresh();
led_C.refresh();
}
As you can see, this code doesn't use any while loops or delays.
Pieter