Long and Shortpress during interrupt

Hello,
i need help with my code. So i have two buttons one should increment the other decrement. If I hold one of them it should increment or decrement the parameter every second by 10. If i press it once it should just increment or decrement by 1.

The Problem behind this is that i have to do this with Interrupts. If i click the Button the interrupt is called with attachInterrupt and i am only allowed to programm the code for long and short press in the interrupt function.

i really have no idea how this is possible to do i am trying since many hours....

Wire your buttons from the pin, to the button, to ground and use INPUT_PULLUP. This will give a LOW with a PRESSED button and a HIGH with NOT PRESSED button.

You will want to detect FALLING edge (NOT pressed to PRESSED) and RISING edge (PRESSED to NOT pressed) on the interrupts.

yes i already did all of this, my problem is just to implement the code for short press and long press in the interrupt
my biggest problem ist the long press. I dont know how to do this with millis (i have to do it with millis())

Save the value of millis() when the button becomes pressed. Save the value of millis() when the button becomes released and subtract the pressed time from the released time.

If the result exceeds what you regard as a long press then a long press has occured

1 Like

You should learn to explain your issue so effort is not wasted on parts you "already did."

i said i need help with the code not wiring

What code?

1 Like

Buttons don't need interrupts. Interrupts are for fast signals; buttons are slow signals and nobody cares if your button press is detected now or 10 milliseconds later.

You might be trying to solve a problem that should not be a problem. What is your use case?

2 Likes

its a task from my prof haha

we have to use this

void setup() {
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(2), upKeyPressed, RISING);
attachInterrupt(digitalPinToInterrupt(3), downKeyPressed, RISING);
sei();
}
and write the code in upKeyPressed and downKeyPressed, increment and decrement the int parameter by 10 for longpress and 1 for shortpress

None will use interrupt business to code button handler.

With best regards.

i am studying right now and my prof wants us to do this as a practice :sweat_smile:

I don't think that's ever going to work.

If you want/need to program a button to distinguish between a long press and a short press, the interrupt will have to be triggered on the falling as well as the rising edge of the pin. Otherwise the microcontroller will only know when the button was pressed, or released, but not both. And you need to know both.

1 Like

You showed neither.

Your prof wants other people to do your homework? Must be a "quality" university.

1 Like

man i tried for so long now, i am just asking for help to understand what is going on or how i could solve my problem

You should accept help, not grade it.

Copy/paste this.

1 Like

That's why profs and TAs have office hours. They will give you the appropriate level of help without compromising your learning experience (which is the reason you pay tuition).

4 Likes

That was my reaction too, but you could perhaps meet the requirements of the assignment by catching one change of state in the ISR and the opposite change by polling the pin state

1 Like

Yeah, certainly, but I took this remark of OP literally:

So I figured everything has to be done inside the ISR, which kind of limits our options. I suspect it's also part of the exercise to do it that way. I also suspect that the line of code I quoted earlier might not actually be prescribed and that it's probably permissible to trigger on rising as well as falling slope.

1 Like

The wiring is important -- do your buttons bounce? do they have pullups or pull downs on them? The code needs to match your hardware.

This code does nothing about longpress and shortpress:

int parameter = 0;

void setup() {
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(2), upKeyPressed, RISING);
  attachInterrupt(digitalPinToInterrupt(3), downKeyPressed, RISING);
  sei();
}

void loop() {
  // put your main code here, to run repeatedly:

  report();
}

void upKeyPressed(void) {
  ++parameter;
  ;
}

void downKeyPressed(void) {
  --parameter;
  ;
}

void report(void) {
  static uint16_t last = 0;
  static int lastParameter = 0;
  uint16_t now = millis();
  if (now - last < 500) return;
  last = now;
  if ( parameter != lastParameter) {
    lastParameter = parameter;
    Serial.print(parameter);
    Serial.print(" ");
  }
}

... but it could serve to test your wiring.

As for differentiating a long and short press, consider a non-code analog: How you could tell how long someone was using a bathroom if all you could hear was the flush--it's the same problem. I think you need to think out of the box and manufacture some extra information somehow.

1 Like