{"id":20989936,"url":"https://github.com/robtillaart/i2ckeypad8x8","last_synced_at":"2025-05-14T18:32:23.062Z","repository":{"id":82983903,"uuid":"542717480","full_name":"RobTillaart/I2CKeyPad8x8","owner":"RobTillaart","description":"Arduino library for 8x8 or smaller KeyPad connected to an I2C PCF8575.","archived":false,"fork":false,"pushed_at":"2024-07-18T17:53:26.000Z","size":3952,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-08-07T18:26:53.317Z","etag":null,"topics":["arduino","i2c","keypad","pcf8575"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RobTillaart.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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":"RobTillaart","custom":"https://www.paypal.me/robtillaart"}},"created_at":"2022-09-28T17:42:27.000Z","updated_at":"2024-07-31T20:28:25.000Z","dependencies_parsed_at":"2024-07-18T20:32:54.285Z","dependency_job_id":null,"html_url":"https://github.com/RobTillaart/I2CKeyPad8x8","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FI2CKeyPad8x8","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FI2CKeyPad8x8/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FI2CKeyPad8x8/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FI2CKeyPad8x8/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RobTillaart","download_url":"https://codeload.github.com/RobTillaart/I2CKeyPad8x8/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225305812,"owners_count":17453458,"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":["arduino","i2c","keypad","pcf8575"],"created_at":"2024-11-19T06:26:46.012Z","updated_at":"2024-11-19T06:26:46.447Z","avatar_url":"https://github.com/RobTillaart.png","language":"C++","funding_links":["https://github.com/sponsors/RobTillaart","https://www.paypal.me/robtillaart"],"categories":[],"sub_categories":[],"readme":"\n[![Arduino CI](https://github.com/RobTillaart/I2CKeyPad8x8/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)\n[![Arduino-lint](https://github.com/RobTillaart/I2CKeyPad8x8/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/I2CKeyPad8x8/actions/workflows/arduino-lint.yml)\n[![JSON check](https://github.com/RobTillaart/I2CKeyPad8x8/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/I2CKeyPad8x8/actions/workflows/jsoncheck.yml)\n[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/I2CKeyPad8x8.svg)](https://github.com/RobTillaart/I2CKeyPad8x8/issues)\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/I2CKeyPad8x8/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/RobTillaart/I2CKeyPad8x8.svg?maxAge=3600)](https://github.com/RobTillaart/I2CKeyPad8x8/releases)\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/I2CKeyPad8x8.svg)](https://registry.platformio.org/libraries/robtillaart/I2CKeyPad8x8)\n\n\n# I2CKeyPad8x8\n\nArduino library for 8x8 or smaller KeyPad connected to an I2C PCF8575.\n\n\n## Description\n\n**Experimental** (first tests ==\u003e OK)\n\nThe I2CKeyPad8x8 library implements the reading of a 8x8 keypad by means \nof a PCF8575. Smaller keypads, meaning less columns or rows (e.g. 5x4) \ncan be read with it too.\n\n### Breaking change\n\nSince 0.3.0 the library can set a debounce threshold. \nIf this is set (\u003e 0) the **getKey()** and **getChar()** functions \ncan return **I2C_KEYPAD_THRESHOLD** (255).\n\n\n### Related\n\nRelates strongly to https://github.com/RobTillaart/I2CKeyPad. which is \nan 4x4 version using **PCF8574**.\n\n- https://github.com/RobTillaart/PCF8575\n- https://github.com/RobTillaart/AnalogKeypad\n- https://github.com/RobTillaart/I2CKeyPad\n- https://github.com/RobTillaart/I2CKeyPad8x8\n\n\n## Connection\n\nThe PCF8575 is connected between the processor and the (default) 8x8 keypad.\nSee the conceptual schema below. \nIt might take some trying to get the correct pins connected.\n\n```\n          PROC              PCF8575              KEYPAD\n        +--------+        +---------+          +---------+\n        |        |        |       0 |\u003c--------\u003e| R       |\n        |    SDA |\u003c------\u003e|       . |\u003c--------\u003e| O       |\n        |    SCL |\u003c------\u003e|       . |\u003c--------\u003e| W       |\n        |        |        |       7 |\u003c--------\u003e| S       |\n        |        |        |         |          |         |\n        |        |        |       8 |\u003c--------\u003e| C       |\n        |        |        |       . |\u003c--------\u003e| O       |\n        |        |        |       . |\u003c--------\u003e| L       |\n        |        |        |      15 |\u003c--------\u003e| S       |\n        +--------+        +---------+          +---------+ \n```\n\n\n## I2C\n\n### I2C addresses\n\nThis library uses a PCF8575 chip.\n\n|  Type      |  Address-range  |  Notes                    |\n|:-----------|:---------------:|:-------------------------:|\n|  PCF8575   |  0x20 to 0x27   |  same range as PCF8574 !  |\n\nBe careful to select an unique I2C address for every device on the bus.\n\n\n### I2C multiplexing\n\nSometimes you need to control more devices than possible with the default\naddress range the device provides.\nThis is possible with an I2C multiplexer e.g. TCA9548 which creates up\nto eight channels (think of it as I2C subnets) which can use the complete\naddress range of the device.\n\nDrawback of using a multiplexer is that it takes more administration in\nyour code e.g. which device is on which channel.\nThis will slow down the access, which must be taken into account when\ndeciding which devices are on which channel.\nAlso note that switching between channels will slow down other devices\ntoo if they are behind the multiplexer.\n\n- https://github.com/RobTillaart/TCA9548\n\n\n## Interface\n\n```cpp\n#include \"I2CKeyPad8x8.h\"\n```\n\n### Base\n\n- **I2CKeyPad8x8(const uint8_t deviceAddress, TwoWire \\*wire = \u0026Wire)** \nThe constructor sets the device address and optionally \nallows to selects the I2C bus to use.\n- **bool begin()** The return value shows if the PCF8575 with the given \naddress is connected properly. \nCall wire.begin() first!\n- **bool isConnected()** returns false if the PCF8575 cannot be connected to.\n\n\n### getKey\n\n- **uint8_t getKey()** Returns default 0..63 for regular keys, \nReturns **I2C_KEYPAD8X8_NOKEY** (64) if no key is pressed and and **I2C_KEYPAD8X8_FAIL**\n(65) in case of an error, e.g. multiple keys pressed.\nIf a debounce delay is set (see below), it will return **I2C_KEYPAD8X8_THRESHOLD** (255) \nif the function is called too fast.\n- **uint8_t getLastKey()** Returns the last **valid** key pressed 0..63, or **I2C_KEYPAD8X8_NOKEY** \n(64) which is also the initial value.\nThis function does not \"cache\" failed keys.\n- **bool isPressed()** Returns true if one or more keys of the keyPad are pressed.\nNote there is no check if multiple keys are pressed or just one.\nReturns false if no key is pressed or when there is a communication error.\nSo checking **getKey()** yourself will give more information, but is slightly slower.\n\n\n|  getKey()  |  HEX code    |  Meaning                  |  Notes  |\n|:----------:|:------------:|:--------------------------|:--------|\n|  0..63     |  0x00..0x3F  |  valid key pressed        |\n|  64        |  0x40        |  I2C_KEYPAD8X8_NOKEY      |\n|  65        |  0x41        |  I2C_KEYPAD8X8_FAIL       |  multi key or I2C communication error.\n|  255       |  0xFF        |  I2C_KEYPAD8X8_THRESHOLD  |\n\n\n### KeyMap functions\n\nNote: **loadKeyMap()** must be called before **getChar()** and **getLastChar()**\ncan be used!\n\n- **char getChar()** returns the char corresponding to mapped key pressed.\nThe function returns **I2C_KEYPAD_THRESHOLD** (255) if called too fast and a debounce threshold is set.\n- **char getLastChar()** returns the last char pressed.\nThis function is not affected by the debounce threshold.\n- **bool loadKeyMap(char \\* keyMap)** keyMap should point to a (global) char array of length 67.\nThis array maps index 0..63 on a character and index \\[64\\] maps to **I2CKeyPad8x8_NOKEY** (typical 'N') \nand index \\[65\\] maps **I2CKeyPad8x8_FAIL** (typical 'F'). Index 66 is the null char.\nThis allows to define a keymap as a null terminated char array, e.g. \n\n```cpp\nchar keymap = \"1234567890...NF\";  //  ... stands for 50+ more chars.\n\nkp8.loadKeyMap(keymap);\n```\n\n**WARNING**\n\nIf there is no key map loaded the user should **NOT** call **getChar()** or \n**getLastChar()** as these would return meaningless bytes.\n\n\nNote: a keyMap char array may be longer than 66 characters, but only the first 66 are used.\nThe length is **NOT** checked upon loading (as it may contain a NULL char).\n\nSee also future section below.\n\n\n### Debouncing threshold\n\n**Experimental**\n\nSince version 0.3.0, the library implements an experimental debounce threshold\nwhich is non-blocking.\n\nIf a key bounces, it can trigger multiple interrupts, while the purpose is to\nact like only one keypress. The debounce threshold results in a fast return \nof **getKey()** (with **I2C_KEYPAD8x8_THRESHOLD**) if called too fast.\n\nThe default value of the debounce threshold is zero to be backwards compatible.\nThe value is set in milliseconds, with a maximum of 65535 ==\u003e about 65 seconds or 1 minute.\nA value of 1 still allows ~1000 **getKey()** calls per second (in theory).\nA value of 65535 can be used e.g. for a delay after entering a wrong key code / password.\nSetting a high value might result in missed keypresses so use with care.\n\nThe default value of the debounce threshold is zero to be backwards compatible.\n\n- **void setDebounceThreshold(uint16_t value = 0)** set the debounce threshold,\nvalue in milliseconds, max 65535.\nThe default value is zero, to reset its value.\n- **uint16_t getDebounceThreshold()** returns the set debounce threshold.\n- **uint32_t getLastTimeRead()** returns the time stamp of the last valid read key\n(or NOKEY). This variable is used for the debounce, and may be used for other\npurposes too. E.g. track time between keypresses.\n\nIf a debounce threshold is set, and **getKey()** or **getChar()** is called too fast,\nthese functions will return **I2C_KEYPAD8x8_THRESHOLD** (255).\n\nFeedback welcome!\n\n\n### Basic working\n\nAfter the **keypad.begin()** the sketch calls the **keyPad.getKey()** to read values from the keypad. \n- If no key is pressed **I2C_KEYPAD8x8_NOKEY** code (64) is returned.\n- If the read value is not valid, e.g. two keys pressed, **I2C_KEYPAD8x8_FAIL** code (65) is returned.\n- If a debounce threshold is set, **I2C_KEYPAD8x8_THRESHOLD** (255) might be returned.\nSee section above.\n- Otherwise a number 0..63 is returned.\n\nNote **I2C_KEYPAD8x8_NOKEY**, **I2C_KEYPAD8x8_FAIL** and **I2C_KEYPAD8x8_THRESHOLD**, all are 64 or\nbeyond, all valid keys are below 64.\nThis allows easy and fast checking for validity of keys.\n\nOnly if a key map is loaded, the user can call **getChar()** and **getLastChar()** to get mapped keys.\n\n\n## Interrupts\n\nThe library enables the PCF8575 to generate interrupts on the PCF8575 when a key is pressed. \nThis makes checking the keypad far more efficient as one does not need to poll the device over I2C.\nSee examples (TODO).\n\n\n## Smaller keypads\n\nIf one wants to connect a smaller keyPad e.g. a 4x4 to the PCF8575, one need to be\nsure to have the rows on P00..P07 and the columns on P10..P17 (or P08..P15).\n\nThis library does not support the usage of the \"not used\" pins, when connecting a\nsmaller keypad than 8x8. \n\nIn issue #7 an idea is proposed to use the https://github.com/RobTillaart/I2CKeyPad\nwith a PCF8575. It proposes to connect a 4x4 keypad to the P00..P07 pins.\nWarning: this idea is not confirmed to work yet, feedback is welcome.\n\n\n## Future\n\n#### Must\n\n- update documentation\n- keep in sync with **I2CKeyPad** as much as possible.\n\n#### Should\n\n- test extensively\n  - interrupts\n  - keymapping\n  - performance\n- improve error handling\n  - **I2C_KEYPAD_ERR_MODE**\n  - **I2C_KEYPAD_ERR_COMM** (66?) or map to **I2C_KEYPAD_FAIL**?\n\n#### Could\n\n- add examples\n  - from https://github.com/RobTillaart/I2CKeyPad?\n- KeyMap\n  - checking if NULL?  ==\u003e  FAIL, how?\n  - checking length of keymap during load.\n  - default ASCII map (32..96?)\n  - in PROGMEM?\n- add **uint8_t getAddress()**\n\n#### Wont\n\n\n## Support\n\nIf you appreciate my libraries, you can support the development and maintenance.\nImprove the quality of the libraries by providing issues and Pull Requests, or\ndonate through PayPal or GitHub sponsors.\n\nThank you,\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtillaart%2Fi2ckeypad8x8","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobtillaart%2Fi2ckeypad8x8","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtillaart%2Fi2ckeypad8x8/lists"}