Hello this is my project
3 PushButtons
3 Realys
3 Pumps
Every button is connected to the Relay and the relay starts the Pump
When I push the button1 Relay1 is ON and Pump1 is ON after delay time of 4 sec. Pump 1 is OFF
Because I use delay during this 4 sec. my other Buttons 2,3 (Pumps2, 3) are not functional. When the delay finish then my other Buttons/Pumps are functional.
I need to make them to be functional whenever I press the button (during delay)
I know that this is because I use delay (everything is on hold) but I don't know how to make this to work without delay ...because in my real project I need the pump to work maybe 2min. and during this 2min. other pumps are not functional but I need them to be.
Probably I will need to use "currentMillis - previousMillis >= OnTime" but I dont know how... please can someone help me Project Link
#define buttonP1 5 //Button1
#define buttonP2 6 //Button2
#define buttonP3 7 //Button3
#define relayR1 9 // Pump1
#define relayR2 10 //Pump2
#define relayR3 11 //Pump3
void setup() {
Serial.begin(9600);
// put your setup code here, to run once:
// Activating the digital pins pull up resistors
pinMode(buttonP1, INPUT_PULLUP);
pinMode(buttonP2, INPUT_PULLUP);
pinMode(buttonP3, INPUT_PULLUP);
pinMode(relayR1, OUTPUT);
pinMode(relayR2, OUTPUT);
pinMode(relayR3, OUTPUT);
}
void loop() {
// if button is pressed
//Pump1 ON
if (digitalRead(buttonP1) == LOW) {
delay(500);
digitalWrite(relayR1, HIGH);
Serial.print("P1 ON: ");
delay(4000);
//Pump1 Off
digitalWrite(relayR1, LOW);
Serial.println("P1 OFF");
}
else if (digitalRead(buttonP2) == LOW) {
digitalWrite(relayR2, HIGH);
Serial.print("P2 ON: ");
delay(4000);
digitalWrite(relayR2, LOW);
Serial.println("P2 OFF");
}
else if (digitalRead(buttonP3) == LOW) {
digitalWrite(relayR3, HIGH);
Serial.print("P3 ON: ");
delay(4000);
digitalWrite(relayR3, LOW);
Serial.println("P3 OFF");
}
}
thank you but this is very hard code for me... Im a begginer
here is What I did so far... and Button1 is working... but I need to correct other buttons to do the same... fill free to give me sugestions
#define buttonP1 5 //Button1
#define buttonP2 6 //Button2
#define buttonP3 7 //Button3
#define relayR1 9 // Pump1
#define relayR2 10 //Pump2
#define relayR3 11 //Pump3
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 4000; //the value is a number of milliseconds
void setup() {
Serial.begin(9600);
// put your setup code here, to run once:
// Activating the digital pins pull up resistors
pinMode(buttonP1, INPUT_PULLUP);
pinMode(buttonP2, INPUT_PULLUP);
pinMode(buttonP3, INPUT_PULLUP);
pinMode(relayR1, OUTPUT);
pinMode(relayR2, OUTPUT);
pinMode(relayR3, OUTPUT);
startMillis = millis(); //initial start time
}
void loop() {
currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started)
// if button is pressed
//Pump1 ON
if (digitalRead(buttonP1) == LOW) {
digitalWrite(relayR1, HIGH);
Serial.print("P1 ON: ");
delay(500);
}
if (currentMillis - startMillis >= period) { //test whether the period has elapsed
digitalWrite(relayR1, LOW);
Serial.println("P1 OFF"); //if so, change the state of the LED. Uses a neat trick to change the state
startMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
Serial.println(startMillis);
}
else if (digitalRead(buttonP2) == LOW) {
digitalWrite(relayR2, HIGH);
Serial.print("P2 ON: ");
delay(500);
}
if (currentMillis - startMillis >= period) { //test whether the period has elapsed
digitalWrite(relayR2, LOW);
Serial.println("P2 OFF");
startMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
else if (digitalRead(buttonP3) == LOW) {
digitalWrite(relayR3, HIGH);
Serial.print("P3 ON: ");
delay(500);
}
if (currentMillis - startMillis >= period) { //test whether the period has elapsed
digitalWrite(relayR3, LOW);
Serial.println("P3 OFF");
startMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}
arrays are a very basic programming concept that allow an index to refer to a value that is needed multiple times, for example, your button and relay pins.
the following code not only works for one button/relay but as many as are described with value in the arrays
at the top of the code all the variables are captured in arrays. Some arrays have initialized values such as the button and relay pinss, the amount of delay in MsecPeriod and the label array hold a text string descibing the relay
but two other arrays are needed, msecRelay[] holds the timestamp of when the relay was captured and tmr [] indicates whether the timer is enabled
additional values can initialize, for example
const byte PinBut [] = { 5, 6, 7 };
the size of the array, the # of pins can be figured out by the processor using sizeof() which returns the # of bytes in the array
the timer is enabled when tmr [n] is true. When it's enabled, if the time since the relay was turned on and a timestatamp capture exceeds the delay period, MsecPeriod
the timer is disable, false, the relay turned off and there is a print indicating which relay is being turned off
i hope the description helps you understand what is needed to use millis(). Presumably seeing it in code is easier that reading about how to do it
Maybe it's alittle bit more simple with a library. This is an example of the MobaTools library. It does nearly exactly the same as you wish, but with (only 2) leds:
#include <MobaTools.h>
/* Demo: non blocking timers without delay()
* In principle, the 'MoToTimer' works like a kitchen timer.
* You wind it up to a certain time and then it runs back to 0.
* Unlike the kitchen alarm clock, however, it does not ring.
* You have to check cyclically to see if the time has expired. But that fits
* perfectly with the principle of the 'loop', i.e. a cyclical query in an endless loop.
* Function calls:
* MoToTimer.setTime( long Laufzeit ); sets the time in ms
* bool = MoToTimer.running(); == true as long as the time is still running,
* bool = MoToTimer.expired(); This call returns true only once if the time has expired
* succeding calls will return 'false' again.
*
* In this demo, 2 leds are switched on with one button each for different times.
* At each expiry of the time, a message is output once on the serial monitor.
* The buttons must be connected between the pin and Gnd
*/
const byte led1P = 5;
const byte led2P = 6;
const byte button1Pin = A0;
const byte button2Pin = A1;
MoToTimer timer1;
MoToTimer timer2;
void setup() {
Serial.begin(115200);
while (!Serial); // only needed for Arduino Micro/Leonardo
pinMode(led1P, OUTPUT);
pinMode(led2P, OUTPUT);
pinMode(button1Pin, INPUT_PULLUP );
pinMode(button2Pin, INPUT_PULLUP );
}
void loop() {
// -------- switching the first led ------------------
if ( !digitalRead(button1Pin) && !timer1.running() ) {
Serial.println("start first timer");
// Switch led on and start timer
timer1.setTime( 2000 );
digitalWrite( led1P, HIGH );
}
if ( timer1.expired() ) {
Serial.println("first timer expired");
digitalWrite( led1P, LOW );
}
// -------- switching the second led ------------------
if ( !digitalRead(button2Pin) && !timer2.running() ) {
// Switch led on and start timer
Serial.println("start second timer");
timer2.setTime( 1500 );
digitalWrite( led2P, HIGH );
}
if ( timer2.expired() ) {
Serial.println("second timer expired");
digitalWrite( led2P, LOW );
}
}
Yes. I was going to de-arrayize @gcjr's sketch and give it some 21st century style adjustments just to present the essential logic steps w/o the complexity of arrays and industrial certified programming.
if the button is pressed turn on the relay and start a timer
if (when!)the timer expires turn off the relay
where "start a timer" means make note of what time it is ("capture a timestamp") which is just putting the value of millis() into an appropriate variable and
expiring means checking to see if that time had receded into the past, that is to say the elapsed time is greater then the time the relay shoukd be on.
We often skip making that explicit, viz:
unsigned long elapsedTime = now - whenWeStarted;
if (elapsedTime > 4000) digitalWrite(theRelayPin, OFF);
which assumes a now that is the current value of millis() and OFF defined
# define OFF HIGH
to accommodate a module that might want LOW to be OFF.
I'd have to look closer than I dare to be sure, but it looks like the relay will be on for a time after the switch is not being pressed anymore; a slightly more sophisticated approach to the button handling would start that time immediately the switch becomes prsssed. I have not read @MicroBahner's solution yet, I am betting it does that.
BTW and FWIW, @MicroBahner's stuff in it somewhere has a perfectly wonderful button handler thing, just a shoutout here to say thx and well done, too well hidden.