.. | ||
.github | ||
examples | ||
test | ||
.arduino-ci.yml | ||
CHANGELOG.md | ||
DAC8571.cpp | ||
DAC8571.h | ||
keywords.txt | ||
library.json | ||
library.properties | ||
LICENSE | ||
README.md |
DAC8571
Arduino library for DAC8571 I2C 16 bit DAC.
Description
Experimental
The DAC8571 is a small low-power, 16-bit voltage Power-On Reset to Zero output DAC.
The DAC8571 has one 16 bit DAC. The output value can be set from 0..65535. This results in a voltage which depends on a reference voltage Vref (datasheet). At power up it always will start with a value of zero.
The DAC8571 has a temporary register in which a value can be preloaded. This can be used to change the DAC at a later moment.
Not supported is the broadcast function to change multiple DAC8571 (and compatibles) at the same moment by using this temporary register.
As said the library is experimental need to be tested with hardware. Feedback is always welcome, please open an issue.
Settling time
From datasheet page 24.
Settling time to within the 16-bit accurate range of the DAC8571 is achievable within 10 μs for a full-scale code change at the input. Worst case settling times between consecutive code changes is typically less than 2 μs, therefore, the update rate is limited by the I2C interface.
I2C
Address
The DAC8571 support 2 addresses by means of an A0 address pin.
Address | A0 |
---|---|
0x4C | LOW |
0x4E | HIGH |
It might be possible to connect this address pin to an IO pin and keep only one HIGH and remaining LOW to support many devices. This is not tested, feedback welcome.
I2C performance
Extend table, use output of DAC8571_performance.ino
Time in microseconds.
array == write(array, length)
Assumption all write modi have similar performance.
Tested on Arduino UNO.
Speed | function | time | notes |
---|---|---|---|
100000 | write() | ||
100000 | read() | ||
200000 | write() | ||
200000 | read() | ||
400000 | write() | ||
400000 | read() |
Test ESP32 (Kudos to Paul)
Speed | write() | read() | write(array) | Notes |
---|---|---|---|---|
50000 | 800.01 | 800.04 | ||
100000 | 439.02 | 441.18 | 2100.01 | array == 10 elements! |
200000 | 239.12 | 242.41 | 1090.82 | |
300000 | 178.05 | 181.81 | 757.57 | |
400000 | 148.94 | 156.83 | 595.24 | |
500000 | 131.57 | 142.93 | 497.99 | |
600000 | 120.68 | 136.35 | 428.59 | |
700000 | 113.19 | 130.40 | 384.64 | |
800000 | 108.12 | 128.18 | 351.85 | |
900000 | 98.21 | 106.67 | 317.45 | |
1000000 | 94.11 | 94.58 | 296.88 |
I2C multiplexing
Sometimes you need to control more devices than possible with the default address range the device provides. This is possible with an I2C multiplexer e.g. TCA9548 which creates up to eight channels (think of it as I2C subnets) which can use the complete address range of the device.
Drawback of using a multiplexer is that it takes more administration in your code e.g. which device is on which channel. This will slow down the access, which must be taken into account when deciding which devices are on which channel. Also note that switching between channels will slow down other devices too if they are behind the multiplexer.
Related
- https://github.com/RobTillaart/AD5680 (18 bit DAC)
- https://github.com/RobTillaart/DAC8550
- https://github.com/RobTillaart/DAC8551
- https://github.com/RobTillaart/DAC8552
- https://github.com/RobTillaart/DAC8554
- https://github.com/RobTillaart/DAC8571
- https://github.com/RobTillaart/MCP_DAC
- https://github.com/RobTillaart/MCP_ADC
Interface
#include "DAC8571.h"
Constructor
- DAC8571(uint8_t address = 0x4C, TwoWire *wire = &Wire) constructor with I2C address. Default is 0x4C, optional set the WireN I2C bus.
- bool begin(uint16_t value = 0) Set initial value for the DAC, typical zero (power on default). Returns false if address out of range, or if device cannot be seen on the I2C bus. Returns true if successful.
- bool isConnected() test to see if address can be reached on the I2C bus.
- uint8_t getAddress() returns address set in constructor.
Core
The DAC8571 has one 16 bit DAC. The output value can be set from 0..65535.
- bool write(uint16_t value) writes a value 0..65535 to the DAC. NO default, user must explicit set value.
- uint16_t lastWrite() get last value written from cache (fast).
- uint16_t read() get last written value from device.
Percentage wrappers
- void setPercentage(float perc) set 0.00 .. 100.00
- float getPercentage() returns 0.0 .. 100.0
Write modi
The DAC8571 can be written in different modi (datasheet page 19). Not all modi are supported yet, these need testing.
- void setWriteMode(uint8_t mode = DAC8571_MODE_NORMAL)
- uint8_t getWriteMode()
Setting the mode will be applied for all writes until mode is changed.
Mode | Meaning |
---|---|
DAC8571_MODE_STORE_CACHE | store value in temporary register. Preparation for (2, 3 and 4) |
DAC8571_MODE_NORMAL | update DAC with value written. DEFAULT. |
DAC8571_MODE_WRITE_CACHE | writes the temporary register to DAC, ignores new value. |
DAC8571_MODE_BRCAST_0 | broadcast update. Not supported yet. See below. |
DAC8571_MODE_BRCAST_1 | broadcast update. Not supported yet. See below. |
DAC8571_MODE_BRCAST_2 | broadcast update. Not supported yet. See below. |
other | maps onto default DAC8571_MODE_NORMAL. |
Write multiple values - High speed mode.
The maximum length depends on the internal I2C BUFFER of the board. For Arduino this is typical 32 bytes so it allows 14 values.
- void write(uint16_t arr[n], uint8_t length) Writes a buffer with max 14 values in one I2C call. The last value written will be remembered in lastWrite().
Power Down mode
To investigate: Mixes also with broadcast ==> complex API.
- void powerDown(uint8_t pdMode = 0) default low power.
- void wakeUp(uint16_t value = 0) wake up, DAC value set to zero by default.
See table 6, page 22 datasheet for details.
Power Down Mode | Meaning |
---|---|
DAC8571_PD_LOW_POWER | 170 uA |
DAC8571_PD_FAST | 250 uA |
DAC8571_PD_1_KOHM | 200 nA, GND 1 KOhm |
DAC8571_PD_100_KOHM | 200 nA, GND 100 KOhm |
DAC8571_PD_HI_Z | 200 nA, open circuit, high impedance |
Broadcast mode
Not supported
Different ways possible, need to investigate API. (page 19)
Three broadcast commands exists:
Mode | Meaning |
---|---|
DAC8571_MODE_BRCAST_0 | Load all devices from temporary register |
DAC8571_MODE_BRCAST_1 | Load all devices with data. |
DAC8571_MODE_BRCAST_2 | Power down all devices |
Error codes
- int lastError() always check this value after a read() / write() to see if it was DAC8571_OK. After the call to lastError() the error value is reset to DAC8571_OK.
Error code | Value | Notes |
---|---|---|
DAC8571_OK | 0x00 | |
DAC8571_I2C_ERROR | 0x81 | |
DAC8571_ADDRESS_ERROR | 0x82 | |
DAC8571_BUFFER_ERROR | 0x83 | write(arr, length) length error |
Future
Must
- get hardware to test
- improve documentation
- test different write modi
Should
- extend performance table
- replace magic numbers
Could
- add examples
- investigate broadcast support
- investigate known compatibles
- including SPI versions?
Wont
Support
If you appreciate my libraries, you can support the development and maintenance. Improve the quality of the libraries by providing issues and Pull Requests, or donate through PayPal or GitHub sponsors.
Thank you,