Hello guys, I am glad that you are visiting my topic and help me find a solution for these.
I am trying to turn on a relay in 30 second with pressing the button once. After 30 sec, I want the relay automatically off. I am using millis() function to set the time, it's ok but the problem is when I set the time for the interval, which is for instance about 5 sec, I need to keep pressing the button for 5 sec and then the program will be executed. All I want to do is pressing the button once and the program will be executed.
I really appreciate for all your help. Below is my code! Thank you so much guys!
P.s: I am new to arduino, please instruct and teach me if I do wrong code. Thank you y'all!
/*
Blink without Delay
Turns on and off a light emitting diode (LED) connected to a digital pin,
without using the delay() function. This means that other code can run at the
same time without being interrupted by the LED code.
The circuit:
- Use the onboard LED.
- Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA
and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN
is set to the correct LED pin independent of which board is used.
If you want to know what pin the on-board LED is connected to on your
Arduino model, check the Technical Specs of your board at:
https://www.arduino.cc/en/Main/Products
created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen
modified 11 Nov 2013
by Scott Fitzgerald
modified 9 Jan 2017
by Arturo Guadalupi
This example code is in the public domain.
https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
*/
// constants won't change. Used here to set a pin number:
const int ledPin = LED_BUILTIN; // the number of the LED pin
const int button = 2;
// Variables will change:
int ledState = LOW; // ledState used to set the LED
int buttonstate = 0;
int lastbuttonstate = 0;
int lastledstate = 0;
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change:
const long interval = 5000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
pinMode(button, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the difference
// between the current time and last time you blinked the LED is bigger than
// the interval at which you want to blink the LED.
buttonstate = digitalRead(button);
if (buttonstate == LOW)
{
digitalWrite(button,HIGH);
Serial.println("Button is pressed");
delay(50);
}
else
{
//digitalWrite(button,LOW);
Serial.println("Button is not pressed yet");
Serial.println(lastbuttonstate); // read the current state of button
delay(50);
}
lastbuttonstate = buttonstate;
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 (ledState == LOW && buttonstate == LOW) {
ledState = HIGH;
}
else
{
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
Serial.println(lastledstate);
delay(50);
}
lastledstate = ledState;
}
Basically, every time that you read the state of the input you compare it with what it was last time that you read it. So, before reading it again you save the last button state in a variable with a meaningful name
If the current button state does not equal the last button state then the state has changed. In your sketch if the state is now LOW then the button has become pressed
Consider the wording of "becomes pressed" and "was pressed" meaning the same.
"was pressed" is in the past, so you keep track of the time the event occurred. "is pressed" is the present, and does not need to be recorded unless you want to know if the button "was pressed."
The timing in "blink without delay" is like a timed auto race where you have a start time and lap (split, interval) times. Every debounce is waiting for a particular lap/split/interval time.
/*
* Created by ArduinoGetStarted.com
*
* This example code is in the public domain
*
* Tutorial page: https://arduinogetstarted.com/tutorials/arduino-button-pump
*/
#include <ezButton.h> // include ezButton library
#include <ezOutput.h> // include ezOutput library
ezOutput pump(A5); // create ezOutput object attached to pin A5
ezButton button(12); // create ezButton object attached to pin 12
void setup() {
Serial.begin(9600);
button.setDebounceTime(50); // set debounce time to 50 milliseconds
pump.low(); // turn pump off
}
void loop() {
pump.loop(); // MUST call the loop() function first
button.loop(); // MUST call the loop() function first
if (button.isPressed()) {
Serial.println("Pump is started");
pump.low();
pump.pulse(30000); // turn on for 30000 milliseconds ~ 30 seconds
// after 10 seconds, pump will be turned off by pump.loop() function
}
}
Looks plausible. Have you used the wokwi simulator? It's easy to pop something like this in there and try it. I would but it don't work so well on the tablet here where I am.
Avoid raising questions around timing by using
unsigned long timing = 0;
variables. It probably wouldn't make a difference here, but I'd rather not need to look into and have to think about it at all.
Never mind. Sry sry sry. Reading too fast, recognizing patterns that were not there!
I did put your code into the wokwi, but by the time I had it working it had morphed into the way I would have done it, by which point I finally understood how you did it.
You count off 500 increments of 60 milliseconds. I will assume the code works, and the variable types don't matter so much.
Naturally I prefer the way I did it (!), but one advantage mine has is that the timed interval is explicit, expressed directly in milliseconds in a manifest constant.
So sry again. I think maybe a comment and another manifest constant would make it clearer
const int tick = 60; // milliseconds per unit of timing
const long interval = 500; // 500 * 60, 30000 milliseconds (30 seconds)
const int PB_1 = 2; // Button1
const int RLY_1 = 13; //relay 1
//VARIABLES
int buttonState1 = 0;
// current state of the button
bool relay1 = false;
i
//MILLIS
unsigned long previousMillis1 = 0;
const unsigned long interval1 = 5000;
void setup()
{
pinMode(PB_1, INPUT);
digitalWrite(PB_1, HIGH); // pull-up
pinMode(RLY_1, OUTPUT);
digitalWrite(RLY_1, LOW);
Serial.begin(9600);
}
void loop(){
// read the pushbutton input pin:
buttonState1 = digitalRead(PB_1);
unsigned long currentMillis = millis();
// if button is pressed, turn relay on (if it wasn't already on), and reset the timer
if( buttonState1==HIGH ) // no need to check for previous state, in this specific case
{
previousMillis1 = currentMillis;
digitalWrite(RLY_1, HIGH);
relay1 = true;
}
if( relay1 )
{
// turn red led on, if close to turning off the relay
// if enough time has elapsed, turn of the relay
if (currentMillis - previousMillis1 >= interval1)
{
// .. turn of relay
digitalWrite(RLY_1, LOW);
relay1 = false;
}
}
}
Here is the code, I read all of your advices and I really appreciate that
hmm, I tried hold the button down for 15 seconds. The relay will on as the time I hold the button down, after that I release the button, the timer start to count and off for 5 seconds.
I would expect the relay to be on whilst you hold the button down then, when it is released, for it to stay on for 5 seconds before turning off. Is that what you are describing ?
NOTE most relay modules are active LOW, ie they turn on when their input goes LOW. Your code sets the RLY_1 pin HIGH when the button is pressed so could actually be turning the relay off at that point.
Your code in post #14 turns the relay on. When the button is pressed for five seconds, the relay is turned off. When the button is released, the relay turns on.
I'm not good at english, sorry about that. It is what exactly I'm describing. I'm using led pin13 instead of the relay. So I will try with the relay and post the result later.