2024-04-16 15:07:07 -04:00
|
|
|
|
|
|
|
[![Arduino CI](https://github.com/RobTillaart/DAC8571/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
|
|
|
|
[![Arduino-lint](https://github.com/RobTillaart/DAC8571/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/DAC8571/actions/workflows/arduino-lint.yml)
|
|
|
|
[![JSON check](https://github.com/RobTillaart/DAC8571/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/DAC8571/actions/workflows/jsoncheck.yml)
|
|
|
|
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/DAC8571.svg)](https://github.com/RobTillaart/DAC8571/issues)
|
|
|
|
|
|
|
|
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/DAC8571/blob/master/LICENSE)
|
|
|
|
[![GitHub release](https://img.shields.io/github/release/RobTillaart/DAC8571.svg?maxAge=3600)](https://github.com/RobTillaart/DAC8571/releases)
|
|
|
|
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/DAC8571.svg)](https://registry.platformio.org/libraries/robtillaart/DAC8571)
|
|
|
|
|
|
|
|
|
|
|
|
# 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() | |
|
|
|
|
|
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-04-16 15:07:07 -04:00
|
|
|
#### 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.
|
|
|
|
|
|
|
|
- https://github.com/RobTillaart/TCA9548
|
|
|
|
|
|
|
|
|
|
|
|
#### 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
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
#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.
|
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
- **bool write(uint16_t value)** writes a value 0..65535 to the DAC.
|
|
|
|
NO default, user must explicit set value.
|
2024-04-16 15:07:07 -04:00
|
|
|
- **uint16_t lastWrite()** get last value written from cache (fast).
|
|
|
|
- **uint16_t read()** get last written value from device.
|
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
Percentage wrappers
|
|
|
|
- **void setPercentage(float perc)** set 0.00 .. 100.00
|
|
|
|
- **float getPercentage()** returns 0.0 .. 100.0
|
|
|
|
|
2024-04-16 15:07:07 -04:00
|
|
|
|
|
|
|
#### 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**.
|
|
|
|
|
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
#### Write multiple values - High speed mode.
|
2024-04-16 15:07:07 -04:00
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
The maximum length depends on the internal I2C BUFFER of the board.
|
|
|
|
For Arduino this is typical 32 bytes so it allows 14 values.
|
2024-04-16 15:07:07 -04:00
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
- **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()**.
|
2024-04-16 15:07:07 -04:00
|
|
|
|
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
#### Power Down mode
|
2024-04-16 15:07:07 -04:00
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
To investigate: Mixes also with broadcast ==> complex API.
|
2024-04-16 15:07:07 -04:00
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
- **void powerDown(uint8_t pdMode = 0)** default low power.
|
|
|
|
- **void wakeUp(uint16_t value = 0)** wake up, DAC value set to zero by default.
|
2024-04-16 15:07:07 -04:00
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
See table 6, page 22 datasheet for details.
|
2024-04-16 15:07:07 -04:00
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
| 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
|
2024-04-16 15:07:07 -04:00
|
|
|
|
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
#### Broadcast mode
|
2024-04-16 15:07:07 -04:00
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
**Not supported**
|
2024-04-16 15:07:07 -04:00
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
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
|
2024-04-16 15:07:07 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### Error codes
|
|
|
|
|
2024-04-19 13:12:08 -04:00
|
|
|
- **int lastError()** always check this value after a read() / write()
|
2024-04-16 15:07:07 -04:00
|
|
|
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,
|
|
|
|
|
|
|
|
|