{"id":21101148,"url":"https://github.com/crycode-de/node-pcf8574","last_synced_at":"2025-05-16T18:34:21.452Z","repository":{"id":47023091,"uuid":"312250332","full_name":"crycode-de/node-pcf8574","owner":"crycode-de","description":"Node.js module for controlling each pin of a PCF8574/PCF8574A I2C port expander IC.","archived":false,"fork":false,"pushed_at":"2024-04-29T12:14:55.000Z","size":380,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-05-02T19:50:39.395Z","etag":null,"topics":["i2c-bus","node-js","pcf8574"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/crycode-de.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["crycode-de"],"custom":["https://www.paypal.me/petercrycode"]}},"created_at":"2020-11-12T11:02:31.000Z","updated_at":"2024-04-29T12:11:02.000Z","dependencies_parsed_at":"2023-12-19T14:22:43.670Z","dependency_job_id":"53840bca-0ff9-4ab5-8977-ba2439e68977","html_url":"https://github.com/crycode-de/node-pcf8574","commit_stats":{"total_commits":72,"total_committers":3,"mean_commits":24.0,"dds":"0.33333333333333337","last_synced_commit":"aa8ae6a68ebe8759156014c7c43560340989f048"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crycode-de%2Fnode-pcf8574","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crycode-de%2Fnode-pcf8574/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crycode-de%2Fnode-pcf8574/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crycode-de%2Fnode-pcf8574/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/crycode-de","download_url":"https://codeload.github.com/crycode-de/node-pcf8574/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225444761,"owners_count":17475353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["i2c-bus","node-js","pcf8574"],"created_at":"2024-11-19T23:40:18.085Z","updated_at":"2024-11-19T23:40:18.769Z","avatar_url":"https://github.com/crycode-de.png","language":"TypeScript","funding_links":["https://github.com/sponsors/crycode-de","https://www.paypal.me/petercrycode"],"categories":[],"sub_categories":[],"readme":"# pcf8574\n\n[![NPM version](https://img.shields.io/npm/v/pcf8574.svg)](https://www.npmjs.com/package/pcf8574)\n[![Downloads](https://img.shields.io/npm/dm/pcf8574.svg)](https://www.npmjs.com/package/pcf8574)\n[![Known Vulnerabilities](https://snyk.io/test/github/crycode-de/node-pcf8574/badge.svg)](https://snyk.io/test/github/crycode-de/node-pcf8574)\n\n[![NPM](https://nodei.co/npm/pcf8574.png?downloads=true)](https://nodei.co/npm/pcf8574/)\n\n\u003e [!WARNING]\n\u003e This package is deprecated and no longer maintained.  \n\u003e Please use the new package [i2c-io-expanders](https://www.npmjs.com/package/i2c-io-expanders) which supports more ICs and can be used as a drop-in replacement.\n\nControl each pin of a PCF8574/PCF8574A/PCF8574P/PCF8575 I2C port expander IC.\n\nThe **PCF8574/PCF8574A** is an 8 bit/pin port expander IC, which can be controlled over the I2C-Bus.\nEach of the 8 pins can be separately used as an input or output.\nIt also offers an interrupt signal, which can be used to detect input changes by the I2C master (e.g. a Raspberry Pi).\nFor more information about the PCF8574/PCF8574A please consult the [datasheet from Texas Instruments](http://www.ti.com/lit/ds/symlink/pcf8574.pdf).\n\nThe **PCF8575** is a 16 bit/pin port expander IC similar to the PCF8574.\nFor more information about the PCF8575 please consult the [datasheet from Texas Instruments](https://www.ti.com/lit/ds/symlink/pcf8575.pdf).\n\n**Supported (tested) Node.js versions:** 10, 12, 14, 16, 18\n\n## Installation\n\n```\nnpm install pcf8574\n```\n\nTypeScript typings are included in this package.\n\nYou should be able to use this module on any Linux based OS.\n\nTo use the interrupt detection you need a Raspberry Pi or a similar board.\n\n## Examples\n\nNote that you need to construct the [i2c-bus](https://npmjs.org/package/i2c-bus) object\nand pass it in to the module along with the I2C address of the PCF8574/PCF8574A/PCF8575.\n\nThe example blow can be found in the [examples directory](https://github.com/crycode-de/node-pcf8574/tree/master/examples) of this package together with a TypeScript example.\n\n```js\n// Require PCF8574 class from the pcf8574 module\nconst PCF8574 = require('pcf8574').PCF8574;\n\n// For PCF8575 use the PCF8575 class\n// const PCF8575 = require('pcf8574').PCF8575;\n\n// Or use ES6 style imports\n// import { PCF8574 } from 'pcf8574';\n// import { PCF8575 } from 'pcf8574';\n\n// Require the i2c-bus module and open the bus\nconst i2cBus = require('i2c-bus').openSync(1);\n\n// Define the address of the PCF8574/PCF8574A/PCF8575\n// Default addresses: PCF8574A - 0x38; PCF8574/PCF8575 - 0x20;\nconst addr = 0x38;\n\n// Init a new PCF8574 with all pins high by default\n// Instead of 'true' you can also use a 8-bit binary notation to define each\n// pin separately, e.g. 0b00101010\nconst pcf = new PCF8574(i2cBus, addr, true);\n\n// Same for PCF8575\n// const pcf = new PCF8575(i2cBus, addr, true);\n\n// Enable interrupt detection on BCM pin 17 (which is GPIO.0)\npcf.enableInterrupt(17);\n\n// Alternatively you can use for example an interval for manually poll every 250ms\n// setInterval(pcf.doPoll.bind(pcf), 250);\n\n// Note the missing ; at the end of the following lines.\n// This is a Promise chain!\n\n// Define pin 0 as inverted output with initally false\npcf.outputPin(0, true, false)\n\n// Then define pin 1 as inverted output with initally true\n.then(() =\u003e {\n  return pcf.outputPin(1, true, true);\n})\n\n// Then define pin 7 as non inverted input\n.then(() =\u003e {\n  return pcf.inputPin(7, false);\n})\n\n// Delay 1 second\n.then(() =\u003e new Promise((resolve) =\u003e {\n  setTimeout(resolve, 1000);\n}))\n\n// Then turn the pin on\n.then(() =\u003e {\n  console.log('turn pin 0 on');\n  return pcf.setPin(0, true);\n})\n\n// Delay 1 second\n.then(() =\u003e new Promise((resolve) =\u003e {\n  setTimeout(resolve, 1000);\n}))\n\n// Then turn the pin off\n.then(() =\u003e {\n  console.log('turn pin 0 off');\n  return pcf.setPin(0, false);\n});\n\n// Add an event listener on the 'input' event\npcf.on('input', (data) =\u003e {\n  console.log('input', data);\n\n  // Check if a button attached to pin 7 is pressed (signal goes low)\n  if(data.pin === 7 \u0026\u0026 data.value === false){\n    // Toggle pin 1\n    pcf.setPin(1);\n  }\n});\n\n// Handler for clean up on SIGINT (ctrl+c)\nprocess.on('SIGINT', () =\u003e {\n  pcf.removeAllListeners();\n  pcf.disableInterrupt();\n});\n```\n\n\n## API\n\nThe API uses __Events__ for detected input changes and __Promises__ for all asyncronous actions.\n\nInput changes can be detected in two ways:\n* Using a GPIO to observe the interrupt signal from the PCF8574/PCF8574A/PCF8575 IC. *Recommended on Raspberry Pi or similar.*\n* Call `doPoll()` manually frequently enough to actively read the current states. This leads to a higher load on the I2C-Bus.\n\nIf a pin is defined as an input and a changed state is detected, an `input` Event will be emitted with an object containing the `pin` number and the new `value` of this pin.\n\nYou can set an inverted flag for each pin separately, which will result in an inverted input or output.\nIf an inverted input has a low level it will be interpreted as true and a high level will be false.\nAn inverted output will write a low level if you set it to true and write a high level if false.\n\n\n### new PCF8574(i2cBus, address, initialState)\n```ts\nconstructor (i2cBus: I2CBus, address: number, initialState: boolean | number);\n```\nConstructor for a new PCF8574/PCF8574A instance.\n\n* `i2cBus` - Instance of an opened i2c-bus.\n* `address` - The address of the PCF8574/PCF8574A IC.\n* `initialState` - The initial state of the pins of this IC. You can set a bitmask (e.g. *0b00101010*) to define each pin seprately, or use true/false for all pins at once.\n\nNote that you need to construct the [i2c-bus](https://npmjs.org/package/i2c-bus) object and pass it in to the module.\n\nIf you use this IC with one or more input pins, you have to call\n* `enableInterrupt(gpioPin)` to detect interrupts from the IC using a GPIO pin, or\n* `doPoll()` frequently enough to detect input changes with manually polling.\n\n### new PCF8575(i2cBus, address, initialState)\n```ts\nconstructor (i2cBus: I2CBus, address: number, initialState: boolean | number);\n```\nConstructor for a new PCF8575 instance.\n\n* `i2cBus` - Instance of an opened i2c-bus.\n* `address` - The address of the PCF8575 IC.\n* `initialState` - The initial state of the pins of this IC. You can set a bitmask (e.g. *0b0000111100101010*) to define each pin seprately, or use true/false for all pins at once.\n\nNote that you need to construct the [i2c-bus](https://npmjs.org/package/i2c-bus) object and pass it in to the module.\n\nIf you use this IC with one or more input pins, you have to call\n* `enableInterrupt(gpioPin)` to detect interrupts from the IC using a GPIO pin, or\n* `doPoll()` frequently enough to detect input changes with manually polling.\n\n### enableInterrupt(gpioPin)\n```ts\nenableInterrupt (gpioPin: number): void;\n```\nEnable the interrupt detection on the specified GPIO pin.\nYou can use one GPIO pin for multiple instances of the PCF8574 class.\n\n* `gpioPin` - BCM number of the pin, which will be used for the interrupts from the PCF8574/8574A/PCF8575 IC.\n\n\n### disableInterrupt()\n```ts\ndisableInterrupt (): void;\n```\nDisable the interrupt detection.\nThis will unexport the interrupt GPIO, if it is not used by an other instance of this class.\n\n\n### doPoll()\n```ts\ndoPoll (): Promise\u003cvoid\u003e;\n```\nManually poll changed inputs from the PCF8574/PCF8574A/PCF8575 IC.\n\nIf a change on an input is detected, an `input` Event will be emitted with a data object containing the `pin` and the new `value`.\nThis have to be called frequently enough if you don't use a GPIO for interrupt detection.\nIf you poll again before the last poll was completed, the promise will be rejected with an error.\n\n\n### outputPin(pin, inverted, initialValue)\n```ts\noutputPin (pin: PCF8574.PinNumber | PCF8575.PinNumber, inverted: boolean, initialValue?: boolean): Promise\u003cvoid\u003e;\n```\nDefine a pin as an output.\nThis marks the pin to be used as an output pin.\nReturns a Promise which will be resolved when the pin is ready.\n\n* `pin` - The pin number. (0 to 7 for PCF8574, 0 to 15 for PCF8575)\n* `inverted` - true if this pin should be handled inverted (true=low, false=high)\n* `initialValue` - (optional) The initial value of this pin, which will be set immediatly.\n\n\n### inputPin(pin, inverted)\n```ts\ninputPin (pin: PCF8574.PinNumber | PCF8575.PinNumber, inverted: boolean): Promise\u003c\u003e;\n```\nDefine a pin as an input.\nThis marks the pin for input processing and activates the high level on this pin.\nReturns a Promise which will be resolved when the pin is ready.\n\n* `pin` - The pin number. (0 to 7 for PCF8574, 0 to 15 for PCF8575)\n* `inverted` - true if this pin should be handled inverted (high=false, low=true)\n\nNote that an input is always set to high (pullup) internally.\n\n\n### setPin(pin, value)\n```ts\nsetPin (pin: PCF8574.PinNumber | PCF8575.PinNumber, value?: boolean): Promise\u003cvoid\u003e;\n```\nSet the value of an output pin.\nIf no value is given, the pin will be toggled.\nReturns a Promise which will be resolved when the new value is written to the IC.\n\n* `pin` - The pin number. (0 to 7 for PCF8574, 0 to 15 for PCF8575)\n* `value` - The new value for this pin.\n\n\n### setAllPins(value)\n```ts\nsetAllPins (value: boolean): Promise\u003cvoid\u003e;\n```\nSet the given value to all output pins.\nReturns a Promise which will be resolved when the new values are written to the IC.\n\n* `value` - The new value for this pin.\n\n\n### getPinValue(pin)\n```ts\ngetPinValue (pin: PCF8574.PinNumber | PCF8575.PinNumber): boolean;\n```\nReturns the current value of a pin.\nThis returns the last saved value, not the value currently returned by the PCF8574/PCF9574A/PCF8575 IC.\nTo get the current value call doPoll() first, if you're not using interrupts.\n\n* `pin` - The pin number. (0 to 7 for PCF8574, 0 to 15 for PCF8575)\n\n\n## License\n\nLicensed under GPL Version 2\n\nCopyright (c) 2017-2023 Peter Müller \u003cpeter@crycode.de\u003e (\u003chttps://crycode.de/\u003e)  \n2022 - PCF8575 support inspired by Lyndel McGee \u003clynniemagoo@yahoo.com\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrycode-de%2Fnode-pcf8574","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrycode-de%2Fnode-pcf8574","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrycode-de%2Fnode-pcf8574/lists"}