{"id":13893973,"url":"https://github.com/RobTillaart/MAX14661","last_synced_at":"2025-07-17T08:31:45.432Z","repository":{"id":45322961,"uuid":"373277929","full_name":"RobTillaart/MAX14661","owner":"RobTillaart","description":"Arduino library for MAX14661 16 channel I2C multiplexer","archived":false,"fork":false,"pushed_at":"2024-04-13T09:06:13.000Z","size":573,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-19T06:33:36.638Z","etag":null,"topics":["arduino","i2c","multiplexer"],"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":"2021-06-02T19:14:45.000Z","updated_at":"2023-10-13T20:18:01.000Z","dependencies_parsed_at":"2024-11-19T06:41:24.808Z","dependency_job_id":null,"html_url":"https://github.com/RobTillaart/MAX14661","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMAX14661","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMAX14661/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMAX14661/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMAX14661/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RobTillaart","download_url":"https://codeload.github.com/RobTillaart/MAX14661/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226243893,"owners_count":17594452,"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","multiplexer"],"created_at":"2024-08-06T18:01:20.989Z","updated_at":"2024-11-24T22:31:02.876Z","avatar_url":"https://github.com/RobTillaart.png","language":"C++","funding_links":["https://github.com/sponsors/RobTillaart","https://www.paypal.me/robtillaart"],"categories":["C++"],"sub_categories":[],"readme":"\n[![Arduino CI](https://github.com/RobTillaart/MAX14661/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)\n[![Arduino-lint](https://github.com/RobTillaart/MAX14661/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/MAX14661/actions/workflows/arduino-lint.yml)\n[![JSON check](https://github.com/RobTillaart/MAX14661/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/MAX14661/actions/workflows/jsoncheck.yml)\n[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/MAX14661.svg)](https://github.com/RobTillaart/MAX14661/issues)\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/MAX14661/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/RobTillaart/MAX14661.svg?maxAge=3600)](https://github.com/RobTillaart/MAX14661/releases)\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/MAX14661.svg)](https://registry.platformio.org/libraries/robtillaart/MAX14661)\n\n\n# MAX14661\n\nArduino library for MAX14661 multiplexer with I2C interface.\n\n\n## Description\n\nThe MAX14661 multiplexer is a 16 x 2 channel multiplexer. \nIt has 2 lines A and B which can be \nconnected up to 16 A lines and 16 B lines.\n\nThe library provides 4 kinds of interfaces (see below)\n- **PAIR** switch A and B in pairs\n- **SHADOW** use a shadow register to set all simultaneously.\n- **MUX** open channels exclusively.\n- **FULL** control all as you like.\n\nMixing these interfaces is allowed but definitely not advised as \nespecially the **PAIR** interface assumes that A and B selections \nare kept in sync.\nSo depending on your application choose the interface you want to use.\n\nThe MAX14661 device can be controlled by SPI or I2C. \nThis library implements the I2C interface.\n\n\n#### I2C address\n\nThe I2C address can be adjusted by 2 address lines A0 and A1.\nAddresses go from 0x4C (76) .. 0x4F (79). See table 3 datasheet.\n\nThis implies you may have up to 4 MAX14661 multiplexers on one I2C bus.\nIf you need more, consider a TCA9548.\n\nAccording to the datasheet the I2C Serial-Clock Frequency is max 400 kHz.\n(SPI can do 10 MHz)\n\n\n#### 0.2.0 Breaking change\n\nVersion 0.2.0 introduced a breaking change.\nYou cannot set the pins in **begin()** any more.\nThis reduces the dependency of processor dependent Wire implementations.\nThe user has to call **Wire.begin()** and can optionally set the Wire pins \nbefore calling **begin()**.\n\n\n#### Related\n\n- https://github.com/RobTillaart/TCA9548 specific I2C multiplexer.\n- https://github.com/RobTillaart/HC4067 1x16 channel multiplexer.\n- https://github.com/RobTillaart/HC4051 1x8 channel multiplexer.\n- https://github.com/RobTillaart/HC4052 2x4 channel multiplexer.\n- https://github.com/RobTillaart/HC4053 2x3 channel multiplexer.\n\n\n## Interface\n\n```cpp\n#include \"MAX14661.h\"\n```\n\n\n#### Constructor\n\n- **MAX14661(uint8_t deviceAddress, TwoWire \\*wire = \u0026Wire)** Constructor with device address, \nand optional the Wire interface as parameter.\n- **bool begin()** initializes the wire interface.\nReturns true if device address is seen on I2C bus.\n- **bool isConnected()** checks if the device address is visible on the I2C bus.\n\n\n#### PAIR interface\n\nThe functions in this interface part all work symmetrical on the A and B line. \nThey are managed as a PAIR. So this is ideal e.g. to multiplex an I2C bus or \na Serial TX/RX pair line.\n\nThe interface allows to have multiple lines A/B open in parallel.\n\n  // open ==\u003e connect\n- **bool openChannel(uint8_t channel)** connects A/B to chosen channel.\n- **bool closeChannel(uint8_t channel)** disconnects channel from A/B.\n- **bool isOpenChannel(uint8_t channel)** returns true if connected to A/B.\n- **void openAllChannels()** connects all channels.\n- **void closeAllChannels()** disconnects all channels.\n- **void setChannels(uint16_t mask)** connect multiple channels with a bit mask.\n- **uint16_t getChannels()** returns a bit mask of the channels connected.\n\nNote: \n**setChannels(mask)** is the only way to set channels at the very same moment\nin the **PAIR** interface.\n\n\n#### SHADOW interface\n\nExperimental - to be tested.\n\nThe SHADOW interface allows one to prepare which channels should be selected, \nand activate them all at once. \n\n- **bool shadowClear()** clears all shadow registers.\n- **void activateShadow()** write all shadow registers to the direction \nregisters of A and B at once. \n\nPrepare multiple channels at once. This is way faster than per channel.\n\n- **bool setShadowChannelMaskA(uint16_t mask)** write all channels at once.\n- **uint16_t getShadowChannelMaskA()** read shadow registers.\n- **bool setShadowChannelMaskB(uint16_t mask)** write all channels at once.\n- **uint16_t getShadowChannelMaskB()** read shadow registers.\n\nPrepare per channel.\n\n- **bool isOpenShadowChannelA(uint8_t channel)** read status of specific channel in shadow registers.\n- **void openShadowChannelA(uint8_t channel)** prepare a specific channel to open.\n- **void closeShadowChannelA(uint8_t channel)** prepare a specific channel to close.\n- **bool isOpenShadowChannelB(uint8_t channel)** read status of specific channel in shadow registers.\n- **void openShadowChannelB(uint8_t channel)** prepare a specific channel to open.\n- **void closeShadowChannelB(uint8_t channel)** prepare a specific channel to close.\n\nNote: there is no command that sets both A and B simultaneously.\n\n#### MUX interface\n\nThe MUX interface allows one channel (0..15) to be open at a time.\n\n- **void MUXA(uint8_t channel)** if channel \u003c 16 only that channel will be selected. \nAll other values will select no channel.\n- **uint8_t getMUXA()** returns the selected channel.\n255 means none selected.\n- **void MUXB(uint8_t channel)** if channel \u003c 16 only that channel will be selected. \nAll other values will select no channel.\n- **uint8_t getMUXB()** returns the selected channel.\n255 means none selected.\n\n\n#### FULL CONTROL interface\n\nFull control per channel, any combination is possible.\nUse with care as these can interfere e.g. with the PAIR interface.\nAll functions return false if channel \u003e 15.\n\n- **bool openA(uint8_t channel)** idem\n- **bool openB(uint8_t channel)** idem\n- **bool closeA(uint8_t channel)** idem\n- **bool closeB(uint8_t channel)** idem\n\n\n#### LOW LEVEL CONTROL interface\n\nCheck datasheet for the meaning of and the values in the registers.\n\n- **uint8_t readRegister(uint8_t reg)** read low level device register.\n- **int writeRegister(uint8_t reg, uint8_t value)** write value to device register.\n\n\n#### Error handling\n\n- **int lastError()** returns the last error, limited to low level I2C for now.\n\nto be elaborated  / implemented(see future)\n\n|  Define                |  value  |  notes  |\n|:-----------------------|:-------:|:-------:|\n|  MAX14661_OK           |  0x00   |\n|  MAX14661_ERR_I2C      |  0x80   |  not implemented yet  |\n|  MAX14661_ERR_CHANNEL  |  0x81   |  not implemented yet  |\n\n\n## Operation\n\nSee examples\n\n\n## Future\n\n#### Must\n\n- improve documentation\n\n#### Should\n\n- test behaviour.\n- write unit tests.\n- implement error handling.\n  - use an internal mode to see which of the three interfaces is used\n    consequently or not?\n  - MAX14661_ERR_ADDRESS ?\n\n\n#### Could\n\n- optimize low level bit set/clr/get read/write 2 bytes at once.\n- test I2C communication speed.\n  - 100- 400 kHz and up.\n- measure performance.\n- cache direct registers. (fast response).\n- **ShutDown()** SD pin. for low power datasheet p.15\n  - document it.\n  - implement.\n\n\n#### Wont\n\n- SPI interface.\n  - separate (derived ?) class\n- initial values parameter for begin()?\n  - depends on interface (PAIR MUX SHADOW) used, ambiguous. \n  - ==\u003e user task.\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%2FMAX14661","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FRobTillaart%2FMAX14661","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRobTillaart%2FMAX14661/lists"}