You are reading a single comment by @allObjects and its replies. Click here to read the full conversation.
  • Hold your breath buying more hardware. If switching the power for the shift register from 3.3V to 5V (and the decoupling with diode and a 100uF (or a few in parallel)) do not calm down the relays from jittering, the problem (dog) lays (buried) somewhere else.

    When I asked about the switches, I was thinking of the schema, how the diodes and switches are matrix wired. With three lines you are able to catch 8 states, where as the state 0 is the 'unusable all-off' state, leaving seven (7) different watch-detectable states. There may be some 'trickery; to work with less then the twelve (12) diodes I would need to reliably do it (with momentary-on SPST - Single Pole Single Throw - switches in mind vs momentary-on SPDT - Single Pole Double Throw - switches; with the latter ones you may get away with less diodes by using both on states... but Espruino is so fast that it detects the none-on when the switch switches, and with the diode setup it may trigger erroneously on top of the multi triggers by the multiple watches....).

    Furthermore, on all three input lines you have a watch... depending your circuitry and the expected switch value more than one fire and may create your jitter... Multiple get serialized and then are processed one after the other in JS 'tasks' (callbacks). Therefore, after one triggered, you clear all watches, 'wait' some time and ignore any others that do trigger, then read the lines, do the work, set the watches for the going off, do the same finicky things for the off as you did for the on, and then set the watches for 'on's again for the next cycle...

    Attached 'my' schema I was thinking of to check for seven (7) switches.

    And here the (partially tested) code:

    var switches =
    { callback: function(v){}
    , enabled: true
    , repeat: true
    , _pins: []
    , _watches: []
    , _rdy: false
    , setup: function( // setup with pins, callback w/ binary value by default and enabled
            pins       // array of pins [msb..lsb] (weight ...,4,2,1)
          , callback   // callback(value) - value binary value or bit list
          , asValue    // optional - true(default): callback w/ binary value, false: w/ bit list
          , enabled    // optional - true(default), false: disabled
          , repeat     // optional - true(default), false: disables switches on switch on event
          , debounce   // optional - undefined(default): 50ms
          ) {
        this._rdy = this.enabled = false;
        var _debounce = ((typeof debounce !== "undefined") && (debounce >= 0)) ? debounce : 50;
        this.repeat = (repeat !== false);
        this.enabled = (enabled !== false);
        this.asValue = (asValue !== false);
        this.callback = callback;
        this._pins = pins;
        this.prep();
        this._rdy = this.enabled;
      }
    , _hold: function() {
        if (this._rdy) {
          this._rdy = false;
          setTimeout(this._callback.bind(this), 10);
      } } 
    , _callback: function() {
        var val = this.read();
        if (val) { // something detected
           setTimeout(this.callback, 10, val);
           this.enabled = (this.repeat) ? this.enabled : false;
        }
        this._rdy = this.enabled;
      }
    , prep: function() {
        while (this._watches.length > 0) { clearWatch(this._watches.pop()); }
        this._pins.forEach(function(p) {
        pinMode(p,"input_pulldown");
            this.watches.push(setWatch(this._hold.bi­nd(this)
                , { repeat: true, edge: "raising", debounce: _debounce }));
          }, this);
      }
    , read: function() { // can be used anytime to read switches
        var val = 0; 
        this._pins.forEach(function(p) { val = (val << 1) + dititalRead(p); });
        if (val) { val = (this.asValue) ? val : 1 << (val - 1); }
        return val;
      }
    , enable: function(enabled) { 
        this.enabled = (enabled !== false);
        this._rdy = this.enabled;
      }
    };
    switches.setup([B15,B14,B14],function(va­l){ console.log("switch " + val); });
    
    
    The ```watches[]``` holds on the the ```watch_ids``` returned by ```setWatch()``` in order to be able to clear them with ```clearWatch()``` for repeatable use of ```set()``` in one run session. For a nested 'UI', the callback can be changed with ```switches.callback = function(value) {....``` to cater to different menu-levels/contexts. When considering this it is advised to use ```rapeat``` option set to ```false``` to avoid 'logic jitters'.
    
    

    asValueoption allows you to control the value in the callback as well as with theread(_function.asValuewithtruegives you the values1..7, where as withfalsethe values are1,2,4,8,16, 32, 64, alternatively represented as0b00000001,0b00000010, 0b00000100,... 0b01000000```, which represent a bit lis, andtis the format you need for the shift register...

    Since you may need the value as an index for all kinds of things - especially with the display - use the default value and build the bit list just when you need to send the value to the shift register. The conversion is really easy: 1 << (value - 1) creates the bit list from the value.

    There are other solutions, but with three (3) lines you get only six (6) switches, and with four (4) lines you get twelve (12) switches (needs only six (6) diodes). If you can spare six (6) lines, you can detect nine (9) switches without any diode.


    1 Attachment

    • switches7w4.png
About

Avatar for allObjects @allObjects started