basically trying a bit of home automation reguarding a light out side, what i want is if the button is pressed for a short period the light turns and a delay is set to turn the light out, but if the button is held for more than the delay period i want the light to turn straight out with out delay this is what ive got so far
const int SW1 = 2; //Switch 1
const int L1 = 13; // Outside light 1 sub pin 13 for now
int buttonState = 0;
void setup() {
pinMode(L1, OUTPUT);
pinMode(SW1, INPUT);
}
void loop(){
buttonState = digitalRead(SW1);
if (buttonState == HIGH){
digitalWrite(L1, HIGH);
delay(2048);
}
else if (buttonState == HIGH){
digitalWrite(L1, HIGH);
}
else {
digitalWrite(L1, LOW);
}
}
i dont understand why its not working so if someone can point me in the right direction thanks in advance
but it delays reguardless of how long the switch is held
Of course it does. Because that's what you told it to do. Nowhere do you detect that the switch is pressed now but was not before. Nowhere do you record when that happened. Nowhere do you detect that the switch is released but was not before. Nowhere do you record when that happened. Nowhere do you determine how long the switch was pressed.
if (buttonState == HIGH)
{
}
else if (buttonState == HIGH)
{
}
else
{
}
Nothing will ever cause that else if statement block to be executed. If the buttons state is HIGH, the first block will be executed. The second block can not be executed, because the case for the switch being HIGH has already been handled.
Code to deal with buttons clutters things up and makes the main logic harder to read, and differentiating short and long presses just complicates it that much more. So it's good to have the button handling code moved off into another module or to a library. The sketch below uses a library that I wrote. Note that my switch may not be wired the same way as yours. It looks like you may be using a pull-down resistor. I just wire the switch from the pin to ground and use the internal pull-up resistor.
#include <Button.h> //https://github.com/JChristensen/Button
#define BUTTON_PIN 2 //Connect a tactile button switch (or something similar)
//from Arduino pin 2 to ground.
#define PULLUP true //To keep things simple, we use the Arduino's internal pullup resistor.
#define INVERT true //Since the pullup resistor will keep the pin high unless the
//switch is closed, this is negative logic, i.e. a high state
//means the button is NOT pressed. (Assuming a normally open switch.)
#define DEBOUNCE_MS 20 //A debounce time of 20 milliseconds usually works well for tactile button switches.
#define LED_PIN 13 //The standard Arduino "Pin 13" LED.
#define LONG_PRESS 1000 //Define a "long press" to be 1000 milliseconds.
#define LED_DELAY 5 //Seconds to leave the LED on after the button press.
Button myBtn(BUTTON_PIN, PULLUP, INVERT, DEBOUNCE_MS); //Declare the button
boolean ledState; //The current LED status
unsigned long ms; //The current time from millis()
unsigned long msOn; //The time we turned the LED on
void setup(void)
{
pinMode(LED_PIN, OUTPUT); //Set the LED pin as an output
}
void loop(void)
{
ms = millis(); //record the current time
myBtn.read(); //Read the button
if (myBtn.wasReleased()) {
msOn = ms;
ledState = true;
digitalWrite(LED_PIN, HIGH);
}
else if (myBtn.pressedFor(LONG_PRESS)) {
ledState = false;
digitalWrite(LED_PIN, LOW);
while (myBtn.isPressed()) myBtn.read(); //wait for button to be released
}
if (ledState && ms - msOn >= LED_DELAY * 1000) {
ledState = false;
digitalWrite(LED_PIN, LOW);
}
}
ok guys let me put it another way, when i press the button in i want the delay to start and finish and that is it, if the button is held in i still want it to delay for the set time then turn off for instance
button pushed
delay 1 second
turn light off reguardless if button still pressed
i just cant seem to get it to work, and im sure its pretty simple ive been spending half hour a night reading arduino basics and i am sitll clueless so if someone can help and explain exactly what the arduino is doing whilst the code is running that would be apreciated
so if someone can help and explain exactly what the arduino is doing whilst the code is running that would be apreciated
It is executing one instruction after another, as fast as it can. If you tell us specifically what code you are talking about, we can provide more details.
and im sure its pretty simple
You are right. It is. Very simple.
Did you try Jack's code? What happened? How did that differ from what you wanted to have happen?
The group's crystal ball is out for cleaning this week. Last time, it took almost two years to get back. So, don't hold your breath.
Often on a project like this, all the possibilities aren't covered in the specs. I think the following fully specifies the action of the code above. Let us know if this is what you want, and whether it works that way for you.
If LED is off
a. If the button is pressed and released quickly, the LED will turn on for 5 seconds, then turn off.
b. If the button is pressed and held for at least a second, nothing happens.
If LED is on
a. If the button is pressed and released quickly, the LED will stay on for 5 more seconds, then turn off.
b. If the button is pressed and held for at least a second, the LED will turn off.
PaulS:
The group's crystal ball is out for cleaning this week. Last time, it took almost two years to get back. So, don't hold your breath.
tried jacks code it didnt work how i wished but the descriptions helped me understand how his code was executed,
switch pushed led turns on for 5 seconds and turns off even if the switch is still pushed what it is currently doing is waiting for the switch to be released then it will do the 5 second turn off delay after the switch is released
what i want to happen is 5 second light on then turn off regaurdless of switch being held
so if switch pressed led turns on for 5 seconds and turns off even if the switch is held in
spookyman60:
tried jacks code it didnt work how i wished but the descriptions helped me understand how his code was executed,
switch pushed led turns on for 5 seconds and turns off even if the switch is still pushed what it is currently doing is waiting for the switch to be released then it will do the 5 second turn off delay after the switch is released
what i want to happen is 5 second light on then turn off regaurdless of switch being held
so if switch pressed led turns on for 5 seconds and turns off even if the switch is held in
The way I read the original post was that if the button was held in for some relatively longer period it would turn the LED off.
If that is no longer a requirement, try the code below.
#include <Button.h> //https://github.com/JChristensen/Button
#define BUTTON_PIN 2 //Connect a tactile button switch (or something similar)
//from Arduino pin 2 to ground.
#define PULLUP true //To keep things simple, we use the Arduino's internal pullup resistor.
#define INVERT true //Since the pullup resistor will keep the pin high unless the
//switch is closed, this is negative logic, i.e. a high state
//means the button is NOT pressed. (Assuming a normally open switch.)
#define DEBOUNCE_MS 20 //A debounce time of 20 milliseconds usually works well for tactile button switches.
#define LED_PIN 13 //The standard Arduino "Pin 13" LED.
#define LONG_PRESS 1000 //Define a "long press" to be 1000 milliseconds.
#define LED_DELAY 5 //Seconds to leave the LED on after the button press.
Button myBtn(BUTTON_PIN, PULLUP, INVERT, DEBOUNCE_MS); //Declare the button
boolean ledState; //The current LED status
unsigned long ms; //The current time from millis()
unsigned long msOn; //The time we turned the LED on
void setup(void)
{
pinMode(LED_PIN, OUTPUT); //Set the LED pin as an output
}
void loop(void)
{
ms = millis(); //record the current time
myBtn.read(); //Read the button
if (myBtn.wasPressed()) {
msOn = ms;
ledState = true;
digitalWrite(LED_PIN, HIGH);
}
// else if (myBtn.pressedFor(LONG_PRESS)) {
// ledState = false;
// digitalWrite(LED_PIN, LOW);
// while (myBtn.isPressed()) myBtn.read(); //wait for button to be released
// }
if (ledState && ms - msOn >= LED_DELAY * 1000) {
ledState = false;
digitalWrite(LED_PIN, LOW);
}
}
I've added a few comments below that may help. Let us know if you have questions. Enjoy!
void loop(void)
{
//loop executes over and over, very rapidly
ms = millis(); //record the current time
myBtn.read(); //Read the button
if (myBtn.wasPressed()) { //was the button pressed since the last time we checked?
msOn = ms; //yes, save the time it was pressed
ledState = true; //set the LED state variable to indicate the LED is on
digitalWrite(LED_PIN, HIGH); //and turn the LED on
}
//check to see if the LED state is on (true) AND has been on for the maximum delay period
if (ledState && ms - msOn >= LED_DELAY * 1000) {
ledState = false; //if so, set the LED state variable to indicate the LED is off
digitalWrite(LED_PIN, LOW); //and turn the LED off
}
}