{"id":20989805,"url":"https://github.com/robtillaart/mcp4725","last_synced_at":"2025-05-14T18:32:11.291Z","repository":{"id":45321017,"uuid":"273758380","full_name":"RobTillaart/MCP4725","owner":"RobTillaart","description":"Arduino library for 12 bit I2C DAC - MCP4725 ","archived":false,"fork":false,"pushed_at":"2024-04-13T09:07:09.000Z","size":85,"stargazers_count":22,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-07T18:27:21.469Z","etag":null,"topics":["arduino","dac","i2c"],"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},"funding":{"github":"RobTillaart","custom":"https://www.paypal.me/robtillaart"}},"created_at":"2020-06-20T17:55:41.000Z","updated_at":"2024-08-06T05:53:31.000Z","dependencies_parsed_at":"2023-02-10T04:46:04.747Z","dependency_job_id":"d27d36e6-a517-4544-8841-b8befd24d5e0","html_url":"https://github.com/RobTillaart/MCP4725","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMCP4725","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMCP4725/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMCP4725/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FMCP4725/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RobTillaart","download_url":"https://codeload.github.com/RobTillaart/MCP4725/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225305671,"owners_count":17453424,"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","dac","i2c"],"created_at":"2024-11-19T06:26:12.811Z","updated_at":"2025-05-14T18:32:11.275Z","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/MCP4725/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)\n[![Arduino-lint](https://github.com/RobTillaart/MCP4725/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/MCP4725/actions/workflows/arduino-lint.yml)\n[![JSON check](https://github.com/RobTillaart/MCP4725/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/MCP4725/actions/workflows/jsoncheck.yml)\n[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/MCP4725.svg)](https://github.com/RobTillaart/MCP4725/issues)\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/MCP4725/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/RobTillaart/MCP4725.svg?maxAge=3600)](https://github.com/RobTillaart/MCP4725/releases)\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/MCP4725.svg)](https://registry.platformio.org/libraries/robtillaart/MCP4725)\n\n\n# MCP4725\n\nArduino library for 12 bit I2C DAC - MCP4725.\n\n\n## Description\n\nThe MCP4725 is an I2C single channel 12 bit Digital to Analog Converter (DAC).\nIt is possible to have up to 8 MCP4725 on one I2C bus.\nThe MCP4725 supports 100 KHz 400 KHz and 3.4 MHz bus speeds.\n\nThe output of the MCP4725 depends on the voltage supplied, which is in the range\nof 2.7V .. 5.5V. Check datasheet for the details.\n\n\n### 0.4.0 Breaking change\n\nVersion 0.4.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/AD56x8 (multi channel)\n- https://github.com/RobTillaart/AD568X (single channel lower resolution)\n- https://github.com/RobTillaart/MCP_DAC (SPI interface)\n- https://www.amazon.com/dp/B07CZQHF7N  XTR116U based 4-20mA device, controlled by MCP4725\n\n\n## Interface\n\n```cpp\n#include \"MCP4725.h\"\n```\n\n### Constructor\n\n- **MCP4725(uint8_t deviceAddress, TwoWire \\*wire = \u0026Wire)** Constructor, needs I2C address, optional set Wire bus\n- **bool begin()** initializes internals.\nReturns false if address out of range.\nReturns true if deviceAddress can be found on the I2C bus.\n- **bool isConnected()** returns true if device (address) can be seen on the I2C bus.\n- **uint8_t getAddress())** returns address set in constructor.\n\n### Base\n\n- **int setValue(uint16_t value = 0)** value = 0 .. 4095.  \nUses writeFastMode and does not write to EEPROM.\nTherefore it does not update the lastWriteEEPROM timestamp.\nThe default value is 0.  \nReturns 0 on success\n- **uint16_t getValue()** returns last value set from cache, this is much faster than readDAC().  \nThis latter gives the real value from the MCP4725. \nNote: a difference can be caused by power outage a reset etc.\n- **int setPercentage(float percentage)** percentage = 0..100.0%.\nConvenience wrapper around setValue().\n- **float getPercentage()** returns percentage. Wrapper around getValue().\n- **int writeDAC(value, bool EEPROM = false)** Writes to DAC and conditionally to EEPROM.  \nThis latter is for startup / reset behaviour. Check datasheet for the detail behaviour.\n- **bool ready()** returns true if a new value can be written to the MCP4725.  \nReturn false if recently was written to EEPROM.\n- **uint16_t readDAC()** reads the current value set in the MCP4725.\n- **uint16_t readEEPROM()** reads the current value in the EEPROM of the MCP4725.\n- **uint32_t getLastWriteEEPROM()** returns time in millis() when last value was written to EEPROM.\n\nPage 3 of datasheet states it takes **25 - 50 ms** before values are written to EEPROM.\nSo the exact timing of a sensor can differ quite a lot.\nWhen writing to EEPROM with **writeDAC()** one should check it is at least 50 ms ago.\nIf one know the specific timing of a sensor one can tune this or even make it adaptive.\n\n\n### Voltage interface\n\n(Since 0.3.8)\nAssumes linear behaviour over 12 bit from 0..4095 == 0 .. maxVoltage.\nThe default value is 5.0 volt.\nAllows sort of calibration e.g. setting maxVoltage to 4.952 Volt.\nFurthermore it can be a preferred interface over percentage and raw values.\n\n- **void setMaxVoltage(float v = 5.0)** configures maximum voltage of Vout.\n- **float getMaxVoltage()** return set maximum.\n- **void setVoltage(float v)** set the DAC to voltage v.\nThis maps the voltage to 0..4095 and calls **setValue()**\n- **float getVoltage()** get the current setting as a voltage\n\nIf this behaviour is not precise enough or should be more \"complex\" the user can\nalways define its own set of wrapper functions around **getValue()** and **setValue()**.\n\n\n## Experimental\n\nCheck datasheet for these functions, (not tested enough yet).\n\n- **int writePowerDownMode(uint8_t PDM, bool EEPROM = false)**\n- **uint8_t readPowerDownModeEEPROM()**\n- **uint8_t readPowerDownModeDAC()**\n- **int powerOnReset()**\n- **int powerOnWakeUp()**\n\nMore investigations needed for:\n- Writing to EEPROM, **ready()** and **getLastWriteEEPROM()**  \nchecking when and how long the sensor blocks needs to be verified in detail in practice. \n\n\n## Address Notes\n\nThe address of the MCP4725 in the demo sketches is set to 0x62 as that\nwas the address of the sensor I had during writing.\nAccording to the datasheet the address has the following bit pattern:\n\naddress  011000FFU   (so 0x6?)\n\n         F = Factory set bit\n         U = User configurable bit\n\nThis means you can have at most 8 MCP4725 in one I2C bus (without multiplexing).\nYou have to specify the factory bits in your order, but not all shops might\nprovide all versions of the MCP4725.\n\n```\nMCP4725A0T-E/CH:  0110 000U   0x60 - 0x61\nMCP4725A1T-E/CH:  0110 001U   0x62 - 0x63\nMCP4725A2T-E/CH:  0110 010U   0x64 - 0x65\nMCP4725A3T-E/CH:  0110 011U   0x66 - 0x67\n```\n\nIf one need more DAC's one might have a look at the MCP4728\nIt has 4 channels per chip (no experience / library yet)\n\n\n### RP2040 specific\n\nThere are different RP2040 board files.\nThis library works with RP2040 pico - https://github.com/earlephilhower/arduino-pico\nWill give an error on setSDA() and setSCL() with the \"Arduino MBED OS\" version.\n\nSee remark PR #21.\n\n- **bool begin(int sda, int scl)** begin communication with the DAC.\nIt has the parameter for selecting on which pins the communication should happen.\nCheck RP2040 Pinout for compatible pins.\nWhen Wire1 is used, it needs to be specified in the constructor with \"\u0026Wire1\"\n\n\n## Multi devices on one I2C bus\n\nNormal one can have 1 to 8 MCP4725 on a I2C bus. This depends on the right\nchoice of devices as 2 address bits are hard coded in the device.\nSee paragraph 7.2 datasheet + address notes section above.\n\nBut one cannot always order the right devices.\nEspecially breakout boards often have the same address-range.\n\n\n### TCA9548 I2C multiplexer\n\nUse an I2C multiplexer to create multiple \"I2C channels\" which allows then\nup to 8 devices per channel. Selecting the right devices includes setting\nthe I2C multiplexer to the right channel to address the right device.\nThis implies access is a bit slower and uses more code.\n\nOne (TCA9548) multiplexer allows one to control up to 64 MCP4725's.\n\n- https://github.com/RobTillaart/TCA9548\n\nNote that other multiplexers do exist.\n\n\n### Use A0 address pin as a SELECT pin\n\n(Experimental)\n\nNeed to do more tests to see how this solution behaves in practice.\n\nVerified to work - see https://forum.arduino.cc/t/using-digital-pins-to-control-two-mcp4725-modules/1161482/7.\n\nThe assumption here is that the devices are all from the same address range (factory bits).\n\nYou can control multiple MCP4725 over the hardware I2C bus with an extra IO pin per device.\n- Connect the address pin of every MCP4725 to an IO pin which will work as a **SELECT** pin.\n- Keep all IO pins **LOW** so the all have effectively the same address == 0x60.\n- To select a specific MCP4725 you set the related IO pin to **HIGH** and that one will have address == 0x61.\n- Now you can access and control the associated MCP4725 with address 0x61.\n- See **mcp4725_multiple.ino** and **mcp4725_multiple_minimal.ino**\n\n\n## MCP4725 in products\n\n### XTR116U\n\nDaryl M. reported me of a **XTR116U** based board to communicate a signal over a 4-20mA line.\nThis is also known as **Current Loop**. The board is controlled by an MCP4725.\nAn interesting application for the MCP4725 library.\n\n- https://www.amazon.com/dp/B07CZQHF7N\n- https://github.com/researchdesignlab/4-20mA_Loop_Current_Transmitter_XTR116U\n\nThe advantages of an 4-20mA communication are simplicity and insensitive for noise.\nCurrent won't drop even when long wires are used.\nIt is even possible to power devices (not all) with the current loop.\n\n- https://en.wikipedia.org/wiki/Current_loop\n\n\n## Future\n\n#### Must\n\n- update documentation\n\n#### Should\n\n- test the powerDown modes / functions.\n- test A0 (address bit) as SELECT pin.\n- optimize\n  - voltage interface uses float divisions =\u003e store reciprocate?\n  - takes 2 extra floats.\n\n#### Could\n\n- add mavVoltage parameter in begin?\n  - **bool begin(float maxVoltage = 5.0);**\n- extend unit tests\n\n#### Wont\n\n- MCP4725_VERSION ==\u003e MCP4725_LIB_VERSION\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%2Fmcp4725","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobtillaart%2Fmcp4725","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtillaart%2Fmcp4725/lists"}