long hold mode

Hi Im new in programming and also with Arduino. So i gave myself a first challenge to make a a button mode - long hold. I wrote that code but dont know what is wrong with it because it allll seeeemmmss soooo perfect to me :D

the point is, if you hold down the button for 2s or more the light will go HIGH, and if it is allready HIGH it will go LOW... this is the first step, later on i will try to make some doubleclick feature...

int ledpin = 2;
int buttonpin = 5;
int buttonstate = 0;
int exstate = 0;
int ledstate = 0;
int time = 0;
int time2 = 0;
int timedown = 2000;

void setup () {
pinMode(ledpin, OUTPUT);
pinMode(buttonpin, INPUT);
Serial.begin(9600);
}

void loop () {

buttonstate = digitalRead(buttonpin);
if(buttonstate == HIGH && exstate == LOW) {           //remember the time the button was pressed
time = millis();
}

if(buttonstate == HIGH && exstate == HIGH) {           //counts how long the button is down
time2 = millis();
}

if((time2 - time) > timedown) {                               //if the button is pressed for more than 2s the change in ledstate will happens
  if(ledstate == 0){
  ledstate = 1;
  }
  else{
  ledstate = 0;
  }
}

if(ledstate == 0) {
digitalWrite(ledpin, LOW);
}

if(ledstate == 1) {
digitalWrite(ledpin, HIGH);
}


exstate = buttonstate;
}

You haven't described what the program is doing that it shouldn't, or not doing that it should, so, you'll need to do that or figure it out for yourself.

If you want to figure it out for yourself (highly recommended), add Serial.print and Serial.println statements throughout the code.

Determine if the buttonstate variable changes when you press and release the button. This will tell you whether the button is wired correctly. It might not be. You provided no clues to help us determine this.

Show when the button changes from LOW to HIGH (the value in time). You will probably very quickly see that the time variable is declared using the wrong type. The millis() function returns an unsigned long, not an int.

I'dd second what PaulS has said, and say "have you got pull-up or pull-down resistors on your digital input pin? You're not using the built-in ones."

ok sorry about that post without any information, and thanks for help. with serial.println i got look into code and fix it that it work now, it was just the thing that if it went HIGH so the button was pressed for more than 2s it didnt reset the "time" and "time2" so the if(time2-time > holdtime) was running all the time, so i just made correction, whenever it assign a different state, it resets the "time" and "time2".

still there it doesnt something work good for me, and that is unsigned long for "time" and "time2". If i make only long type it works fine but with unsigned long it goes on right after pushing button... long gives me enough space for millis() but still, what is different with unsigned long?

There seems to be something in the way of your monitor. We can't see your new code now. Can you move whatever it is that is in the way?

Here is my code. Now it works all good, but i have to use long instead of unsigned long, because i dont know why, but if i make unsigned long, the led went HIGH right after pressing the button, so there is no 2000ms waiting, and also went LOW right after next click :confused:

int ledpin = 2;
int buttonpin = 5;
int buttonstate = 0;
int exstate = 0;
int ledstate = 0;
long time = 0;
long time2 = 0;
int timedown = 2000;

void setup () {
pinMode(ledpin, OUTPUT);
pinMode(buttonpin, INPUT);
Serial.begin(9600);
}

void loop () {

buttonstate = digitalRead(buttonpin);
if(buttonstate == HIGH && exstate == LOW) {
time = millis();
}

if(buttonstate == HIGH && exstate == HIGH) {
time2 = millis();
}

if((time2 - time) > timedown) {
  if(ledstate == 0){
  ledstate = 1;
  time = millis();
  time2 = millis();
  }
  
  else{
  ledstate = 0;
  time = millis();
  time2 = millis();
  }
}

if(ledstate == 0) {
digitalWrite(ledpin, LOW);
}

if(ledstate == 1) {
digitalWrite(ledpin, HIGH);
}

exstate = buttonstate;
}

What happens if you make timedown an unsigned long, too (so that all 3 time variables are the same size)?

still the same :/

There is no debouncing of the button. Try adding a small delay (10 milliseconds) when the transition from LOW to HIGH first occurs, after the time = millis(); statement.

same :/

Hi, I've tried your code. If I press the button, the led keeps blinking as long as it's pressed. Is this what you're trying to achieve ?

BTW, the button is active high.