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!
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.
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:
Would still love to hear if it is possible to use setWatch btw!