From d6cd0ef8ccdde6c799b19004604c540cf6bbd12c Mon Sep 17 00:00:00 2001 From: Askan Hesse Date: Sat, 7 Apr 2018 00:33:12 +0200 Subject: [PATCH] update version of i2c dependency in package.json --- .gitignore | 3 + README.md | 4 +- examples/package.json | 7 +-- examples/pull_down.js | 38 ++++++++++++ lib/mcp23017.js | 139 ++++++++++++++++++++++++++---------------- package.json | 4 +- 6 files changed, 134 insertions(+), 61 deletions(-) create mode 100644 examples/pull_down.js diff --git a/.gitignore b/.gitignore index da23d0d..8fc484b 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,6 @@ build/Release # Deployed apps should consider commenting this line out: # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git node_modules + +# Intellij +.idea/ diff --git a/README.md b/README.md index 0a1c9da..3bcf02d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ node-mcp23017 Node.js library for the I2C I/O Expander MCP23017 on a Raspberry Pi -It currently only supports reading from and writing to the chip +It currently supports reading and writing of GPIOs, and changing thier pull-up resistor configuration. The module tries to mimic the Arduino-Syntax @@ -79,6 +79,7 @@ var mcp = new MCP23017({ for (var i = 0; i < 16; i++) { mcp.pinMode(i, mcp.OUTPUT); //mcp.pinMode(i, mcp.INPUT); //if you want them to be inputs + //mcp.pinMode(i, mcp.INPUT_PULLUP); //if you want them to be pullup inputs } mcp.digitalWrite(0, mcp.HIGH); //set GPIO A Pin 0 to state HIGH @@ -140,7 +141,6 @@ setInterval(blink, 100); //blink all LED's with a delay of 100ms ## TODO -- implement built-in pullup resistors - implement interrupt handling ## Acknowledgement diff --git a/examples/package.json b/examples/package.json index 52b9128..81a4c5f 100644 --- a/examples/package.json +++ b/examples/package.json @@ -1,8 +1,7 @@ { - "name": "mcp23017-blink-example", - "version": "1.0.0", - "description": "blinks 16 leds", - "main": "blink.js", + "name": "mcp23017-examples", + "version": "1.1.0", + "description": "different examples for showing functionality of library.", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, diff --git a/examples/pull_down.js b/examples/pull_down.js new file mode 100644 index 0000000..a44b92b --- /dev/null +++ b/examples/pull_down.js @@ -0,0 +1,38 @@ +var MCP23017 = require('node-mcp23017'); + +var mcp = new MCP23017({ + address: 0x20, //all address pins pulled low + device: '/dev/i2c-1', // Model B + debug: false +}); + +mcp.pinMode(0, mcp.INPUT_PULLUP); +mcp.pinMode(1, mcp.INPUT_PULLUP); +mcp.pinMode(2, mcp.INPUT_PULLUP); +mcp.pinMode(3, mcp.INPUT_PULLUP); +mcp.pinMode(4, mcp.INPUT_PULLUP); +mcp.pinMode(5, mcp.INPUT_PULLUP); +mcp.pinMode(6, mcp.INPUT_PULLUP); +mcp.pinMode(7, mcp.INPUT_PULLUP); +mcp.pinMode(8, mcp.INPUT_PULLUP); +mcp.pinMode(9, mcp.INPUT_PULLUP); +mcp.pinMode(10, mcp.INPUT_PULLUP); +mcp.pinMode(11, mcp.INPUT_PULLUP); +mcp.pinMode(12, mcp.INPUT_PULLUP); +mcp.pinMode(13, mcp.INPUT_PULLUP); +mcp.pinMode(14, mcp.INPUT_PULLUP); +mcp.pinMode(15, mcp.INPUT); // this one should float from time to time + +setInterval(function(){ + +var test = function(i){ + return function(err, value){ + if(value == false){ + console.log("Pull down on pin " + i, value); + } + } +} + +for (var i = 8; i < 16; i++) { + mcp.digitalRead(i, test(i)); +} diff --git a/lib/mcp23017.js b/lib/mcp23017.js index d6db99b..0119daf 100644 --- a/lib/mcp23017.js +++ b/lib/mcp23017.js @@ -1,24 +1,30 @@ -var DIRECTION_GPIOA = 0x00, - DIRECTION_GPIOB = 0x01, - FROM_GPIOA = 0x12, - FROM_GPIOB = 0x13, - TO_GPIOA = 0x14, - TO_GPIOB = 0x15, +var REGISTER_GPIOA = 0x00, + REGISTER_GPIOB = 0x01, + REGISTER_GPIOA_PULLUP = 0x0C; + REGISTER_GPIOB_PULLUP = 0x0D; + READ_GPIOA_ADDR = 0x12, + READ_GPIOB_ADDR = 0x13, + WRITE_GPIOA_ADDR = 0x14, + WRITE_GPIOB_ADDR = 0x15, Wire = require('i2c'); var MCP23017 = (function() { MCP23017.prototype.HIGH = 1; MCP23017.prototype.LOW = 0; + MCP23017.prototype.INPUT_PULLUP = 2; MCP23017.prototype.INPUT = 1; MCP23017.prototype.OUTPUT = 0; MCP23017.prototype.address = 0x20; //if the mcp has all adress lines pulled low - MCP23017.prototype.oldADir = 0xff; //initial state of GPIO A - MCP23017.prototype.oldBDir = 0xff; //initial state of GPIO A + MCP23017.prototype.dirAState = 0xff; //initial state of GPIO A bank + MCP23017.prototype.dirBState = 0xff; //initial state of GPIO B bank - MCP23017.prototype.oldGpioA = 0x0; //initial state of GPIO A - MCP23017.prototype.oldGpioB = 0x0; //initial state of GPIO B + MCP23017.prototype.dirAPullUpState = 0x0; //initial state of GPIO A pull up resistor state + MCP23017.prototype.dirBPullUpState = 0x0; //initial state of GPIO B pull up resistor state + + MCP23017.prototype.gpioAState = 0x0; //initial state of GPIOS A + MCP23017.prototype.gpioBState = 0x0; //initial state of GPIOS B function MCP23017 (config) { this.address = config.address; @@ -34,8 +40,8 @@ var MCP23017 = (function() { //inits both registers as an input MCP23017.prototype.reset = function () { - this.oldBDir = 0xff; - this.oldADir = 0xff; + this.dirBState = 0xff; + this.dirAState = 0xff; this._initGpioA(); this._initGpioB(); }; @@ -44,7 +50,7 @@ var MCP23017 = (function() { sets an pin as an INPUT or OUTPUT */ MCP23017.prototype.pinMode = function (pin, dir) { - if (dir !== this.INPUT && dir !== this.OUTPUT) { + if (dir !== this.INPUT && dir !== this.INPUT_PULLUP && dir !== this.OUTPUT) { console.error('invalid value', dir); return; } @@ -56,71 +62,98 @@ var MCP23017 = (function() { } //delegate to funktion that handles low level stuff - this._setGpioDir(pin >= 8 ? pin - 8 : pin, dir, pin >= 8 ? DIRECTION_GPIOB : DIRECTION_GPIOA); + this._setGpioDir(pin >= 8 ? pin - 8 : pin, dir, pin >= 8 ? REGISTER_GPIOB : REGISTER_GPIOA, pin >= 8 ? REGISTER_GPIOB_PULLUP : REGISTER_GPIOA_PULLUP); }; /* internally used to set the direction registers */ - MCP23017.prototype._setGpioDir = function (pin, dir, register) { + MCP23017.prototype._setGpioDir = function (pin, dir, registerDirection, registerPullUp) { var pinHexMask = Math.pow(2, pin), - registerValue; + registerDir, + registerPullUpDir; - if (register === DIRECTION_GPIOA) { - registerValue = this.oldADir; + if (registerDirection === REGISTER_GPIOA) { + registerDir = this.dirAState; if (dir === this.OUTPUT) { - if ((this.oldADir & pinHexMask) === pinHexMask) { + if ((this.dirAState & pinHexMask) === pinHexMask) { this.log('setting pin \'' + pin + '\' as an OUTPUT'); - this.oldADir = this.oldADir ^ pinHexMask; - registerValue = this.oldADir; + this.dirAState = this.dirAState ^ pinHexMask; + registerDir = this.dirAState; } else { this.log('pin \'' + pin + '\' already an OUTPUT'); } - } else if (dir === this.INPUT) { - if ((this.oldADir & pinHexMask) !== pinHexMask) { + } else if (dir === this.INPUT || dir === this.INPUT_PULLUP) { + if ((this.dirAState & pinHexMask) !== pinHexMask) { this.log('setting pin \'' + pin + '\' as an INPUT'); - this.oldADir = this.oldADir ^ pinHexMask; - registerValue = this.oldADir; + this.dirAState = this.dirAState ^ pinHexMask; + registerDir = this.dirAState; } else { this.log('pin \'' + pin + '\' already an INPUT'); } + if (dir === this.INPUT_PULLUP) { + registerPullUpDir = this.dirAPullUpState; + if ((this.dirAPullUpState & pinHexMask) !== pinHexMask) { + this.log('activate INPUT_PULLUP for pin \'' + pin + '\''); + this.dirAPullUpState = this.dirAPullUpState ^ pinHexMask; + registerPullUpDir = this.dirAPullUpState; + } else { + this.log('pin \'' + pin + '\' already activated INPUT_PULLUP'); + } + } } - } else if (register === DIRECTION_GPIOB) { - registerValue = this.oldBDir; + } else if (registerDirection === REGISTER_GPIOB) { + registerDir = this.dirBState; if (dir === this.OUTPUT) { - if ((this.oldBDir & pinHexMask) === pinHexMask) { + if ((this.dirBState & pinHexMask) === pinHexMask) { this.log('setting pin \'' + pin + '\' as an OUTPUT'); - this.oldBDir = this.oldBDir ^ pinHexMask; - registerValue = this.oldBDir; + this.dirBState = this.dirBState ^ pinHexMask; + registerDir = this.dirBState; } else { this.log('pin \'' + pin + '\' already an OUTPUT'); } - } else if (dir === this.INPUT) { - if ((this.oldBDir & pinHexMask) !== pinHexMask) { + } else if (dir === this.INPUT || dir === this.INPUT_PULLUP) { + if ((this.dirBState & pinHexMask) !== pinHexMask) { this.log('setting pin \'' + pin + '\' as an INPUT'); - this.oldBDir = this.oldBDir ^ pinHexMask; - registerValue = this.oldBDir; + this.dirBState = this.dirBState ^ pinHexMask; + registerDir = this.dirBState; } else { this.log('pin \'' + pin + '\' already an INPUT'); } + if (dir === this.INPUT_PULLUP) { + registerPullUpDir = this.dirBPullUpState; + if ((this.dirBPullUpState & pinHexMask) !== pinHexMask) { + this.log('activate INPUT_PULLUP for pin \'' + pin + '\''); + this.dirBPullUpState = this.dirBPullUpState ^ pinHexMask; + registerPullUpDir = this.dirBPullUpState; + } else { + this.log('pin \'' + pin + '\' already activated INPUT_PULLUP'); + } + } } } - this._send(register, [registerValue]); - this.log('register: ' + register + ', value: ' + registerValue); + + this._send(register, [registerDir]); + this.log('pin: ' + pin + ', register: ' + register + ', value: ' + registerDir); + + if(registerPullUpDir !== undefined){ + this._send(registerPullUp, [registerPullUpDir]); + this.log('pin: ' + pin + ', register: ' + registerPullUp + ', pull up value: ' + registerPullUpDir); + } }; MCP23017.prototype._setGpioAPinValue = function (pin, value) { var pinHexMask = Math.pow(2, pin); if (value === 0) { - if ((this.oldGpioA & pinHexMask) === pinHexMask) { - this.oldGpioA = this.oldGpioA ^ pinHexMask; - this._send(TO_GPIOA, [this.oldGpioA]); + if ((this.gpioAState & pinHexMask) === pinHexMask) { + this.gpioAState = this.gpioAState ^ pinHexMask; + this._send(WRITE_GPIOA_ADDR, [this.gpioAState]); } } if (value === 1) { - if ((this.oldGpioA & pinHexMask) !== pinHexMask) { - this.oldGpioA = this.oldGpioA ^ pinHexMask; - this._send(TO_GPIOA, [this.oldGpioA]); + if ((this.gpioAState & pinHexMask) !== pinHexMask) { + this.gpioAState = this.gpioAState ^ pinHexMask; + this._send(WRITE_GPIOA_ADDR, [this.gpioAState]); } } }; @@ -128,15 +161,15 @@ var MCP23017 = (function() { MCP23017.prototype._setGpioBPinValue = function (pin, value) { var pinHexMask = Math.pow(2, pin); if (value === 0) { - if ((this.oldGpioB & pinHexMask) === pinHexMask) { - this.oldGpioB = this.oldGpioB ^ pinHexMask; - this._send(TO_GPIOB, [this.oldGpioB]); + if ((this.gpioBState & pinHexMask) === pinHexMask) { + this.gpioBState = this.gpioBState ^ pinHexMask; + this._send(WRITE_GPIOB_ADDR, [this.gpioBState]); } } if (value === 1) { - if ((this.oldGpioB & pinHexMask) !== pinHexMask) { - this.oldGpioB = this.oldGpioB ^ pinHexMask; - this._send(TO_GPIOB, [this.oldGpioB]); + if ((this.gpioBState & pinHexMask) !== pinHexMask) { + this.gpioBState = this.gpioBState ^ pinHexMask; + this._send(WRITE_GPIOB_ADDR, [this.gpioBState]); } } }; @@ -168,7 +201,7 @@ var MCP23017 = (function() { }; MCP23017.prototype.digitalRead = function (pin, callback) { - var register = pin >= 8 ? FROM_GPIOB : FROM_GPIOA; //get the register to read from + var register = pin >= 8 ? READ_GPIOB_ADDR : READ_GPIOA_ADDR; //get the register to read from pin = pin >= 8 ? pin - 8 : pin; //remap the pin to internal value var pinHexMask = Math.pow(2, pin); //create a hexMask @@ -188,13 +221,13 @@ var MCP23017 = (function() { }; MCP23017.prototype._initGpioA = function () { - this._send(DIRECTION_GPIOA, [this.oldADir]); //Set Direction to Output - this._send(TO_GPIOA, [0x0]); //clear all output states + this._send(REGISTER_GPIOA, [this.dirAState]); //Set Direction to Output + this._send(WRITE_GPIOA_ADDR, [0x0]); //clear all output states }; MCP23017.prototype._initGpioB = function () { - this._send(DIRECTION_GPIOB, [this.oldBDir]); //Set Direction to Output - this._send(TO_GPIOB, [0x0]); //clear all output states + this._send(REGISTER_GPIOB, [this.dirBState]); //Set Direction to Output + this._send(WRITE_GPIOB_ADDR, [0x0]); //clear all output states }; MCP23017.prototype._send = function (cmd, values) { diff --git a/package.json b/package.json index f5df37d..0f453e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-mcp23017", - "version": "0.0.2", + "version": "0.0.3", "description": "Library to use the MCP23017 16bit I/O Expander with the Raspberry Pi", "main": "main.js", "author": "Kai Henzler", @@ -10,6 +10,6 @@ }, "license": "MIT", "dependencies": { - "i2c": "0.1.4" + "i2c": "0.2.3" } }