Button-LongPress-ShortPress

this code works very well, but I need a small change:

//////////////////////////////////////////////////////////////////////////////
// Arduino button tutorial 3.
//
// Demonstrates:
// - detection of releasing edge and deglitching
// - state variables for iterative update call
// - distinction of short press and long press
//
// Push-button must be connected as follows:
//              __,__
//   Pin2 ------o   o------ GND
//
// (C) 2011 By P. Bauermeister
// This example code is in the public domain.
//////////////////////////////////////////////////////////////////////////////

// Adapt these to your board and application timings:

#define BUTTON_PIN        2  // Button

#define LONGPRESS_LEN    25  // Min nr of loops for a long press
#define DELAY            20  // Delay per loop in ms

//////////////////////////////////////////////////////////////////////////////

enum { EV_NONE=0, EV_SHORTPRESS, EV_LONGPRESS };

boolean button_was_pressed; // previous state
int button_pressed_counter; // press running duration

void setup()
{
  pinMode(BUTTON_PIN, INPUT);
  digitalWrite(BUTTON_PIN, HIGH); // pull-up
  Serial.begin(9600);
  button_was_pressed = false;
  button_pressed_counter = 0;
}

int handle_button()
{
  int event;
  int button_now_pressed = !digitalRead(BUTTON_PIN); // pin low -> pressed

  if (!button_now_pressed && button_was_pressed) {
    if (button_pressed_counter < LONGPRESS_LEN)
      event = EV_SHORTPRESS;
    else
      event = EV_LONGPRESS;
  }
  else
    event = EV_NONE;

  if (button_now_pressed)
    ++button_pressed_counter;
  else
    button_pressed_counter = 0;

  button_was_pressed = button_now_pressed;
  return event;
}

void loop()
{
  // handle button
  boolean event = handle_button();

  // do other things
  switch (event) {
    case EV_NONE:
      Serial.print(".");
      break;
    case EV_SHORTPRESS:
      Serial.print("S");
      break;
    case EV_LONGPRESS:
      Serial.print("L");
      break;
  }

  // add newline sometimes
  static int counter = 0;
  if ((++counter & 0x3f) == 0)
    Serial.println();

  delay(DELAY);
}

with this code,
when you ‘short press’ it, it will ‘Serial.print(“S”)’ only ones, (when the button is released), if released before set time.
and
when you ‘long press’ it, it will ‘Serial.print(“L”)’ only ones, (when the button is released), if released after set time.

what must be changed

basically…
if I press the button and release it before set time, it must ‘Serial.print(“S”)’ and flash LED ones (this part is all good for me)
but…
if I press the button and hold , it must '‘Serial.print(temperature)’ continuously after set time, and until I release the button.

Your sample code is far too complicated for what you want to do. Think of it as responding to a button push. When you press the button, start you timer. Then you gave two conditions, either the button is released before a set time, in which case flash the LED, or the button is still depressed in which case print your temp WHILE the button is still depressed.

I would re-write that advice slightly to say "print your temp IF the button is still depressed."

Fair enough.

  static int counter = 0;
  if ((counter++ &0x3f) == 0)
    Serial.println();

Does anyone knows how this works?

GrOnThOs:

  static int counter = 0;

if ((counter++ &0x3f) == 0)
    Serial.println();



Does anyone knows how this works?

What does this have to do with the thread?

hi, thanx all.
here is what I came up with, it seems like it is doing what I want
and is a bit simpler, what do yo think?

#define BUTTON_PIN        3  // Button
#define LONGPRESS_LEN    25  // Min nr of loops for a long press
#define DELAY            20  // Delay per loop in ms

boolean button_was_pressed; // previous state
int button_pressed_counter; // press running duration


void setup()
{
  pinMode(BUTTON_PIN, INPUT);
  digitalWrite(BUTTON_PIN, HIGH); // pull-up
  Serial.begin(9600);
  button_was_pressed = false;
  button_pressed_counter = 0;
}

int handle_button()
{
  int event;
  int button_now_pressed = !digitalRead(BUTTON_PIN); // pin low -> pressed

  if (!button_now_pressed && button_was_pressed) {
    if (button_pressed_counter < LONGPRESS_LEN)
      Serial.print("Short ");
  }
  
  if (button_now_pressed)
    ++button_pressed_counter;
  else
    button_pressed_counter = 0;

  button_was_pressed = button_now_pressed;
  return event;
}


void loop()
{
  // handle button
  boolean event = handle_button();

 if (button_pressed_counter > LONGPRESS_LEN*5)
      Serial.println("Long");

  delay(DELAY);

}

