Soy un principiante completo con Arduino, pero he buscado bastante y parece que no puedo solucionar este problema.
Estoy tratando de crear un procedimiento que se llama repetidamente en el principal loop()
que establecerá una variable según el estado actual de un botón, así como la duración del botón o durante el cual se presionó. Este código es probablemente más complicado de lo que debe ser, pero parece dejar la variable en 0
. ¿Qué me estoy perdiendo?
Hay un código en loop()
sí mismo que restablece la rotaryButtonToAction
variable noPress
una vez que se ha actuado.
#define noPress 0
#define shortPressReleased 1
#define longPressReleased 2
#define shortPressHolding 3
#define longPressHolding 4
int rotaryButtonState;
int rotaryButtonReading;
int lastRotaryButtonReading = HIGH;
int timeOfLastRotaryButtonReadingChange = 0;
int debounceDelay = 50;
int longPressDelay = 300;
int rotaryButtonToAction = 0;
void checkRotaryButton() {
if (rotaryButtonToAction == noPress) { // if there is nothing to action, check the state of the button
rotaryButtonReading = digitalRead(ROTARY_BUTTON); // store pin's current state
if (rotaryButtonReading != lastRotaryButtonReading) { // if pin state has changed from the last reading, set timeOfLastRotaryButtonReadingChange to the time of the change
timeOfLastRotaryButtonReadingChange = millis();
}
if (millis() - timeOfLastRotaryButtonReadingChange > debounceDelay) { // if more time has passed than the debounce delay, change the action state of the button
if (rotaryButtonReading = LOW) { // if the button is still pressed, set the action to indicate it has been pressed and is still pressed
rotaryButtonToAction = shortPressHolding;
}
else { // if the button was pressed for longer than the debounce delay and was released, set the action
rotaryButtonToAction = shortPressReleased;
}
}
}
if (millis() - timeOfLastRotaryButtonReadingChange > longPressDelay) { // if more time has passed than the long press delay, change the action state of the button
if (rotaryButtonReading == LOW) { // if the button is still pressed, set the action to indicate it has been pressed and is still pressed
rotaryButtonToAction = longPressHolding;
}
else { // if the button was pressed for longer than the long press delay and was released, set the action
rotaryButtonToAction = longPressReleased;
}
}
} // end checkRotaryButton
Nunca usé Arduino, pero ¿no necesita usar signos iguales dobles en una función de comparación?
Entonces, ¿ if (rotaryButtonToAction = noPress)
debería ser if (rotaryButtonToAction == noPress)
en su lugar?
Bueno, después de mucho jugar, adopté un enfoque completamente diferente que parece hacer justo lo que necesito. Creo que este es un ejemplo de una "máquina de estado", aunque soy nuevo en todo esto...
void checkRotaryButton() {
rotaryButtonReading = digitalRead(ROTARY_BUTTON); // store pin's current state
if (rotaryButtonReading != lastRotaryButtonReading) { // if pin state has changed from the last reading
timeOfLastRotaryButtonChange = millis(); // if pin state different, store the time of the state change
}
timeSinceLastRotaryButtonChange = millis() - timeOfLastRotaryButtonChange;
if (rotaryButtonReading == LOW && timeSinceLastRotaryButtonChange < debounceDelay) {
// has only been low for less than the debounce time - do nothing
}
if (rotaryButtonReading == LOW && timeSinceLastRotaryButtonChange > longPressDelay && rotaryButtonToAction != longPressed) {
rotaryButtonToAction = longPressed;
Serial.println("button pressed long");
}
if (rotaryButtonReading == LOW && timeSinceLastRotaryButtonChange > debounceDelay && timeSinceLastRotaryButtonChange < longPressDelay && rotaryButtonToAction != holdingPress) {
rotaryButtonToAction = holdingPress;
Serial.println("holding button pressed");
}
if (rotaryButtonReading == HIGH && timeSinceLastRotaryButtonChange > debounceDelay && rotaryButtonToAction == holdingPress) {
rotaryButtonToAction = shortPressed;
Serial.println("released short press");
}
lastRotaryButtonReading = rotaryButtonReading; // store this reading for comparison the next time the procedure loops
} // end checkRotaryButton
Jens Hembach
pirómano analógico
Jens Hembach
ratones