Go Down

Topic: Press button action. And press and hold button action (Read 603 times) previous topic - next topic

chadpriddle

Sep 24, 2011, 11:09 pm Last Edit: Sep 24, 2011, 11:12 pm by chadpriddle Reason: 1
I'm creating a simple program that just handles 2 keystrokes on the keyboard with the press of the same button.

I want the a keystroke for when the button is just pressed and I want a different keystroke for when the button is pressed and held for 5 seconds.

Code: [Select]
void setup() {
  Serial.begin(9600);
  pinMode(10, INPUT_PULLUP);
  delay(4000);
}

void loop() {
  if (digitalRead(10) == HIGH) {
    Keyboard.print("Button Held For 5 Seconds");
    delay(5000);
  } else {
    Keyboard.print("Button Presses Once");
    delay(1000);
  }
  delay(10);
}


I've looked on the forums and can't find anything simple like this. My only other solution is to have 2 separate buttons but id' like to stick with only one.

Thanks in advanced

olikraus

#1
Sep 24, 2011, 11:36 pm Last Edit: Sep 24, 2011, 11:40 pm by olikraus Reason: 1
1. Do not use delay()
2. Learn to construct state machines

How can i teach you to create a state machine? There are many resources on the web, maybe this one:
http://www.splatco.com/fsm_tute/fsm_tute01.htm
I also have my own tutorial online:
http://code.google.com/p/m2tklib/wiki/t05


Let me try to make a small tutorial with your example:
a) identify the inputs
--> button, values are pressed and not pressed
--> additionally we need a timer and a signal for this timer: target time reached
b) identify the outputs
--> action 1 and 2
--> and for the timer: start timer (calculate target time)
c) identify the states

State 1: button not pressed, wait for button pressed
State 2: button is pressed, but target time not reached AND button is still pressed
State 3: button is not pressed and target time has not been reached --> action 1, goto State A
State 4: button is not pressed and target time has been reached --> action 2, goto State B

Exercise: Use a paper and draw the four states. Use a circle or box to represent the state.
Draw arrows for all possible state changes. Next to the arrows write the condition for which the state change can occur.
Example:
State 1  ----- button is pressed ------> State 2

Finally do the implementation

Code: [Select]
int state = 1;
...
switch(state) {
  case 1:
    if ( /* button is pressed */ )
    {
      state = 2;
      target_time = millis() + 5000;
    }
    break;
  ...
}


Got the idea? Maybe you can share your state machine with us.

Oliver



naweston

chadpriddle -

I am just begging my first project using arduino as well. My project is very similar to yours, though mine is a tad bit simpler. I am super new at this but here is what I am wanting to code for.

4 button momentary footswitch wired to Teensy board.

Button 1 pressed --> sends KEY_ENTER

Button 2 pressed --> sends KEY_SPACE

Button 3 pressed --> sends KEY_UP

Button 4 pressed --> sends KEY_DOWN


I am lost as to where to being: assigning pins and action states, etc. SUPER NEWB!

a.d

To the original poster - http://jmsarduino.blogspot.com/2009/05/click-for-press-and-hold-for-b.html

chadpriddle

Thanks for the replies! I followed the link and was able to customize it to my application:

Code: [Select]
#define buttonPin 10 // analog input pin to use as a digital input

#define debounce 20 // ms debounce period to prevent flickering when pressing or releasing the button
#define holdTime 1500 // ms hold period: how long to wait for press+hold event

// Button variables
int buttonVal = 0; // value read from button
int buttonLast = 0; // buffered value of the button's previous state
long btnDnTime; // time the button was pressed down
long btnUpTime; // time the button was released
boolean ignoreUp = false; // whether to ignore the button release because the click+hold was triggered

//=================================================


void setup()
{

// Set button input pin
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH );
}


//=================================================


void loop()
{

// Read the state of the button
buttonVal = digitalRead(buttonPin);

// Test for button pressed and store the down time
if (buttonVal == LOW && buttonLast == HIGH && (millis() - btnUpTime) > long(debounce))
{
btnDnTime = millis();
}

// Test for button release and store the up time
if (buttonVal == HIGH && buttonLast == LOW && (millis() - btnDnTime) > long(debounce))
{
if (ignoreUp == false) event1();
else ignoreUp = false;
btnUpTime = millis();
}

// Test for button held down for longer than the hold time
if (buttonVal == LOW && (millis() - btnDnTime) > long(holdTime))
{
event2();
ignoreUp = true;
btnDnTime = millis();
}

buttonLast = buttonVal;

}


//=================================================
// Events to trigger by click and press+hold

void event1()
{

Keyboard.print(" "); // pressed once
delay(1000);
}

void event2()
{
Keyboard.set_key1(KEY_ESC); // pressed and held
Keyboard.send_now();

Keyboard.set_key1(0);
Keyboard.send_now();
delay(1000);
}



Go Up