GrOnThOs:
static int counter = 0;
if ((counter++ &0x3f) == 0)
Serial.println();]

it makes 63 Hexadecimal, counts then goes to a new line (or something like that)

well, I dont know what I am doing, but here is my full code with a long/short button included:

#include <C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\EEPROM.h> //(for me) 
#include "DigiKeyboard.h"                                // for debug (no serial.print on ATtiny85)
int counter = 0;
const byte  LM35Pin = A1;
const byte LED2 = 1;
const byte button = 0;
const float EMA_alpha = 0.3;  
boolean TemperatureInRange = false;//initialization of EMA alpha
float FilteredTemperature = readTemp();                                              //set EMA S for t=1
float Setpoint;                                                                   // Desired temperature
float readTemp()                                        // get the temperature and convert it to celsius
{
  return analogRead(LM35Pin) * 0.48828125;
}
boolean PrintButtonLP = false;
boolean SetButtonSP = false;
boolean buttonActive = false;
boolean longPressActive = false;
long buttonTimer = 0;
long longPressTime = 5000;
void setup() {
  pinMode(LED2, OUTPUT);
  pinMode(button, INPUT);
  Setpoint = EEPROM.get(1, Setpoint);                                  // read the settemp on the eeprom
  FilteredTemperature = readTemp();                                                  //set EMA S for t=1
  digitalWrite(LED2, HIGH);                                                        // flash once (ready)
  delay(500);
  digitalWrite(LED2, LOW);
  if (PrintButtonLP==true)
  {
  digitalWrite(LED2, HIGH);                      
  }
}
void loop() 
{
  if (digitalRead(button) == HIGH) 
  {
    if (buttonActive == false) 
    {
      buttonActive = true;
      buttonTimer = millis();
    }
     if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) 
     {
      longPressActive = true;
      PrintButtonLP = !PrintButtonLP;
     }
   } else {
     if (buttonActive == true) 
     {
      if (longPressActive == true) 
      {
        longPressActive = false;
        //delay(25);
    } else {
        SetButtonSP = !SetButtonSP;
      }
      buttonActive = false;
     }
  }
{
  float temperature = readTemp();
  FilteredTemperature = (EMA_alpha * temperature) + ((1 - EMA_alpha) * FilteredTemperature);//run the EMA
  if (PrintButtonLP==false)
  {
  delay(500);
  }
  if (PrintButtonLP==true)
  {
   DigiKeyboard.print("      ");
   DigiKeyboard.print(temperature); //real temp
   DigiKeyboard.print("   ");
   DigiKeyboard.println(FilteredTemperature); 
     
   //filtered
  }
   if (SetButtonSP==true)                                                            // chk settemp swtch
   {
     Setpoint = FilteredTemperature;                                        // set current temp to eeprom
     EEPROM.put (1, Setpoint);
     digitalWrite(LED2, HIGH);                                 // flash once (current temp set to eeprom)
     delay(2000);
     //???digitalWrite(LED2, LOW);
     digitalWrite(LED2, SetButtonSP = false);
     if (PrintButtonLP==true)
     {
       DigiKeyboard.println(" set; ");         // (serial.print when 'settemp to eeprom' for ATtiny85)
     }
   }
  if (FilteredTemperature < Setpoint + 10.0)
  {
    if (!TemperatureInRange)
    {
      // Temperature newly in range
      digitalWrite(LED2, LOW);
      TemperatureInRange = true;
    }
  } else {
    if (TemperatureInRange) 
    {
      // Temperature is newly out of range
      TemperatureInRange = false;
      digitalWrite(LED2, HIGH);                   // 2 x flash once only (when 'settemp minus 10 deg')
      if (PrintButtonLP==true)
      {
        DigiKeyboard.println(" alarm; "); // (serial.print when 'settemp minus 10deg' for ATtiny85)
     }
    } else {
  }
  }
  if ( (FilteredTemperature > Setpoint - 10.0) && (counter < 1) )                   // Too low by 10.0°C
  {
     digitalWrite(LED2, HIGH);                       // 2 x flash once only (when 'settemp minus 10 deg')
     delay(250);
     digitalWrite(LED2, LOW);
     delay(250);
     if (PrintButtonLP==true)
    {
     DigiKeyboard.println(" test; ");      // (serial.print when 'settemp minus 10deg' for ATtiny85)
    }
     counter++;
  }
}
}

it only just fits on a Digispark ATtiny85 but it works

There is a neat system for different button presses in this link.

...R

Mr. Gammon has written a very simple switch library discussed here:

SwitchManager