Hi I'm fairly new to arduino and needed some advice:
I am working on a project where I am using a button to perform a certain function depending on how long it has been pressed for, the following are the steps i want performed;
If button pressed I want LED to turn ON and a timer to begin as soon as the button is pressed
Given time interval, if the button is press time exceeds the interval, I want to print out holding.
When button is released at any moment, the LED should turn OFF.
The code I've written works but it seems like after the first two button presses exceeding 20 seconds, it takes a longer time than 20 seconds to output holding the next time around and that time increases with each time the button is held. What could I be doing wrong? Here is my code:
const int button1Pin = 2; // pushbutton 1 pin
const int ledPin = 13; // LED pin
unsigned long timeInterval = 20000; //20 secs
unsigned long beginTime;
void setup()
{
Serial.begin(9600);
// Set up the pushbutton pins to be an input:
pinMode(button1Pin, INPUT);
pinMode(button2Pin, INPUT);
// Set up the LED pin to be an output:
pinMode(ledPin, OUTPUT);
}
void loop()
{
int button1State, button2State; // variables to hold the pushbutton states
If i wanted to extend this to n buttons and n led's would i just need to keep replicating the two if statement conditions for those buttons and leds similar to the first button/led pair?
If i wanted to extend this to n buttons and n led's would i just need to keep replicating the two if statement conditions for those buttons and leds similar to the first button/led pair?
Only if you want to produce turgid and not learn how to program properly.
I tried this but it did not work, I held the button for over a minute and should have received the response after 20 seconds but I didn't. Not sure what's wrong now. I feel like adding the timeInterval to beginTime will never make millis() greater because beginTime is set to millis().
I feel like adding the timeInterval to beginTime will never make millis() greater because beginTime is set to millis().
Then that is what is wrong. The variable beginTime MUST be set to be equal to millis() when the LOW is FIRST DETECTED on the switch.
Keep a track of the last state of the switch in a global variable and the first detection is when the current state of the switch is low AND the last state was high.
Make the last thing you do in the loop an assignment of the current switch state to the last switch state variable.
This is known as a state change detector and an example is given in the examples section of the IDE.
HINT:- When testing go for shorter time delays, say three seconds, to speed things up. Once it is working then extend the times to the length you want.
I did set beginTime equal to millis(), I'm still not sure why I can't get it to do as initially thought out. The second if statement is not working because i do not get the output of the "holding" in the serial monitor after the specified time that was past.
And what do you mean by keep track of the state, why would i need to do that?
Thanks a lot for your help and staying patient with me!
I'm still not sure why I can't get it to do as initially thought out.
Because you thought it out wrong. Begin time is set to millis every time in the loop when button1State is LOW.
So later on when you ask
if((beginTime >= timeInterval) && (button1State == LOW))
This is always true once millis has exceeded the fixed value in timeInterval, because millis never resets back to zero, well not for about 48 days anyway, so it constantly prints out holding.
And what do you mean by keep track of the state,
At the end of the loop make a copy of button1State in another variable called say lastButton1State
why would i need to do that?
To see if their has been a change in the button state since last time, so you can detect an edge, when the button has become pressed and not just a level, is the button currently being held down.
I suggest printing the values of beginTime, timeInterval, etc. in the Serial monitor so you can understand the problem more. You also need to come up with formulas as millis() does not reset. Formula/s to get the 20 seconds button satisfied.
I have tried every variation of writing the code but did not get the outcome i desired. I came across this code in the forum that does exactly what I want but i can't seem to figure how it differed from what I came up with. The code is the following:
int ledPin = 13;
int buttonPin = 2;
int firsttime = 1;
unsigned long startTime;
unsigned long pressTime;
Can anyone explain to me what I was doing wrong compared to the code above (what is the purpose of frsttime variable)? Also if I wanted to apply the same loop to another button, would I need to repeat the code or is there a more efficient way to do that? And if anyone can also to tell me how i can display the Serial.println("holding") only once when the if statement is satisfied(If i used an lcd i don't want the print to appear continuously, but only once)
I was able to serial print only once out of the loop by using a flag, thanks for the help!
How do you recommend I go about applying the same function in the same program to another pair of switch/led and eventually extend it to n number of switch/led pairs.
larryd:
firsttime is a flag.
When it is set i.e. 1, you lock in the start time which subsequently is used in the calculations.
Suggest you use a name like firstTimeFlag.
BTW
Use CTRL T to format the sketch.
Please use code tags.
Use the </> icon in the posting menu.
[code] Paste sketch here. [/code]
I am sure if you think about it a bit, you can figure out how to control printing the way you need.
Here is the current working code that prints only once after every time the loop is satisfied. Again, I want to extend this program to using another pair of switch/led with the same functionality in the same program. Thanks for your patience with me.
Yes, my initial thought was to repeat the code but I thought there might be an easier and shorter way to accomplish this. I will be adding to my sketch to perform other functions with other buttons and don't really want the code to bulk up if there is a way to prevent it.
but I thought there might be an easier and shorter way to accomplish this
Their is, it is to use an array for each variable and then run the code in a for loop, taking one iteration of the loop for each function. You can extend the whole thing to virtually any number of functions without making the code any longer.