• @bigplik, you just pass a second argument into the constructor. The second argument is the button / pin and is optional. If absent, it is BTN1.

    var SWBtn = require("https://raw.githubusercontent.c­om/muet/EspruinoDocs/master/modules/SWBu­tton.js"); 
      , mySWBtn0 = new SWBtn( function(k) {
          console.log("BTN1 detected " + k); // log key press pattern
          if        (k === "L"  ) { LED1.set();
          } else if (k === "LS" ) { LED1.reset();
          } else if (k === "LL" ) { LED2.set();
          } else if (k === "LLS") { LED2.reset();
          }
        }   
       ,<MyButtonOrPin>
       ); 
    

    The constructor accepts three arguments of which latter two are optional:

    var SWBtn = require("https://raw.githubusercontent.c­om/muet/EspruinoDocs/master/modules/SWBu­tton.js");
    var mySWBtn = new SWBtn(function(s){
        console.log("BTN1 detected " + k); // log key press pattern
          if        (s === "L"  ) { LED1.set();
          } else if (s === "LS" ) { LED1.reset();
          } else if (s === "LL" ) { LED2.set();
          } else if (s=== "LLS") { LED2.reset();
          }
        }          // --- callback function called with string of Ls and Ss
                   //     representing the sequence of Long and Short presses
     , optBtnOrPin // --- button or pin to watch, optional, default is BTN1
     , optDisabled // --- boolean to start enabled or disabled, optional,
                   //     default is false (false-y, which means enabled)
     );
    

    If you construct the software button disabled, you can enable - as well as disable - it anytime in the code:

    mySWBtn.disable(false); // enable button
    mySWBtn.disable() // same as above: enable button
    mySWBtn.disable(true) // disable button
    

    With application code controlled enabling/disabling of the SW Button you can ensure unambiguous UI behavior.

    Since SWButton (what you get from module) is a constructor, you can setup multiple SW Buttons, like:

    var swBtn1 = new SWButton(...,pin3)       // sw btn 1 enabled on pin3
      , swBtn2 = new SWButton(...,pin12,true) // sw btn 2 disabled on pin 12
    

    To see the code, just open in the browser the url in the require. You will notice that it includes much more information - including inline doc and examples. SW button is quite 'open': you even can configure the (detection) timings meeting custom requirements:

    /* Copyright (c) 2014 Markus Muetschard. See MIT LICENSE for copying permission. */
    
    /*
    SWBtn class - instances of SWBtn makes many buttons out of 
    just one hardware button by detecting sequences of short and 
    long presses and passing them on to a user defined, dispatching 
    callback function.
    
    For example, one long press of Espruino onboard BTN1 turns LED1 
    on, and one long and one short turn it off. Two long presses and 
    two long presses followed by a short one do the same to LED2, etc.
    
    Each detected sequence is passed in form of a string of "S"s 
    and "L"s to the user provided callback function. The callback 
    function uses the string as a key to call assigned functions
    like dispatcher.
    
    NOTE: Works on 1v72+ due to export and usage pattern
    
    Usage examples:
    
    // 1st example just logs the key press pattern
    var SWBtn = require("SWButton");
    var mySWBtn = new SWBtn(function(k){
        console.log("BTN1 detected " + k); // log key press pattern
      });
    
    // 2nd example tests key pattern and executes accordingly
    var SWBtn = require("SWButton");
    var mySWBtn = new SWBtn(function(k){
        console.log("BTN1 detected " + k); // log key press pattern
        if        (k === "L"  ) { LED1.set();
        } else if (k === "LS" ) { LED1.reset();
        } else if (k === "LL" ) { LED2.set();
        } else if (k === "LLS") { LED2.reset();
        }
      });
    
    // 3rd example avoids chained ifs by:
    var functions = // function names match key press pattern
    { L:   function(){ LED1.set();   }
    , LS:  function(){ LED1.reset(); }
    , LL:  function(){ LED2.set();   }
    , LLS: function(){ LED2.reset(); }
    };
    var SWBtn = require("SWButton");
    var mySWBtn = new SWBtn(function(k){
        console.log("BTN1 detected " + k); // log detected key pattern and...
        if (functions[k]) { functions[k](); }; // ...dispatch if defined
      },BTN1,false);
    
    // 4th example assumes a push button on pin B2 connecting to +3.3
    pinMode(B2,"input_pulldown");
    var SWBtn = require("SWButton");
    var mySWBtn = new SWBtn(function(k){
        console.log("Btn on B2 detected " + k); // log key press pattern
      },B2);
    
    */
    
    /**
    SWBtn - SoftWare Butten 'class'
    - constructor - accepts these arguments:
      - f - (optional) anonymous, one argument accepting dispatching callback function
      - b - (optional) button/pin id - default is BTN1
      - d - (optional) boolean interpreted disable flag - default false
            Allows button to be creted in disabled state in order 
            for (other) initializations to complete before being
            enabled with .disable(0) / .disable(false) / .disable()
            method invocation.
    - instance properties:
      - f - storex passed or set dispatching callback function
      - b - storex button / pin id
      - d - stores disabled (status) of button
      - t - xgofdx timeout for sequence end / pause detection
      - k - stores build-up key store holding on to the "S"s and "L"s of a squence
      - w - stores hold on to the watch set with setWatch()
    */
    var SWBtn = function(f,b,d) {
      this.f = (f) ? f : function(){};
      this.b = (b) ? b : BTN1;
      this.t = null;
      this.k = null;
      this.w = null;
      this.disable(d);
     }
    
    /**
    .C - Constants / Configuration - defining the timings 
    - shared by all instances of SWBtn:
      - B - integer - debounce [ms]
      - L - float   - min Long press [s]
      - P - integer - min Pause [ms]
      - D - integer - delay of fnc function invocation [ms]
      Pressing a button / keeping a pin low for .C.L seconds or more is detected
      as a long press when unpressed / released / pin turns high and and adds an 
      "L" to .k key (press sequnce) - otherwise a short press is detected and an 
      "S" is adde - and the .t timeout is set with .C.P Pause time and .e() ended
      call back for press sequence end detection and processing (invocation of
      user defined - ,k key decoding dispatch - function).
    */
    SWBtn.prototype.C =
      { B: 20
      , L: 0.250
      , P: 220
      , D: 10
      };
    
    /**
    .disable(b) - disables/enables button
    - method - accepts one argument
      - b - boolean - (optional) boolean interpreted disable flag - default false
      Used to (temporarily) disable the button (also used in constructor).
      It clears/sets the hardware / pin watch using clearWatch() / setWatch() functions.
      NOTE1: When button is disabled while press sequence is going on, sequence end is
        not detected, but partial sequence is still stored in .k key property (but does 
        not include an ongoing press). 
      NOTE2: The .k key property is cleared (set to "") when button is (re-)enabled.
      NOTE3: any passed parameter that evaluates to false in an 'if (parameter)' and 
        omission of parameter enable the button: .disable(false), .disable(0),
        .disable(""), .disable(''), .disable(null), .disable(undefined), and .disable(),
        all these invocations enable the button... ;)
    */
    SWBtn.prototype.disable = function(b) {
      if (b) {
        if (this.w) { 
          this.d = true;
          clearWatch(this.w);
          this.w = null; 
          if (this.t) {
            clearTimeout(this.t);
            this.t = null;
          }
        }
      } else {
        if (!this.w) {
          this.d = false;
          this.k = "";
          var _this = this;
          this.w = setWatch( function(e){ _this.c(e); }, this.b
                     , { repeat:true, edge:"both", debounce:_this.C.B } );
        }
      }
     };
    
    /**
    .c(e) - button/pin button/pin state change callback - invoked by Espruino
    - method - accepts one e event argument (object) 
      Espruino reference for .setWatch() defines e event object as:
      - time     - float   - time of this state change [s]
      - lastTime - float   - time of last such state change [s]
      - state    - boolean - current state of the button / pin
      Notes button/pin status and - on unpress/release state - 
      appends "L"(ong) or "S"(short) to .k key (sequence) and 
      sets .t timeout to .C.P Pause for sequence end detection
    */
    SWBtn.prototype.c = function(e){ // change of state - called by set watch
      if (e.state) {
        if (this.t) {
          clearTimeout(this.t);
          this.t = null;
        }
      } else {
        this.k = this.k + ((e.time - e.lastTime < this.C.L) ? "S" :"L");
        var _this = this;
        this.t = setTimeout(function(){ _this.e(); }, this.C.P);
      }
     };
    
    /**
    .e() - sequence ended timeout callback - invoked by .t timeout set in .c(e)
    - method - accepts no arguments
      Marks detected end of press sequence and invokes user provided .f 
      callback function in a setTimeout() with .C.D delay.
    */
    SWBtn.prototype.e = function() {
      this.t = null;
      var _k = this.k;
      if (_k.length > 0) {
        this.k = "";
        var _this = this;
        setTimeout(function(){ _this.f(_k); },this.C.D);
      }
     };
    
    exports = SWBtn;
    
  • in reply to @allObjects
    sorry but still not clear,
    I used your parts of code above and still have some errors

    do I need some setWatch to make it run?

    is this example below enough to run or there is missing part?
    in my case this code doesn't detect any button

    var SWBtn = require("https://raw.githubusercontent.c­om/muet/EspruinoDocs/master/modules/SWBu­tton.js");
    var mySWBtn = new SWBtn(function(k){
        console.log("BTN1 detected " + k); // log key press pattern
        if        (k === "L"  ) { LED1.set();
        } else if (k === "LS" ) { LED1.reset();
        } else if (k === "LL" ) { LED2.set();
        } else if (k === "LLS") { LED2.reset();
        }
      });
    
About

Avatar for bigplik @bigplik started