You are reading a single comment by @n00b and its replies. Click here to read the full conversation.
  • I went ahead and tried the interval route, and seemed to have made it work. Possible downside is the interval eating resource for other stuff, but I think I can get away with it by being smart in clearing the interval when input is safely not needed.

    My solution:

    var i2c = new I2C();
    i2c.setup({
        scl: B2,
        sda: B3
    });
    var address = 0; //this is the address, set by the address pins.
    
    // for MCP23017
    var port = require("MCP23017").connect(i2c, null, address);
    
    //matrix
    var colPins = [port.A7, port.A6, port.A5, port.A4];
    var rowPins = [port.A3, port.A2, port.A1, port.A0];
    
    
    //set col to low
    for (var i in colPins) {
        colPins[i].mode("output");
        colPins[i].write(0);
    }
    
    //set row to 1 via pull up
    for (var j in rowPins) {
        rowPins[j].mode("input_pullup");
    }
    
    var col = -1;
    var row = -1;
    var lastButton = null;
    
    function mapToButton(c, r) {
        if (c === 3 && r === 3) return ("B1");
        if (c === 2 && r === 3) return ("B2");
        if (c === 1 && r === 3) return ("B3");
        if (c === 0 && r === 3) return ("B4");
        if (c === 3 && r === 2) return ("B5");
        if (c === 2 && r === 2) return ("B6");
        if (c === 1 && r === 2) return ("B7");
        if (c === 0 && r === 2) return ("B8");
        if (c === 3 && r === 1) return ("B9");
        if (c === 2 && r === 1) return ("B10");
        if (c === 1 && r === 1) return ("B11");
        if (c === 0 && r === 1) return ("B12");
        if (c === 3 && r === 0) return ("B13");
        if (c === 2 && r === 0) return ("B14");
        if (c === 1 && r === 0) return ("B15");
        if (c === 0 && r === 0) return ("B16");
    }
    
    function scanCol() {
        //set col to low
        var i, j;
        for (i in colPins) {
            colPins[i].mode("output");
            colPins[i].write(0);
        }
    
        //set row to 1 via pull up
        for (j in rowPins) {
            rowPins[j].mode("input_pullup");
        }
        for (i in rowPins) {
            if (rowPins[i].read() === 0) {
                col = i;
                break;
            }
        }
    }
    
    function scanRow() {
        //set row to low
        var i, j;
        for (i in rowPins) {
            rowPins[i].mode("output");
            rowPins[i].write(0);
        }
    
        //set row to 1 via pull up
        for (j in colPins) {
            colPins[j].mode("input_pullup");
        }
        for (i in colPins) {
            if (colPins[i].read() === 0) {
                row = i;
                break;
            }
        }
        if (col >= 0 && row >= 0) {
            var btn = mapToButton(col, row);
            if (lastButton !== btn) {
                print(btn);
                lastButton = btn;
            }
        }
    }
    
    setInterval(function () {
    
        col = -1;
        row = -1;
        scanCol();
        if (col >= 0) {
            scanRow();
        } else {
            lastButton = null;
        }
    }, 50);
    
    

    Would still love to hear if it is possible to use setWatch btw!

About

Avatar for n00b @n00b started