Skip to content

Commit

Permalink
Added CyclingButton, which is a 1-button value input. Short presses s…
Browse files Browse the repository at this point in the history
…witch on/off, long presses cycle through the values.
  • Loading branch information
jackjansen committed Dec 25, 2024
1 parent faeb384 commit 9e8f716
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 21 deletions.
2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
; http://docs.platformio.org/page/projectconf.html
[platformio]
default_envs =
lolin32-example-bleled-kitchensink
lolin32-example-input
;
; common options for all variants of iotsa
;
Expand Down
77 changes: 68 additions & 9 deletions src/iotsaInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,25 +249,39 @@ void ValueInput::bindVar(float& _var, float _min, float _max, float _stepSize) {
}


void ValueInput::_changeValue(int steps) {
bool ValueInput::_changeValue(int steps) {
bool reachedLimit = false;
value += steps;
IFDEBUG IotsaSerial.printf("ValueInput callback increment %d value %d", steps, value);
if (intVar) {
*intVar += steps*intStep;
if (*intVar < intMin) *intVar = intMin;
if (*intVar > intMax) *intVar = intMax;
if (*intVar < intMin) {
*intVar = intMin;
reachedLimit = true;
}
if (*intVar > intMax) {
*intVar = intMax;
reachedLimit = true;
}
IFDEBUG IotsaSerial.printf(" intVar %d", *intVar);
}
if (floatVar) {
*floatVar += steps*floatStep;
if (*floatVar < floatMin) *floatVar = floatMin;
if (*floatVar > floatMax) *floatVar = floatMax;
if (*floatVar < floatMin) {
*floatVar = floatMin;
reachedLimit = true;
}
if (*floatVar > floatMax) {
*floatVar = floatMax;
reachedLimit = true;
}
IFDEBUG IotsaSerial.printf(" floatVar %f", *floatVar);
}
IFDEBUG IotsaSerial.println();
if (activationCallback) {
activationCallback();
}
return reachedLimit;
}

RotaryEncoder::RotaryEncoder(int _pinA, int _pinB)
Expand Down Expand Up @@ -358,8 +372,8 @@ UpDownButtons::UpDownButtons(Button& _up, Button& _down, bool _useState)
useState(_useState),
stateVar(NULL)
{
up.setCallback(std::bind(&UpDownButtons::_upPressed, this));
down.setCallback(std::bind(&UpDownButtons::_downPressed, this));
up.setCallback(std::bind(&UpDownButtons::_upPressedCallback, this));
down.setCallback(std::bind(&UpDownButtons::_downPressedCallback, this));
up.setRepeat(500, 100);
down.setRepeat(500, 100);
}
Expand All @@ -382,7 +396,7 @@ void UpDownButtons::loop() {
down.loop();
}

bool UpDownButtons::_upPressed() {
bool UpDownButtons::_upPressedCallback() {
if (!up.pressed) return true;
if (useState) {
// The buttons double as on/off buttons. A short press means "on"
Expand All @@ -398,7 +412,7 @@ bool UpDownButtons::_upPressed() {
return true;
}

bool UpDownButtons::_downPressed() {
bool UpDownButtons::_downPressedCallback() {
if (useState) {
// The buttons double as on/off buttons. A short press means "off"
// only longer press (repeats) means "decrease". We determine
Expand All @@ -417,3 +431,48 @@ bool UpDownButtons::_downPressed() {
_changeValue(-1);
return true;
}


CyclingButton::CyclingButton(Button& _button)
: ValueInput(),
state(false),
button(_button),
stateVar(NULL)
{
button.setCallback(std::bind(&CyclingButton::_pressedCallback, this));
button.setRepeat(500, 100);
}

void CyclingButton::bindStateVar(bool& _var) {
stateVar = &_var;
}

void CyclingButton::setStateCallback(ActivationCallbackType callback) {
stateCallback = callback;
}

void CyclingButton::setup() {
button.setup();
}

void CyclingButton::loop() {
button.loop();
}

bool CyclingButton::_pressedCallback() {
if (button.pressed) {
// The button was pressed. We ignore the first press.
if (button.repeatCount == 0) return true;
if (_changeValue(direction)) {
direction = -direction;
}
} else {
// The button was released. If this was a short press we toggle on/off.
if (button.repeatCount == 0) {
state = !state;
if (stateVar) *stateVar = state;
if (stateCallback) stateCallback();
}
}
return true;
}
38 changes: 27 additions & 11 deletions src/iotsaInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ class Input {
class Button : public Input {
public:
Button(int _pin, bool _actOnPress, bool _actOnRelease, bool _wake=false);
void setup();
void loop();
void setup() override;
void loop() override;
void setRepeat(uint32_t _firstRepeat, uint32_t _minRepeat);
void bindVar(bool& _var, bool _toggle);
bool pressed;
Expand All @@ -74,15 +74,15 @@ class Button : public Input {
class Touchpad : public Button {
public:
Touchpad(int _pin, bool _actOnPress, bool _actOnRelease, bool _wake=false);
void setup();
void setup() override;
// void loop() is used from Button
bool pressed;
uint32_t duration;
#ifdef IOTSA_DEBUG_INPUT
uint16_t dbg_lastValue;
#endif
protected:
bool _getState();
virtual bool _getState() override;
#ifdef IOTSA_DEBUG_INPUT
public:
#endif
Expand All @@ -97,7 +97,7 @@ class ValueInput : public Input {
void bindVar(float& _var, float _min, float _max, float _stepSize);
int value;
protected:
void _changeValue(int steps);
bool _changeValue(int steps);
int *intVar, intMin, intMax, intStep;
float *floatVar, floatMin, floatMax, floatStep;
};
Expand All @@ -107,8 +107,8 @@ class ESP32Encoder;
class RotaryEncoder : public ValueInput {
public:
RotaryEncoder(int _pinA, int _pinB);
void setup();
void loop();
void setup() override;
void loop() override;
void setAcceleration(uint32_t _accelMillis);
uint32_t duration;
protected:
Expand All @@ -127,21 +127,37 @@ class RotaryEncoder : public ValueInput {
class UpDownButtons : public ValueInput {
public:
UpDownButtons(Button& _up, Button& _down, bool _useState=false);
void setup();
void loop();
void setup() override;
void loop() override;
void bindStateVar(bool& _var);
void setStateCallback(ActivationCallbackType callback);
bool state;
protected:
Button& up;
Button& down;
bool _upPressed();
bool _downPressed();
bool _upPressedCallback();
bool _downPressedCallback();
bool useState;
bool *stateVar;
ActivationCallbackType stateCallback;
};

class CyclingButton : public ValueInput {
public:
CyclingButton(Button& _button);
void setup() override;
void loop() override;
void bindStateVar(bool& _var);
void setStateCallback(ActivationCallbackType callback);
bool state;
protected:
Button& button;
bool _pressedCallback();
bool *stateVar;
int direction = 1;
ActivationCallbackType stateCallback;
};

class IotsaInputMod : public IotsaMod {
public:
IotsaInputMod(IotsaApplication& app, Input **_inputs, int _nInput) : IotsaMod(app), inputs(_inputs), nInput(_nInput) {}
Expand Down

0 comments on commit 9e8f716

Please sign in to comment.