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
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?
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
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.
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).
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
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.
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.