@ancienthero, ...first shot, my answer in previous post is correct... BUT:
A defined sequence of short and long presses could be the prefix to the desired behavior. After the introductory sequence - like a preamble - the sw button would shift gear into a state which only detects the press of the last button and then return back to regular button behavior...
While listening to myself, I see that there is no need for any special thing, except a vary small change to the existing code / module: Passing the last press time to the function invoked - TO ALL INVOKED FUNCTIONS as a first argument... or pass the button object and have the button remember the time of the last press with a method to go for... or just have the button to remember the last press time.... Just remembering the last press time is the easiest to implement - no real change is needed for the interface or in the invocation pattern.
Here the just two (2) changes in the module code and usage example how to take advantage of that new feature of the SWButton:
Change in the constructor - add instance variable this.p = 0; to hold on to the time - in seconds - of the last press:
function SWBtn(fnc,btn,d) {
this.f = (fnc) ? fnc : function(){};
this.b = (btn) ? btn : BTN1;
this.t = null;
this.k = null;
this.w = null;
this.p = 0; # will hold on to the time of the last press
this.disable(d);
}
Capturing the last press time on watch event in (private) method .c(...) (~ line 131 in code in post #5:
...
SWBtn.prototype.c = function(e){ // change of state - called by set watch
...
this.k = this.k + (((this.p = e.time - e.lastTime )< this.C.L) ? "S" :"L"); // store p-ress time [s]
...
Using the captured press time in the called function to, for example turn red LED1 on for the same time, so you can easy verify if it works:
var SWBtn = require("https://raw.githubusercontent.com/muet/EspruinoDocs/master/modules/SWButton.js");
var mySWBtn = new SWBtn(function(k){
console.log("BTN1 detected " + k); // log key press pattern
if (k === "S" ) { LED1.set(); setTimeout(function(){
LED1.reset();},mySWBtn.p);
} else if (k === "L" ) { LED1.set(); setTimeout(function(){
LED1.reset();},mySWBtn.p);
} else if (k === "SS" ) { LED2.set(); setTimeout(function(){
LED2.reset();},mySWBtn.p);
} else if (k === "SL" ) { LED2.set(); setTimeout(function(){
LED2.reset();},mySWBtn.p);
} else if (k === "SLS") { LED1.set(); LED2.set(); setTimeout(function(){
LED1.reset();LED2.reset();},mySWBtn.p);
} else if (k === "SLS") { LED1.set(); LED2.set(); setTimeout(function(){
LED1.reset();LED2.reset();},mySWBtn.p);
});
This mySWBtn behaves as follows:
1 short press turns the red LED1 on for the same time as the short press.
1 long press turns the red LED1 on for the same time as the long press- the long press has to be the minimum as defined in C.L.
1 short and a 2nd short press turns green LED2 on for the same time as the 2nd short press.
1 short and a 2nd - long - press turns green LED2 on for the same time as the 2nd - long - press.
1 short and 1 long press and then the 3rd - short - press turns both red and green LEDs on for the same time as the 3rd - short - press.
1 short and 1 long press and then the 3rd - long - press turns both red and green LEDs on for the same time as the 3rd - short - press.
Calling the same function for both - short and long - last pressesmakes it possible to cover the complete time span...
Practical application is setting a value higher / lower, duration longer or shorter in analogue mode rather than in discrete steps.
If the pressing time should directly change something while press is still going on, then the very first suggestion of shifting from normal short-long detection mode into a separate mode could do so. The changes would be a bit more, but still manageable. I amy come back to this in a future post.
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
EDIT / Correction to previous post:
@ancienthero, ...first shot, my answer in previous post is correct... BUT:
A defined sequence of short and long presses could be the prefix to the desired behavior. After the introductory sequence - like a preamble - the sw button would shift gear into a state which only detects the press of the last button and then return back to regular button behavior...
While listening to myself, I see that there is no need for any special thing, except a vary small change to the existing code / module: Passing the last press time to the function invoked - TO ALL INVOKED FUNCTIONS as a first argument... or pass the button object and have the button remember the time of the last press with a method to go for... or just have the button to remember the last press time.... Just remembering the last press time is the easiest to implement - no real change is needed for the interface or in the invocation pattern.
Here the just two (2) changes in the module code and usage example how to take advantage of that new feature of the SWButton:
Change in the constructor - add instance variable
this.p = 0;
to hold on to the time - in seconds - of the last press:Capturing the last press time on watch event in (private) method
.c(...)
(~ line 131 in code in post #5:Using the captured press time in the called function to, for example turn red LED1 on for the same time, so you can easy verify if it works:
This mySWBtn behaves as follows:
C.L
.Calling the same function for both - short and long - last pressesmakes it possible to cover the complete time span...
Practical application is setting a value higher / lower, duration longer or shorter in analogue mode rather than in discrete steps.
If the pressing time should directly change something while press is still going on, then the very first suggestion of shifting from normal short-long detection mode into a separate mode could do so. The changes would be a bit more, but still manageable. I amy come back to this in a future post.